'use client';

import { useMemo, useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import {
  Search,
  X,
  Plus,
  Users as UsersIcon,
  UserCheck,
  UserX,
  BadgeCheck,
  ArrowUpDown,
  ArrowUp,
  ArrowDown,
  MoreHorizontal,
  RefreshCw,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Card, CardContent } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import { Spinner } from '@/components/ui/spinners';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import PaginationComponent from '../paginationComponent/paginationComponent';
import axios from '@/network/axios';
import { apis } from '@/utils/apis/apis';
import { SuccessResponse } from '@/utils/types/Responses';
import type { UserModel } from '@/utils/types/User';
import {
  fetchUsers,
  archiveUsers,
} from '@/network/apis/dashboard/userManagment/users/users.apis';
import {
  accountTypeMeta,
  avatarTint,
  formatDateTime,
  fullName,
  getInitials,
  statusMeta,
} from './userListUtils';
import { UserDetailSheet } from './UserDetailSheet';

const TYPE_CHIPS = [
  { label: 'All types', value: '' },
  { label: 'Admins', value: '1' },
  { label: 'Brands', value: '2' },
  { label: 'Influencers', value: '3' },
];

const STATUS_CHIPS = [
  { label: 'All', value: '' },
  { label: 'Active', value: '1' },
  { label: 'Inactive', value: '0' },
];

type SortKey = 'name' | 'credit' | 'created_at';
type SortDir = 'asc' | 'desc';

async function setActivation(userId: number, active: boolean) {
  const res = await axios.post<SuccessResponse<UserModel>>(
    apis.DASHBOARD.USER_MANAGEMENT.UPDATE_USER(userId.toString()),
    { is_activated: active ? '1' : '0' },
  );
  return res.data?.data;
}

function Pill({ label, className }: { label: string; className: string }) {
  return (
    <span className={`inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-medium ${className}`}>
      {label}
    </span>
  );
}

function StatCard({
  label,
  value,
  icon,
  tint,
  loading,
}: {
  label: string;
  value?: number;
  icon: React.ReactNode;
  tint: string;
  loading: boolean;
}) {
  return (
    <Card>
      <CardContent className="flex items-center gap-3 p-4">
        <span className={`flex size-10 items-center justify-center rounded-lg ${tint}`}>{icon}</span>
        <div>
          <div className="text-xs text-muted-foreground">{label}</div>
          <div className="text-xl font-semibold tabular-nums">
            {loading ? <span className="text-muted-foreground">…</span> : (value ?? 0).toLocaleString()}
          </div>
        </div>
      </CardContent>
    </Card>
  );
}

export function UsersListView() {
  const router = useRouter();
  const sp = useSearchParams();
  const qc = useQueryClient();

  const page = Number(sp?.get('page') ?? 1);
  const name = sp?.get('name') ?? '';
  const type = sp?.get('account_type_id') ?? '';
  const status = sp?.get('is_activated') ?? '';
  const verified = sp?.get('email_verified') ?? '';

  const [searchInput, setSearchInput] = useState(name);
  const [selected, setSelected] = useState<Set<number>>(new Set());
  const [sortKey, setSortKey] = useState<SortKey>('created_at');
  const [sortDir, setSortDir] = useState<SortDir>('desc');
  const [sheetUser, setSheetUser] = useState<UserModel | null>(null);
  const [sheetOpen, setSheetOpen] = useState(false);

  const listParams = useMemo(() => {
    const p: Record<string, unknown> = { page };
    if (name) p.name = name;
    if (type) p.account_type_id = type;
    if (status !== '') p.is_activated = status;
    if (verified !== '') p.email_verified = verified;
    return p;
  }, [page, name, type, status, verified]);

  const { data, isLoading, isFetching, error } = useQuery({
    queryKey: ['admin-users', listParams],
    queryFn: () => fetchUsers(listParams),
    retry: false,
  });

  // KPI counts — each reads pagination.total for its filter (truthful global counts).
  const kpiTotal = useQuery({ queryKey: ['users-kpi', 'total'], queryFn: () => fetchUsers({}), staleTime: 60_000 });
  const kpiActive = useQuery({ queryKey: ['users-kpi', 'active'], queryFn: () => fetchUsers({ is_activated: '1' }), staleTime: 60_000 });
  const kpiInactive = useQuery({ queryKey: ['users-kpi', 'inactive'], queryFn: () => fetchUsers({ is_activated: '0' }), staleTime: 60_000 });
  const kpiVerified = useQuery({ queryKey: ['users-kpi', 'verified'], queryFn: () => fetchUsers({ email_verified: '1' }), staleTime: 60_000 });

  const items = data?.items ?? [];
  const pagination = data?.pagination;
  const totalPages = pagination?.last_page ?? 1;

  const sortedItems = useMemo(() => {
    const arr = [...items];
    arr.sort((a, b) => {
      let cmp = 0;
      if (sortKey === 'name') cmp = fullName(a).localeCompare(fullName(b));
      else if (sortKey === 'credit') cmp = (a.credit ?? 0) - (b.credit ?? 0);
      else cmp = new Date(a.created_at).getTime() - new Date(b.created_at).getTime();
      return sortDir === 'asc' ? cmp : -cmp;
    });
    return arr;
  }, [items, sortKey, sortDir]);

  const updateUrl = (next: Record<string, string | null | undefined>) => {
    const params = new URLSearchParams(sp?.toString() ?? '');
    for (const [k, v] of Object.entries(next)) {
      if (v === null || v === undefined || v === '') params.delete(k);
      else params.set(k, v);
    }
    if (!('page' in next)) params.delete('page');
    setSelected(new Set());
    router.push(`?${params.toString()}`);
  };

  const toggleSort = (key: SortKey) => {
    if (sortKey === key) setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'));
    else {
      setSortKey(key);
      setSortDir(key === 'name' ? 'asc' : 'desc');
    }
  };

  const allOnPageSelected = sortedItems.length > 0 && sortedItems.every((u) => selected.has(u.id));
  const toggleSelectAll = () => {
    setSelected((prev) => {
      const next = new Set(prev);
      if (allOnPageSelected) sortedItems.forEach((u) => next.delete(u.id));
      else sortedItems.forEach((u) => next.add(u.id));
      return next;
    });
  };
  const toggleSelect = (id: number) => {
    setSelected((prev) => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  };

  const invalidate = () => {
    qc.invalidateQueries({ queryKey: ['admin-users'] });
    qc.invalidateQueries({ queryKey: ['users-kpi'] });
  };

  const toggleActivation = useMutation({
    mutationFn: (user: UserModel) => setActivation(user.id, !user.is_activated),
    onSuccess: (_, user) => {
      toast.success(`User ${user.is_activated ? 'deactivated' : 'activated'}`);
      invalidate();
      setSheetOpen(false);
    },
    onError: (e: any) => toast.error(e?.response?.data?.message || 'Failed to update status'),
  });

  const bulkActivation = useMutation({
    mutationFn: async ({ ids, active }: { ids: number[]; active: boolean }) => {
      await Promise.all(ids.map((id) => setActivation(id, active)));
    },
    onSuccess: (_, { active }) => {
      toast.success(`${selected.size} user(s) ${active ? 'activated' : 'deactivated'}`);
      setSelected(new Set());
      invalidate();
    },
    onError: (e: any) => toast.error(e?.response?.data?.message || 'Bulk update failed'),
  });

  const bulkArchive = useMutation({
    mutationFn: (ids: number[]) => archiveUsers(ids),
    onSuccess: (res) => {
      toast.success(`${res?.archived ?? selected.size} user(s) archived`);
      setSelected(new Set());
      invalidate();
    },
    onError: (e: any) => toast.error(e?.response?.data?.message || 'Archive failed'),
  });

  const busy = bulkActivation.isPending || bulkArchive.isPending;

  const openSheet = (user: UserModel) => {
    setSheetUser(user);
    setSheetOpen(true);
  };

  const SortHead = ({ label, k, className }: { label: string; k: SortKey; className?: string }) => (
    <TableHead className={className}>
      <button
        type="button"
        onClick={() => toggleSort(k)}
        className="inline-flex items-center gap-1 hover:text-foreground"
      >
        {label}
        {sortKey === k ? (
          sortDir === 'asc' ? <ArrowUp className="size-3.5" /> : <ArrowDown className="size-3.5" />
        ) : (
          <ArrowUpDown className="size-3.5 opacity-40" />
        )}
      </button>
    </TableHead>
  );

  return (
    <div className="space-y-5">
      {/* Header */}
      <div className="flex items-center justify-between gap-3">
        <div>
          <h1 className="text-2xl font-semibold">Users</h1>
          <p className="text-sm text-muted-foreground">Manage platform accounts, access and status.</p>
        </div>
        <Button onClick={() => router.push('/users/add')}>
          <Plus className="size-4 mr-1.5" /> Create user
        </Button>
      </div>

      {/* KPI strip */}
      <div className="grid grid-cols-2 lg:grid-cols-4 gap-3">
        <StatCard label="Total users" value={kpiTotal.data?.pagination?.total} loading={kpiTotal.isLoading} icon={<UsersIcon className="size-5 text-violet-600" />} tint="bg-violet-50" />
        <StatCard label="Active" value={kpiActive.data?.pagination?.total} loading={kpiActive.isLoading} icon={<UserCheck className="size-5 text-emerald-600" />} tint="bg-emerald-50" />
        <StatCard label="Inactive" value={kpiInactive.data?.pagination?.total} loading={kpiInactive.isLoading} icon={<UserX className="size-5 text-amber-600" />} tint="bg-amber-50" />
        <StatCard label="Verified emails" value={kpiVerified.data?.pagination?.total} loading={kpiVerified.isLoading} icon={<BadgeCheck className="size-5 text-blue-600" />} tint="bg-blue-50" />
      </div>

      {/* Toolbar */}
      <Card>
        <CardContent className="space-y-3 pt-4">
          <div className="flex flex-col sm:flex-row gap-2">
            <div className="relative flex-1">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground" />
              <Input
                value={searchInput}
                onChange={(e) => setSearchInput(e.target.value)}
                onKeyDown={(e) => e.key === 'Enter' && updateUrl({ name: searchInput })}
                placeholder="Search by name…"
                className="pl-9"
              />
            </div>
            <div className="flex gap-2">
              <Button onClick={() => updateUrl({ name: searchInput })}>
                <Search className="size-4 mr-1" /> Search
              </Button>
              <Button
                variant={verified === '1' ? 'primary' : 'outline'}
                onClick={() => updateUrl({ email_verified: verified === '1' ? null : '1' })}
              >
                <BadgeCheck className="size-4 mr-1" /> Verified
              </Button>
              {(name || type || status !== '' || verified !== '') && (
                <Button variant="outline" onClick={() => { setSearchInput(''); router.push('?'); setSelected(new Set()); }}>
                  <X className="size-4" />
                </Button>
              )}
            </div>
          </div>

          <div className="flex flex-wrap items-center gap-2">
            <span className="text-xs text-muted-foreground mr-1">Type:</span>
            {TYPE_CHIPS.map((c) => (
              <Button key={c.value || 'all'} size="sm" variant={type === c.value ? 'primary' : 'outline'} onClick={() => updateUrl({ account_type_id: c.value || null })}>
                {c.label}
              </Button>
            ))}
            <span className="text-xs text-muted-foreground mx-1">Status:</span>
            {STATUS_CHIPS.map((c) => (
              <Button key={c.value || 'all'} size="sm" variant={status === c.value ? 'primary' : 'outline'} onClick={() => updateUrl({ is_activated: c.value === '' ? null : c.value })}>
                {c.label}
              </Button>
            ))}
          </div>
        </CardContent>
      </Card>

      {/* Bulk action bar */}
      {selected.size > 0 && (
        <div className="flex flex-wrap items-center gap-2 rounded-lg border bg-muted/40 px-4 py-2">
          <span className="text-sm font-medium">{selected.size} selected</span>
          <div className="flex-1" />
          <Button size="sm" variant="outline" disabled={busy} onClick={() => bulkActivation.mutate({ ids: Array.from(selected), active: true })}>Activate</Button>
          <Button size="sm" variant="outline" disabled={busy} onClick={() => bulkActivation.mutate({ ids: Array.from(selected), active: false })}>Deactivate</Button>
          <Button size="sm" variant="outline" className="text-red-600 border-red-200 hover:bg-red-50" disabled={busy} onClick={() => bulkArchive.mutate(Array.from(selected))}>Archive</Button>
          {busy && <Spinner className="size-4 animate-spin" />}
        </div>
      )}

      {/* Table */}
      <Card>
        <CardContent className="p-0 overflow-x-auto">
          {isLoading ? (
            <div className="flex items-center justify-center py-16"><Spinner className="size-8 animate-spin text-primary" /></div>
          ) : error ? (
            <div className="p-6 text-sm text-red-600">Failed to load users: {(error as any)?.response?.data?.message || (error as Error)?.message}</div>
          ) : sortedItems.length === 0 ? (
            <div className="py-16 text-center text-muted-foreground">No users match your filters.</div>
          ) : (
            <Table>
              <TableHeader>
                <TableRow className="bg-accent/40">
                  <TableHead className="w-10">
                    <Checkbox checked={allOnPageSelected} onCheckedChange={toggleSelectAll} aria-label="Select all" />
                  </TableHead>
                  <SortHead label="User" k="name" />
                  <TableHead>Type</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead>Phone</TableHead>
                  <TableHead>Country</TableHead>
                  <SortHead label="Credit" k="credit" className="text-right" />
                  <SortHead label="Created" k="created_at" />
                  <TableHead className="w-10 text-right">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {sortedItems.map((u) => {
                  const t = accountTypeMeta(u.account_type_id, u.account_type);
                  const s = statusMeta(u.is_activated);
                  return (
                    <TableRow key={u.id} className="cursor-pointer hover:bg-muted/40" onClick={() => openSheet(u)}>
                      <TableCell onClick={(e) => e.stopPropagation()}>
                        <Checkbox checked={selected.has(u.id)} onCheckedChange={() => toggleSelect(u.id)} aria-label={`Select ${fullName(u)}`} />
                      </TableCell>
                      <TableCell>
                        <div className="flex items-center gap-3">
                          <span className={`flex size-9 items-center justify-center rounded-full text-xs font-semibold shrink-0 ${avatarTint(u.id)}`}>
                            {getInitials(u)}
                          </span>
                          <div className="min-w-0">
                            <div className="font-medium truncate max-w-[200px]">{fullName(u)}</div>
                            <div className="text-xs text-muted-foreground truncate max-w-[200px]">{u.email}</div>
                          </div>
                        </div>
                      </TableCell>
                      <TableCell><Pill {...t} /></TableCell>
                      <TableCell><Pill {...s} /></TableCell>
                      <TableCell className="text-sm whitespace-nowrap">{u.phone || '—'}</TableCell>
                      <TableCell className="text-sm">{u.country?.name || '—'}</TableCell>
                      <TableCell className="text-right tabular-nums font-medium">{(u.credit ?? 0).toLocaleString()}</TableCell>
                      <TableCell className="text-sm whitespace-nowrap">{formatDateTime(u.created_at)}</TableCell>
                      <TableCell className="text-right" onClick={(e) => e.stopPropagation()}>
                        <DropdownMenu>
                          <DropdownMenuTrigger asChild>
                            <Button variant="ghost" size="sm" className="size-8 p-0"><MoreHorizontal className="size-4" /></Button>
                          </DropdownMenuTrigger>
                          <DropdownMenuContent align="end">
                            <DropdownMenuItem onClick={() => openSheet(u)}>Quick view</DropdownMenuItem>
                            <DropdownMenuItem onClick={() => router.push(`/users/${u.id}`)}>Full profile</DropdownMenuItem>
                            <DropdownMenuItem onClick={() => router.push(`/users/add/${u.id}`)}>Edit</DropdownMenuItem>
                            <DropdownMenuSeparator />
                            <DropdownMenuItem onClick={() => toggleActivation.mutate(u)}>
                              {u.is_activated ? 'Deactivate' : 'Activate'}
                            </DropdownMenuItem>
                            <DropdownMenuItem className="text-red-600" onClick={() => bulkArchive.mutate([u.id])}>Archive</DropdownMenuItem>
                          </DropdownMenuContent>
                        </DropdownMenu>
                      </TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>

      {/* Footer */}
      <div className="flex items-center justify-between">
        <div className="text-xs text-muted-foreground flex items-center gap-2">
          {isFetching && !isLoading ? (<><RefreshCw className="size-3.5 animate-spin" /> Refreshing…</>) : pagination ? `${pagination.total} total` : null}
        </div>
        {totalPages > 1 && (
          <PaginationComponent currentPage={pagination?.current_page ?? page} totalPages={totalPages} onPageChange={(p) => updateUrl({ page: String(p) })} />
        )}
      </div>

      <UserDetailSheet
        user={sheetUser}
        open={sheetOpen}
        onClose={() => setSheetOpen(false)}
        onToggleActivation={(u) => toggleActivation.mutate(u)}
        toggling={toggleActivation.isPending}
      />
    </div>
  );
}
