'use client';

import { useCallback, useEffect, useMemo, useState, useTransition } from 'react';
import { useMutation, useQuery } from '@tanstack/react-query';
import { useRouter, useSearchParams } from 'next/navigation';
import { Pagination, UserModel } from '@/utils/types/User';
import {
  RiCheckboxCircleFill,
  RiErrorWarningFill,
  RiEditLine,
  RiSearchLine,
  RiFilterOffLine,
  RiAddLine,
  RiDownloadLine,
  RiMore2Line,
  RiUserFollowLine,
  RiUserUnfollowLine,
  RiHistoryLine,
  RiArchiveLine,
  RiInboxUnarchiveLine,
} from '@remixicon/react';
import { Checkbox } from '@/components/ui/checkbox';
import { archiveUsers, unarchiveUsers, type ArchiveResult } from '@/network/apis/dashboard/userManagment/users/users.apis';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { apis } from '@/utils/apis/apis';
import { toast } from 'sonner';
import { Alert, AlertIcon, AlertTitle } from '@/components/ui/alert';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
  Card,
  CardContent,
  CardFooter,
  CardHeader,
} from '@/components/ui/card';
import { Spinner } from '@/components/ui/spinners';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import PaginationComponent from '../paginationComponent/paginationComponent';
import AddBalanceModal from '../AddBalanceModal/AddBalanceModal';
import useEditBalance from '@/modules/users/hooks/useEditBalance';
import { updateUsers } from '@/network/apis/dashboard/userManagment/users/users.apis';
import axios from '@/network/axios';

type BalanceLastAddition = {
  amount: number;
  balance_after: number;
  date: string;
  action: string;
};

type BalanceEntry = {
  type_balance: number;
  label: string;
  current_balance: number;
  total_added: number;
  total_used: number;
  last_addition: BalanceLastAddition | null;
};

type BalanceSummaryResponse = {
  user_id: number;
  user_name: string;
  email: string;
  balances: BalanceEntry[];
};

type BalanceSummaryMap = Record<number, Record<number, BalanceEntry>>;

const UsersClientList = ({
  users: initialUsers,
  pagination,
  mode = 'active',
}: {
  users: UserModel[] | null;
  pagination: Pagination | undefined;
  mode?: 'active' | 'archived';
}) => {
  const isArchivedView = mode === 'archived';
  const router = useRouter();
  const searchParams = useSearchParams();
  const [isPending, startTransition] = useTransition();
  const [users, setUsers] = useState<UserModel[] | null>(initialUsers);

  const [filters, setFilters] = useState({
    name: searchParams?.get('name') || '',
    email: searchParams?.get('email') || '',
    phone: searchParams?.get('phone') || '',
    is_activated: searchParams?.get('is_activated') || '',
  });
  const [showFilters, setShowFilters] = useState(
    !!(searchParams?.get('name') || searchParams?.get('email') || searchParams?.get('phone') || searchParams?.get('is_activated')),
  );

  const currentPage = useMemo(() => {
    const fromUrl = Number(searchParams?.get('page') || '');
    if (!Number.isNaN(fromUrl) && fromUrl > 0) return fromUrl;
    return pagination?.current_page ?? 1;
  }, [searchParams, pagination]);

  const totalPages = useMemo(() => {
    if (pagination?.last_page) return pagination.last_page;
    if (pagination?.total && pagination?.per_page) {
      return Math.max(1, Math.ceil(pagination.total / pagination.per_page));
    }
    return 1;
  }, [pagination]);

  const { mutateAsync: editBalanceAsync, isPending: isEditingBalance } = useEditBalance();
  const { mutateAsync: updateUserAsync, isPending: isUpdatingUser } = useMutation({
    mutationFn: ({ id, data }: { id: string; data: FormData }) => updateUsers(data, id),
  });

  const [isEditBalanceDialogOpen, setIsEditBalanceDialogOpen] = useState(false);
  const [selectedUser, setSelectedUser] = useState<UserModel | null>(null);
  const [balanceFormData, setBalanceFormData] = useState({
    credit: '',
    requests_balance: '',
    search_balance: '',
    social_listening_balance: '',
    lookalike_balance: '',
    mynetwork_balance: '',
    campaign_balance: '',
    competitor_analysis_balance: '',
    phone_number_balance: '',
    media_plan_balance: '',
    media_plan_creators_balance: '',
    notes: '',
    end_date: '',
  });
  const [editedFields, setEditedFields] = useState<Set<string>>(new Set());
  const [endDateChanged, setEndDateChanged] = useState(false);
  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set());

  useEffect(() => {
    setSelectedIds(new Set());
  }, [initialUsers]);

  const SKIPPED_LABELS: Record<string, string> = {
    self: 'cannot archive yourself',
    privileged: 'admin/privileged users',
    not_found: 'not found',
  };

  const showArchiveResult = (result: ArchiveResult | undefined, action: 'archived' | 'unarchived') => {
    const successCount = action === 'archived' ? (result?.archived ?? 0) : (result?.unarchived ?? 0);
    const skipped = result?.skipped ?? {};
    const skippedDetails: string[] = [];
    let skippedCount = 0;
    for (const [key, arr] of Object.entries(skipped)) {
      const list = Array.isArray(arr) ? arr : [];
      if (list.length > 0) {
        skippedCount += list.length;
        const label = SKIPPED_LABELS[key] ?? key;
        skippedDetails.push(`${list.length} ${label}`);
      }
    }
    let msg = `${successCount} ${action}.`;
    if (skippedCount > 0) {
      msg += ` ${skippedCount} skipped${skippedDetails.length ? ` (${skippedDetails.join(', ')})` : ''}.`;
    }
    if (successCount > 0 && skippedCount === 0) toast.success(msg);
    else if (successCount > 0) toast.warning(msg);
    else toast.error(msg);
  };

  const archiveMutation = useMutation({
    mutationFn: (ids: number[]) => archiveUsers(ids),
    onSuccess: (data, ids) => {
      showArchiveResult(data, 'archived');
      const successCount = data?.archived ?? 0;
      if (successCount > 0) {
        const processedIds = new Set(data?.ids ?? ids);
        setUsers((prev) => (prev ?? []).filter((u) => !processedIds.has(u.id)));
      }
      setSelectedIds(new Set());
      router.refresh();
    },
    onError: (error: unknown) => {
      const errMsg = (error as { response?: { data?: { message?: string } } })?.response?.data?.message
        || 'Failed to archive clients';
      toast.error(errMsg);
    },
  });

  const unarchiveMutation = useMutation({
    mutationFn: (ids: number[]) => unarchiveUsers(ids),
    onSuccess: (data, ids) => {
      showArchiveResult(data, 'unarchived');
      const successCount = data?.unarchived ?? 0;
      if (successCount > 0) {
        const processedIds = new Set(data?.ids ?? ids);
        setUsers((prev) => (prev ?? []).filter((u) => !processedIds.has(u.id)));
      }
      setSelectedIds(new Set());
      router.refresh();
    },
    onError: (error: unknown) => {
      const errMsg = (error as { response?: { data?: { message?: string } } })?.response?.data?.message
        || 'Failed to unarchive clients';
      toast.error(errMsg);
    },
  });

  const toggleSelectAll = () => {
    if (!users) return;
    if (selectedIds.size === users.length) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(users.map((u) => u.id)));
    }
  };

  const toggleSelectOne = (id: number) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  const handleBulkAction = () => {
    const ids = Array.from(selectedIds);
    if (ids.length === 0) return;
    const verb = isArchivedView ? 'unarchive' : 'archive';
    if (!window.confirm(`${verb === 'archive' ? 'Archive' : 'Unarchive'} ${ids.length} client${ids.length === 1 ? '' : 's'}?`)) return;
    if (isArchivedView) unarchiveMutation.mutate(ids);
    else archiveMutation.mutate(ids);
  };

  const handleRowAction = (id: number) => {
    if (!window.confirm(isArchivedView ? 'Unarchive this client?' : 'Archive this client?')) return;
    if (isArchivedView) unarchiveMutation.mutate([id]);
    else archiveMutation.mutate([id]);
  };

  const userIds = useMemo(() => (initialUsers ?? []).map((u) => u.id), [initialUsers]);

  const fetchBalanceSummaries = useCallback(async () => {
    if (!userIds.length) return {} as BalanceSummaryMap;
    const results = await Promise.allSettled(
      userIds.map((uid) =>
        axios
          .get<{ status: boolean; data: BalanceSummaryResponse }>(
            '/dashboard/balance/summary',
            { params: { user_id: uid } },
          )
          .then((r) => r.data.data),
      ),
    );
    const map: BalanceSummaryMap = {};
    results.forEach((r) => {
      if (r.status === 'fulfilled' && r.value) {
        const byType: Record<number, BalanceEntry> = {};
        r.value.balances?.forEach((b) => {
          byType[b.type_balance] = b;
        });
        map[r.value.user_id] = byType;
      }
    });
    return map;
  }, [userIds]);

  const { data: balanceSummaries } = useQuery<BalanceSummaryMap>({
    queryKey: ['balance-summaries', userIds],
    queryFn: fetchBalanceSummaries,
    enabled: userIds.length > 0,
    staleTime: 60_000,
  });

  const getBalance = (userId: number, typeBalance: number): BalanceEntry | undefined => {
    return balanceSummaries?.[userId]?.[typeBalance];
  };

  useEffect(() => {
    setUsers(initialUsers);
  }, [initialUsers]);

  useEffect(() => {
    setFilters({
      name: searchParams?.get('name') || '',
      email: searchParams?.get('email') || '',
      phone: searchParams?.get('phone') || '',
      is_activated: searchParams?.get('is_activated') || '',
    });
    setShowFilters(
      !!(searchParams?.get('name') || searchParams?.get('email') || searchParams?.get('phone') || searchParams?.get('is_activated')),
    );
  }, [searchParams]);

  const BALANCE_FIELDS = [
    { key: 'credit', label: 'Credit', typeId: 0 },
    { key: 'requests_balance', label: 'Reports Balance', typeId: 1 },
    { key: 'search_balance', label: 'Search Balance', typeId: 2 },
    { key: 'social_listening_balance', label: 'Social Listening Balance', typeId: 3 },
    { key: 'lookalike_balance', label: 'Lookalike Balance', typeId: 4 },
    { key: 'mynetwork_balance', label: 'Network Balance', typeId: 5 },
    { key: 'campaign_balance', label: 'Campaign Management Balance', typeId: 6 },
    { key: 'competitor_analysis_balance', label: 'Competitor Analysis Balance', typeId: 7 },
    { key: 'phone_number_balance', label: 'Phone Number Balance', typeId: 8 },
    { key: 'media_plan_balance', label: 'Media Plan Balance', typeId: 9 },
    { key: 'media_plan_creators_balance', label: 'Media Plan Creators Balance', typeId: 10 },
    { key: 'whatsapp_message_balance', label: 'WhatsApp Messages Balance', typeId: 11 },
    { key: 'collaboration_request_balance', label: 'Collaboration Requests Balance', typeId: 12 },
    { key: 'relationship_lists_limit', label: 'Relationship Lists Limit', typeId: 13 },
    { key: 'influencers_per_list_limit', label: 'Influencers per List Limit', typeId: 14 },
  ] as const;

  const applyFilters = () => {
    startTransition(() => {
      const params = new URLSearchParams();
      if (filters.name.trim()) params.set('name', filters.name.trim());
      if (filters.email.trim()) params.set('email', filters.email.trim());
      if (filters.phone.trim()) params.set('phone', filters.phone.trim());
      if (filters.is_activated) params.set('is_activated', filters.is_activated);
      router.push(`?${params.toString()}`);
    });
  };

  const clearFilters = () => {
    startTransition(() => {
      setFilters({ name: '', email: '', phone: '', is_activated: '' });
      router.push('?page=1');
    });
  };

  const handleFilterKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter') applyFilters();
  };

  const hasActiveFilters = !!(filters.name.trim() || filters.email.trim() || filters.phone.trim() || filters.is_activated);

  const handleOpenEditBalanceDialog = (e: React.MouseEvent, user: UserModel) => {
    e.stopPropagation();
    setSelectedUser(user);
    const summaryMap = balanceSummaries?.[user.id];
    setBalanceFormData({
      credit: String(user.credit ?? 0),
      requests_balance: String(summaryMap?.[1]?.current_balance ?? user.requests_balance ?? 0),
      search_balance: String(summaryMap?.[2]?.current_balance ?? user.search_balance ?? 0),
      social_listening_balance: String(summaryMap?.[3]?.current_balance ?? user.social_listening_balance ?? 0),
      lookalike_balance: String(summaryMap?.[4]?.current_balance ?? user.lookalike_balance ?? 0),
      mynetwork_balance: String(summaryMap?.[5]?.current_balance ?? user.mynetwork_balance ?? 0),
      campaign_balance: String(summaryMap?.[6]?.current_balance ?? user.campaign_balance ?? 0),
      competitor_analysis_balance: String(summaryMap?.[7]?.current_balance ?? user.competitor_analysis_balance ?? 0),
      phone_number_balance: String(summaryMap?.[8]?.current_balance ?? user.phone_number_balance ?? 0),
      media_plan_balance: String(summaryMap?.[9]?.current_balance ?? user.media_plan_balance ?? 0),
      media_plan_creators_balance: String(summaryMap?.[10]?.current_balance ?? user.media_plan_creators_balance ?? 0),
      notes: '',
      end_date: user.subscription_end_date
        ? new Date(user.subscription_end_date).toISOString().split('T')[0]
        : '',
    });
    setEditedFields(new Set());
    setEndDateChanged(false);
    setIsEditBalanceDialogOpen(true);
  };

  const toggleActivation = useMutation({
    mutationFn: async ({ userId, activate }: { userId: number; activate: boolean }) => {
      const formData = new FormData();
      formData.append('is_activated', activate ? '1' : '0');
      const res = await axios.post(apis.DASHBOARD.USER_MANAGEMENT.UPDATE_USER(String(userId)), formData);
      return res.data;
    },
    onSuccess: (_data, variables) => {
      toast.success(variables.activate ? 'Client activated successfully' : 'Client deactivated successfully');
      setUsers((prev) =>
        (prev ?? []).map((u) =>
          u.id === variables.userId ? { ...u, is_activated: variables.activate } : u,
        ),
      );
    },
    onError: (error: unknown) => {
      const errMsg =
        (error as { response?: { data?: { message?: string } } })?.response?.data?.message
        || 'Failed to update client status';
      toast.error(errMsg);
    },
  });

  const handleToggleActivation = (user: UserModel) => {
    const newState = !user.is_activated;
    toggleActivation.mutate({ userId: user.id, activate: newState });
  };

  const handleCloseEditBalanceDialog = () => {
    setIsEditBalanceDialogOpen(false);
    setSelectedUser(null);
    setEditedFields(new Set());
    setEndDateChanged(false);
  };

  const handleBalanceFieldChange = (key: string, value: string) => {
    setBalanceFormData((prev) => ({ ...prev, [key]: value }));
    setEditedFields((prev) => {
      const next = new Set(prev);
      const originalValue = String((selectedUser as Record<string, unknown>)?.[key] ?? 0);
      if (value !== originalValue) {
        next.add(key);
      } else {
        next.delete(key);
      }
      return next;
    });
  };

  const handleSubmitEditBalance = async () => {
    if (!selectedUser) return;
    const promises: Promise<unknown>[] = [];

    for (const field of BALANCE_FIELDS) {
      if (editedFields.has(field.key)) {
        const newVal = Number(balanceFormData[field.key as keyof typeof balanceFormData]);
        if (field.typeId === 0) {
          const fd = new FormData();
          fd.append('credit', String(newVal));
          promises.push(updateUserAsync({ id: String(selectedUser.id), data: fd }));
        } else {
          promises.push(
            editBalanceAsync({
              user_id: selectedUser.id,
              type_balance: field.typeId,
              new_balance: newVal,
              notes: balanceFormData.notes,
            }),
          );
        }
      }
    }

    if (balanceFormData.end_date) {
      const originalEndDate = selectedUser.subscription_end_date
        ? new Date(selectedUser.subscription_end_date).toISOString().split('T')[0]
        : '';
      if (balanceFormData.end_date !== originalEndDate) {
        const fd = new FormData();
        fd.append('end_date', balanceFormData.end_date);
        promises.push(updateUserAsync({ id: String(selectedUser.id), data: fd }));
      }
    }

    if (promises.length === 0) {
      handleCloseEditBalanceDialog();
      return;
    }

    try {
      await Promise.all(promises);

      setUsers(
        (prevUsers) =>
          prevUsers?.map((u) => {
            if (u.id === selectedUser.id) {
              const updatedUser = { ...u };
              for (const field of BALANCE_FIELDS) {
                if (editedFields.has(field.key)) {
                  (updatedUser as Record<string, unknown>)[field.key] = Number(
                    balanceFormData[field.key as keyof typeof balanceFormData],
                  );
                }
              }
              return updatedUser;
            }
            return u;
          }) ?? null,
      );

      toast.custom(
        () => (
          <Alert variant="mono" icon="success" close={false}>
            <AlertIcon>
              <RiCheckboxCircleFill />
            </AlertIcon>
            <AlertTitle>Updated successfully</AlertTitle>
          </Alert>
        ),
        { position: 'top-center' },
      );
      handleCloseEditBalanceDialog();
      router.refresh();
    } catch (error) {
      toast.custom(
        () => (
          <Alert variant="mono" icon="destructive" close={false}>
            <AlertIcon>
              <RiErrorWarningFill />
            </AlertIcon>
            <AlertTitle>
              {error instanceof Error ? error.message : 'Failed to update'}
            </AlertTitle>
          </Alert>
        ),
        { position: 'top-center' },
      );
    }
  };

  const handlePageChange = (page: number) => {
    const params = new URLSearchParams(searchParams?.toString());
    params.set('page', String(page));
    router.push(`?${params.toString()}`);
  };

  const formatDate = (dateString: string | null) => {
    if (!dateString) return '-';
    return new Date(dateString).toLocaleDateString('en-US', {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
    });
  };

  const handleExportCSV = () => {
    if (!users?.length) return;
    const headers = [
      'Name', 'Email', 'Phone', 'Brand', 'Country', 'Status', 'Credit',
      'Reports Balance', 'Search Balance', 'Social Listening', 'Lookalike',
      'Network', 'Campaign Mgmt', 'Competitor Analysis', 'Phone Number',
      'Media Plan', 'Media Plan Creators',
      'Subscription', 'Sub Start', 'Sub End', 'Created At',
    ];
    const escapeCSV = (val: unknown) => {
      const s = String(val ?? '');
      return `"${s.replace(/"/g, '""')}"`;
    };
    const rows = users.map((u) => {
      const sm = balanceSummaries?.[u.id];
      return [
        `${u.first_name ?? ''} ${u.last_name ?? ''}`.trim(),
        u.email, u.phone, u.brand_name, u.country?.name ?? '',
        u.is_activated ? 'Active' : 'Inactive', u.credit,
        sm?.[1]?.current_balance ?? u.requests_balance ?? 0,
        sm?.[2]?.current_balance ?? u.search_balance ?? 0,
        sm?.[3]?.current_balance ?? u.social_listening_balance ?? 0,
        sm?.[4]?.current_balance ?? u.lookalike_balance ?? 0,
        sm?.[5]?.current_balance ?? u.mynetwork_balance ?? 0,
        sm?.[6]?.current_balance ?? u.campaign_balance ?? 0,
        sm?.[7]?.current_balance ?? u.competitor_analysis_balance ?? 0,
        sm?.[8]?.current_balance ?? u.phone_number_balance ?? 0,
        sm?.[9]?.current_balance ?? u.media_plan_balance ?? 0,
        sm?.[10]?.current_balance ?? u.media_plan_creators_balance ?? 0,
        u.is_paid_subscription ? (u.paid_subscription ?? 'Yes') : 'None',
        formatDate(u.subscription_start_date),
        formatDate(u.subscription_end_date), formatDate(u.created_at),
      ];
    });
    const csv = [headers.join(','), ...rows.map((r) => r.map(escapeCSV).join(','))].join('\n');
    const blob = new Blob([csv], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `clients_export_${new Date().toISOString().split('T')[0]}.csv`;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <>
      <Card>
        <CardHeader className="pb-4">
          <div className="flex flex-col gap-4">
            <div className="flex items-center justify-between">
              <div>
                <h2 className="text-xl font-semibold text-foreground">
                  {isArchivedView ? 'Archived Clients' : 'Client Management'}
                </h2>
                <p className="text-sm text-muted-foreground mt-0.5">
                  {pagination?.total ?? users?.length ?? 0} {isArchivedView ? 'archived' : 'total'} clients
                </p>
              </div>
              <div className="flex items-center gap-2">
                {selectedIds.size > 0 && (
                  <Button
                    variant={isArchivedView ? 'primary' : 'destructive'}
                    size="sm"
                    onClick={handleBulkAction}
                    disabled={archiveMutation.isPending || unarchiveMutation.isPending}
                  >
                    {isArchivedView ? (
                      <RiInboxUnarchiveLine className="size-4 mr-1.5" />
                    ) : (
                      <RiArchiveLine className="size-4 mr-1.5" />
                    )}
                    {isArchivedView ? 'Unarchive' : 'Archive'} Selected ({selectedIds.size})
                  </Button>
                )}
                <Button
                  variant={showFilters ? 'primary' : 'outline'}
                  size="sm"
                  onClick={() => setShowFilters(!showFilters)}
                >
                  <RiSearchLine className="size-4 mr-1.5" />
                  Filters
                  {hasActiveFilters && (
                    <span className="ml-1.5 size-5 rounded-full bg-white text-primary text-xs flex items-center justify-center font-semibold">
                      !
                    </span>
                  )}
                </Button>
                <Button variant="outline" size="sm" onClick={handleExportCSV} disabled={!users?.length}>
                  <RiDownloadLine className="size-4 mr-1.5" />
                  Export
                </Button>
                {!isArchivedView && (
                  <>
                    <Button variant="outline" size="sm" onClick={() => router.push('/client-management/archived')}>
                      <RiArchiveLine className="size-4 mr-1.5" />
                      Archived
                    </Button>
                    <Button size="sm" onClick={() => router.push('/client-management/add')}>
                      <RiAddLine className="size-4 mr-1.5" />
                      Add Client
                    </Button>
                  </>
                )}
                {isArchivedView && (
                  <Button variant="outline" size="sm" onClick={() => router.push('/client-management')}>
                    Back to Clients
                  </Button>
                )}
              </div>
            </div>

            {showFilters && (
              <div className="rounded-lg border bg-muted/30 p-4">
                <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-3">
                  <div>
                    <Label className="text-xs font-medium text-muted-foreground mb-1.5 block">Name</Label>
                    <Input
                      placeholder="Search name..."
                      value={filters.name}
                      onChange={(e) => setFilters({ ...filters, name: e.target.value })}
                      onKeyDown={handleFilterKeyDown}
                      className="h-9"
                    />
                  </div>
                  <div>
                    <Label className="text-xs font-medium text-muted-foreground mb-1.5 block">Email</Label>
                    <Input
                      placeholder="Search email..."
                      value={filters.email}
                      onChange={(e) => setFilters({ ...filters, email: e.target.value })}
                      onKeyDown={handleFilterKeyDown}
                      className="h-9"
                    />
                  </div>
                  <div>
                    <Label className="text-xs font-medium text-muted-foreground mb-1.5 block">Phone</Label>
                    <Input
                      placeholder="Search phone..."
                      value={filters.phone}
                      onChange={(e) => setFilters({ ...filters, phone: e.target.value })}
                      onKeyDown={handleFilterKeyDown}
                      className="h-9"
                    />
                  </div>
                  <div>
                    <Label className="text-xs font-medium text-muted-foreground mb-1.5 block">Status</Label>
                    <Select
                      value={filters.is_activated}
                      onValueChange={(value) => setFilters({ ...filters, is_activated: value === 'all' ? '' : value })}
                    >
                      <SelectTrigger className="h-9">
                        <SelectValue placeholder="All statuses" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="all">All</SelectItem>
                        <SelectItem value="1">Active</SelectItem>
                        <SelectItem value="0">Inactive</SelectItem>
                      </SelectContent>
                    </Select>
                  </div>
                  <div className="flex items-end gap-2">
                    <Button size="sm" className="h-9" onClick={applyFilters} disabled={isPending}>
                      {isPending ? <Spinner className="size-4 animate-spin" /> : <RiSearchLine className="size-4" />}
                      <span className="ml-1.5">Apply</span>
                    </Button>
                    {hasActiveFilters && (
                      <Button variant="outline" size="sm" className="h-9" onClick={clearFilters} disabled={isPending}>
                        <RiFilterOffLine className="size-4" />
                        <span className="ml-1.5">Clear</span>
                      </Button>
                    )}
                  </div>
                </div>
              </div>
            )}
          </div>
        </CardHeader>

        <CardContent className="overflow-x-auto p-0">
          <Table className="min-w-max">
            <TableHeader>
              <TableRow className="bg-muted/50">
                <TableHead className="w-10 h-10 sticky left-0 bg-muted/50 z-20 px-2">
                  <Checkbox
                    checked={!!users?.length && selectedIds.size === users.length}
                    onCheckedChange={toggleSelectAll}
                    aria-label="Select all"
                  />
                </TableHead>
                <TableHead className="min-w-[160px] h-10 sticky left-10 bg-muted/50 z-10 font-semibold">Name</TableHead>
                <TableHead className="min-w-[180px] h-10 font-semibold">Email</TableHead>
                <TableHead className="min-w-[120px] h-10 font-semibold">Phone</TableHead>
                <TableHead className="min-w-[120px] h-10 font-semibold">Brand</TableHead>
                <TableHead className="min-w-[100px] h-10 font-semibold">Country</TableHead>
                <TableHead className="min-w-[80px] h-10 font-semibold">Type</TableHead>
                <TableHead className="min-w-[80px] h-10 font-semibold">Status</TableHead>
                <TableHead className="min-w-[70px] h-10 font-semibold text-right">Credit</TableHead>
                <TableHead className="min-w-[110px] h-10 font-semibold text-right"><div>Reports<div className="text-[10px] font-normal text-muted-foreground">added/current</div></div></TableHead>
                <TableHead className="min-w-[110px] h-10 font-semibold text-right"><div>Search<div className="text-[10px] font-normal text-muted-foreground">added/current</div></div></TableHead>
                <TableHead className="min-w-[120px] h-10 font-semibold text-right"><div>Social Listen.<div className="text-[10px] font-normal text-muted-foreground">added/current</div></div></TableHead>
                <TableHead className="min-w-[110px] h-10 font-semibold text-right"><div>Lookalike<div className="text-[10px] font-normal text-muted-foreground">added/current</div></div></TableHead>
                <TableHead className="min-w-[110px] h-10 font-semibold text-right"><div>Network<div className="text-[10px] font-normal text-muted-foreground">added/current</div></div></TableHead>
                <TableHead className="min-w-[120px] h-10 font-semibold text-right"><div>Campaign<div className="text-[10px] font-normal text-muted-foreground">added/current</div></div></TableHead>
                <TableHead className="min-w-[120px] h-10 font-semibold text-right"><div>Competitor<div className="text-[10px] font-normal text-muted-foreground">added/current</div></div></TableHead>
                <TableHead className="min-w-[120px] h-10 font-semibold text-right"><div>Phone Number<div className="text-[10px] font-normal text-muted-foreground">added/current</div></div></TableHead>
                <TableHead className="min-w-[120px] h-10 font-semibold text-right"><div>Media Plan<div className="text-[10px] font-normal text-muted-foreground">added/current</div></div></TableHead>
                <TableHead className="min-w-[130px] h-10 font-semibold text-right"><div>MP Creators<div className="text-[10px] font-normal text-muted-foreground">added/current</div></div></TableHead>
                <TableHead className="min-w-[120px] h-10 font-semibold text-right"><div>WhatsApp<div className="text-[10px] font-normal text-muted-foreground">added/current</div></div></TableHead>
                <TableHead className="min-w-[130px] h-10 font-semibold text-right"><div>Collab. Req.<div className="text-[10px] font-normal text-muted-foreground">added/current</div></div></TableHead>
                <TableHead className="min-w-[120px] h-10 font-semibold text-right"><div>Rel. Lists<div className="text-[10px] font-normal text-muted-foreground">limit</div></div></TableHead>
                <TableHead className="min-w-[120px] h-10 font-semibold text-right"><div>Inf./List<div className="text-[10px] font-normal text-muted-foreground">limit</div></div></TableHead>
                <TableHead className="min-w-[90px] h-10 font-semibold text-right hidden">Used</TableHead>
                <TableHead className="min-w-[100px] h-10 font-semibold">Subscription</TableHead>
                <TableHead className="min-w-[100px] h-10 font-semibold">Sub Start</TableHead>
                <TableHead className="min-w-[100px] h-10 font-semibold">Sub End</TableHead>
                <TableHead className="min-w-[100px] h-10 font-semibold">Created</TableHead>
                <TableHead className="min-w-[100px] h-10 font-semibold">Created By</TableHead>
                <TableHead className="min-w-[90px] h-10 font-semibold text-center sticky right-0 bg-muted/50 z-10">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {users && users.length > 0 ? (
                users.map((user) => {
                  const fullName = `${user.first_name ?? ''} ${user.last_name ?? ''}`.trim() || '-';
                  return (
                    <TableRow
                      key={user.id}
                      className="cursor-pointer hover:bg-muted/40 transition-colors"
                      onClick={() => router.push(`/client-management/${user.id}`)}
                    >
                      <TableCell
                        className="sticky left-0 bg-background z-20 px-2"
                        onClick={(e) => e.stopPropagation()}
                      >
                        <Checkbox
                          checked={selectedIds.has(user.id)}
                          onCheckedChange={() => toggleSelectOne(user.id)}
                          aria-label={`Select ${fullName}`}
                        />
                      </TableCell>
                      <TableCell className="sticky left-10 bg-background z-10 font-medium text-sm">
                        {fullName}
                      </TableCell>
                      <TableCell className="text-sm">{user.email ?? '-'}</TableCell>
                      <TableCell className="text-sm tabular-nums">{user.phone ?? '-'}</TableCell>
                      <TableCell className="text-sm">{user.brand_name ?? '-'}</TableCell>
                      <TableCell className="text-sm">{user.country?.name ?? '-'}</TableCell>
                      <TableCell className="text-sm">
                        <Badge variant="mono" appearance="outline" className="text-xs">
                          {user.account_type ?? '-'}
                        </Badge>
                      </TableCell>
                      <TableCell>
                        <Badge
                          variant={user.is_activated ? 'success' : 'warning'}
                          appearance="outline"
                          className="text-xs"
                        >
                          {user.is_activated ? 'Active' : 'Inactive'}
                        </Badge>
                      </TableCell>
                      <TableCell className="text-sm text-right tabular-nums font-medium">{user.credit ?? 0}</TableCell>
                      {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14].map((typeId) => {
                        const entry = getBalance(user.id, typeId);
                        const fallbackKeys: Record<number, string> = {
                          1: 'requests_balance', 2: 'search_balance', 3: 'social_listening_balance',
                          4: 'lookalike_balance', 5: 'mynetwork_balance', 6: 'campaign_balance',
                          7: 'competitor_analysis_balance', 8: 'phone_number_balance',
                          9: 'media_plan_balance', 10: 'media_plan_creators_balance',
                          11: 'whatsapp_message_balance', 12: 'collaboration_request_balance',
                          13: 'relationship_lists_limit', 14: 'influencers_per_list_limit',
                        };
                        const fallbackVal = ((user as Record<string, unknown>)[fallbackKeys[typeId]] as number) ?? 0;

                        if (entry) {
                          const added = entry.total_added ?? 0;
                          const current = entry.current_balance ?? 0;
                          return (
                            <TableCell key={typeId} className="text-sm text-right tabular-nums font-medium whitespace-nowrap">
                              <span className="text-muted-foreground">{Number(added).toLocaleString()}</span>
                              <span className="text-muted-foreground/60 mx-0.5">/</span>
                              <span className={current < added ? 'text-amber-600' : 'text-foreground'}>{Number(current).toLocaleString()}</span>
                            </TableCell>
                          );
                        }

                        return (
                          <TableCell key={typeId} className="text-sm text-right tabular-nums font-medium">
                            {Number(fallbackVal).toLocaleString()}
                          </TableCell>
                        );
                      })}
                      <TableCell className="text-sm text-right tabular-nums hidden">{user.total_used_amount ?? 0}</TableCell>
                      <TableCell>
                        {user.is_paid_subscription ? (
                          <Badge variant="success" appearance="outline" className="text-xs">
                            {user.paid_subscription ?? 'Yes'}
                          </Badge>
                        ) : (
                          <span className="text-xs text-muted-foreground">None</span>
                        )}
                      </TableCell>
                      <TableCell className="text-sm text-muted-foreground">{formatDate(user.subscription_start_date)}</TableCell>
                      <TableCell className="text-sm text-muted-foreground">{formatDate(user.subscription_end_date)}</TableCell>
                      <TableCell className="text-sm text-muted-foreground">{formatDate(user.created_at)}</TableCell>
                      <TableCell className="text-sm">{user.created_by?.name ?? '-'}</TableCell>
                      <TableCell className="sticky right-0 bg-background z-10 text-center">
                        <DropdownMenu>
                          <DropdownMenuTrigger asChild>
                            <Button variant="ghost" size="sm" className="size-8 p-0">
                              <RiMore2Line className="size-4" />
                            </Button>
                          </DropdownMenuTrigger>
                          <DropdownMenuContent align="end" className="w-44">
                            <DropdownMenuItem onClick={(e) => handleOpenEditBalanceDialog(e as unknown as React.MouseEvent, user)}>
                              <RiEditLine className="size-4 mr-2" />
                              Edit Balance
                            </DropdownMenuItem>
                            <DropdownMenuItem onClick={() => router.push(`/balance-logs/user/${user.id}?name=${encodeURIComponent(user.name || user.email || '')}`)}>
                              <RiHistoryLine className="size-4 mr-2" />
                              Balance Logs
                            </DropdownMenuItem>
                            <DropdownMenuSeparator />
                            <DropdownMenuItem
                              onClick={() => handleRowAction(user.id)}
                              disabled={archiveMutation.isPending || unarchiveMutation.isPending}
                            >
                              {isArchivedView ? (
                                <>
                                  <RiInboxUnarchiveLine className="size-4 mr-2 text-primary" />
                                  <span className="text-primary">Unarchive</span>
                                </>
                              ) : (
                                <>
                                  <RiArchiveLine className="size-4 mr-2 text-amber-600" />
                                  <span className="text-amber-600">Archive</span>
                                </>
                              )}
                            </DropdownMenuItem>
                            <DropdownMenuSeparator />
                            <DropdownMenuItem
                              onClick={() => handleToggleActivation(user)}
                              disabled={toggleActivation.isPending}
                            >
                              {user.is_activated ? (
                                <>
                                  <RiUserUnfollowLine className="size-4 mr-2 text-destructive" />
                                  <span className="text-destructive">Deactivate</span>
                                </>
                              ) : (
                                <>
                                  <RiUserFollowLine className="size-4 mr-2 text-green-600" />
                                  <span className="text-green-600">Activate</span>
                                </>
                              )}
                            </DropdownMenuItem>
                          </DropdownMenuContent>
                        </DropdownMenu>
                      </TableCell>
                    </TableRow>
                  );
                })
              ) : (
                <TableRow>
                  <TableCell colSpan={26} className="text-center py-12 text-muted-foreground">
                    {isPending ? (
                      <div className="flex items-center justify-center gap-2">
                        <Spinner className="size-4 animate-spin" />
                        Loading clients...
                      </div>
                    ) : (
                      <div>
                        <p className="font-medium">No clients found</p>
                        <p className="text-sm mt-1">Try adjusting your filters or add a new client.</p>
                      </div>
                    )}
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </CardContent>

        <CardFooter className="justify-between border-t py-3">
          <p className="text-sm text-muted-foreground">
            Page {currentPage} of {totalPages}
            {pagination?.total ? ` (${pagination.total} records)` : ''}
          </p>
          <PaginationComponent
            currentPage={currentPage}
            totalPages={totalPages}
            onPageChange={handlePageChange}
          />
        </CardFooter>
      </Card>

      <Dialog open={isEditBalanceDialogOpen} onOpenChange={setIsEditBalanceDialogOpen}>
        <DialogContent className="sm:max-w-lg">
          <DialogHeader>
            <DialogTitle>
              Manage Balance — {selectedUser ? `${selectedUser.first_name ?? ''} ${selectedUser.last_name ?? ''}`.trim() : ''}
            </DialogTitle>
            <p className="text-xs text-muted-foreground mt-1">Values are set as absolute amounts (not added to existing).</p>
          </DialogHeader>
          <div className="space-y-3 py-2 max-h-[60vh] overflow-y-auto">
            {BALANCE_FIELDS.map((field) => {
              const summaryEntry = selectedUser && field.typeId > 0
                ? balanceSummaries?.[selectedUser.id]?.[field.typeId]
                : undefined;
              const currentValue = summaryEntry
                ? String(summaryEntry.current_balance)
                : String((selectedUser as Record<string, unknown>)?.[field.key] ?? 0);
              const isChanged = editedFields.has(field.key);
              const lastAdd = summaryEntry?.last_addition;
              return (
                <div key={field.key} className="space-y-1">
                  <div className="flex items-center gap-3">
                    <Label className="w-48 shrink-0 text-sm font-medium">{field.label}</Label>
                    <div className="flex items-center gap-2 flex-1">
                      <span className="text-xs text-muted-foreground w-20 text-right tabular-nums">
                        Current: {Number(currentValue).toLocaleString()}
                      </span>
                      <Input
                        type="number"
                        min={0}
                        className={`flex-1 ${isChanged ? 'border-blue-500 ring-1 ring-blue-200' : ''}`}
                        value={balanceFormData[field.key as keyof typeof balanceFormData]}
                        onChange={(e) => handleBalanceFieldChange(field.key, e.target.value)}
                      />
                    </div>
                  </div>
                  {lastAdd && (
                    <div className="ml-[12.5rem] pl-[5.5rem] text-[11px] text-muted-foreground flex items-center gap-3">
                      <span>Last: +{Number(lastAdd.amount).toLocaleString()}</span>
                      <span>Used: {Number(summaryEntry?.total_used ?? 0).toLocaleString()}</span>
                      {lastAdd.date && (
                        <span>{new Date(lastAdd.date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}</span>
                      )}
                    </div>
                  )}
                </div>
              );
            })}
            <div className="border-t pt-3 mt-3">
              <div className="flex items-center gap-3">
                <Label className="w-48 shrink-0 text-sm font-medium">Subscription End Date</Label>
                <Input
                  type="date"
                  className="flex-1"
                  value={balanceFormData.end_date}
                  onChange={(e) => {
                    setBalanceFormData({ ...balanceFormData, end_date: e.target.value });
                    const originalEndDate = selectedUser?.subscription_end_date
                      ? new Date(selectedUser.subscription_end_date).toISOString().split('T')[0]
                      : '';
                    setEndDateChanged(e.target.value !== originalEndDate);
                  }}
                />
              </div>
            </div>
            <div className="border-t pt-3 mt-3">
              <Label className="text-sm font-medium">Notes (Optional)</Label>
              <Textarea
                placeholder="Add notes for this balance change..."
                value={balanceFormData.notes}
                onChange={(e) =>
                  setBalanceFormData({ ...balanceFormData, notes: e.target.value })
                }
                rows={2}
                className="mt-2"
              />
            </div>
          </div>
          <DialogFooter>
            <Button
              variant="outline"
              onClick={handleCloseEditBalanceDialog}
              disabled={isEditingBalance || isUpdatingUser}
            >
              Cancel
            </Button>
            <Button
              onClick={handleSubmitEditBalance}
              disabled={isEditingBalance || isUpdatingUser || (editedFields.size === 0 && !endDateChanged)}
            >
              {(isEditingBalance || isUpdatingUser) && <Spinner className="size-4 animate-spin mr-2" />}
              Save Changes {editedFields.size > 0 && `(${editedFields.size})`}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
};

export { UsersClientList };
