import { Search, Upload, UserMinus } from 'lucide-react';

import { useRef, useState } from 'react';

import { Head, Link, router, useForm } from '@inertiajs/react';

import { AdminDataTable } from '@/Components/admin/AdminDataTable';
import { ChartErrorBoundary } from '@/Components/admin/ChartErrorBoundary';
import { PerPageSelector } from '@/Components/admin/PerPageSelector';
import { SortHeader } from '@/Components/admin/SortHeader';
import PageHeader from '@/Components/layout/PageHeader';
import { Badge } from '@/Components/ui/badge';
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from '@/Components/ui/breadcrumb';
import { Button } from '@/Components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/Components/ui/dialog';
import { ExportButton } from '@/Components/ui/export-button';
import { Input } from '@/Components/ui/input';
import { LoadingButton } from '@/Components/ui/loading-button';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/Components/ui/select';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/Components/ui/table';
import { useAdminFilters } from '@/hooks/useAdminFilters';
import { useAdminKeyboardShortcuts } from '@/hooks/useAdminKeyboardShortcuts';
import { useNavigationState } from '@/hooks/useNavigationState';
import AdminLayout from '@/Layouts/AdminLayout';
import { formatRelativeTime } from '@/lib/format';
import type { PaginatedResponse } from '@/types';

interface SubscriberRow {
  id: number;
  email: string;
  name: string | null;
  status: string;
  verified_at: string | null;
  created_at: string;
}

interface Stats {
  total: number;
  verified: number;
  unverified: number;
  unsubscribed: number;
}

interface Props {
  subscribers: PaginatedResponse<SubscriberRow>;
  filters: {
    search?: string;
    status?: string;
    sort?: string;
    dir?: string;
    per_page?: number;
  };
  stats: Stats;
}

function statusBadgeVariant(status: string): 'default' | 'secondary' | 'destructive' | 'outline' {
  if (status === 'verified') return 'default';
  if (status === 'unsubscribed') return 'destructive';
  return 'secondary';
}

function ImportDialog() {
  const [open, setOpen] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const { data, setData, post, processing, errors, reset } = useForm<{ csv_file: File | null }>({
    csv_file: null,
  });

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    post(route('admin.subscribers.import'), {
      forceFormData: true,
      onSuccess: () => {
        setOpen(false);
        reset();
        if (fileInputRef.current) fileInputRef.current.value = '';
      },
    });
  }

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button variant="outline" size="sm">
          <Upload className="mr-2 h-4 w-4" />
          Import CSV
        </Button>
      </DialogTrigger>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>Import Subscribers</DialogTitle>
          <DialogDescription>
            Upload a CSV file to bulk-import subscribers. Duplicate emails are skipped automatically.
          </DialogDescription>
        </DialogHeader>
        <form onSubmit={handleSubmit} className="space-y-4">
          <div className="space-y-2">
            <p className="text-sm font-medium">Expected CSV columns (in order):</p>
            <div className="rounded-md border bg-muted/50 p-3 font-mono text-xs text-muted-foreground">
              email*, name, status
            </div>
            <p className="text-xs text-muted-foreground">
              * Required. Status defaults to <code>verified</code> if omitted. Accepted values:{' '}
              <code>verified</code>, <code>unverified</code>, <code>unsubscribed</code>.
            </p>
          </div>
          <div className="space-y-1">
            <input
              ref={fileInputRef}
              type="file"
              accept=".csv,.txt"
              className="block w-full text-sm text-foreground file:mr-3 file:rounded file:border file:border-border file:bg-background file:px-3 file:py-1.5 file:text-sm file:font-medium hover:file:bg-muted"
              aria-label="CSV file"
              onChange={(e) => setData('csv_file', e.target.files?.[0] ?? null)}
            />
            {errors.csv_file && (
              <p className="text-xs text-destructive">{errors.csv_file}</p>
            )}
          </div>
          <DialogFooter>
            <Button type="button" variant="ghost" onClick={() => setOpen(false)}>
              Cancel
            </Button>
            <LoadingButton type="submit" loading={processing} disabled={!data.csv_file}>
              Import
            </LoadingButton>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

export default function AdminSubscribersIndex({ subscribers, filters, stats }: Props) {
  const searchInputRef = useRef<HTMLInputElement>(null);
  const { search, setSearch, updateFilter, handleSort, handlePage } = useAdminFilters({
    route: '/admin/subscribers',
    filters,
  });
  const isNavigating = useNavigationState();

  function handleUnsubscribe(subscriber: SubscriberRow) {
    if (!confirm(`Unsubscribe ${subscriber.email}?`)) return;
    router.delete(route('admin.subscribers.destroy', { subscriber: subscriber.id }));
  }

  const exportParams: Record<string, string> = {};
  if (filters.search) exportParams.search = filters.search;
  if (filters.status) exportParams.status = filters.status;

  useAdminKeyboardShortcuts({
    onSearch: () => searchInputRef.current?.focus(),
    onNextPage: subscribers.current_page < subscribers.last_page ? () => handlePage(subscribers.current_page + 1) : undefined,
    onPrevPage: subscribers.current_page > 1 ? () => handlePage(subscribers.current_page - 1) : undefined,
  });

  return (
    <AdminLayout>
      <Head title="Admin - Subscribers" />
      <div className="container pt-6">
        <Breadcrumb>
          <BreadcrumbList>
            <BreadcrumbItem>
              <BreadcrumbLink asChild>
                <Link href="/admin">Admin</Link>
              </BreadcrumbLink>
            </BreadcrumbItem>
            <BreadcrumbSeparator />
            <BreadcrumbItem>
              <BreadcrumbPage>Subscribers</BreadcrumbPage>
            </BreadcrumbItem>
          </BreadcrumbList>
        </Breadcrumb>
      </div>

      <PageHeader
        title="Subscribers"
        subtitle="Email subscribers and their verification status"
        actions={
          <div className="flex items-center gap-2">
            <ImportDialog />
            <ExportButton href={route('admin.subscribers.export')} params={exportParams} />
          </div>
        }
      />

      <div className="container py-8 space-y-6">
        {/* Stats */}
        <div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
          <div className="rounded-lg border bg-card p-4 space-y-1">
            <div className="text-xs text-muted-foreground">Total</div>
            <div className="text-2xl font-bold">{stats.total}</div>
          </div>
          <div className="rounded-lg border bg-card p-4 space-y-1">
            <div className="text-xs text-muted-foreground">Verified</div>
            <div className="text-2xl font-bold text-green-600 dark:text-green-400">{stats.verified}</div>
          </div>
          <div className="rounded-lg border bg-card p-4 space-y-1">
            <div className="text-xs text-muted-foreground">Unverified</div>
            <div className="text-2xl font-bold text-yellow-600 dark:text-yellow-400">{stats.unverified}</div>
          </div>
          <div className="rounded-lg border bg-card p-4 space-y-1">
            <div className="text-xs text-muted-foreground">Unsubscribed</div>
            <div className="text-2xl font-bold text-red-600 dark:text-red-400">{stats.unsubscribed}</div>
          </div>
        </div>

        {/* Filters */}
        <fieldset className="flex flex-col sm:flex-row gap-3 sm:items-center flex-wrap">
          <legend className="sr-only">Subscriber Filters</legend>
          <Input
            ref={searchInputRef}
            placeholder="Search by email or name..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="max-w-sm"
            aria-label="Search subscribers"
          />
          <Select
            value={filters.status ?? 'all'}
            onValueChange={(v) => updateFilter({ status: v === 'all' ? undefined : v })}
          >
            <SelectTrigger className="w-[160px]" aria-label="Filter by status">
              <SelectValue placeholder="All Statuses" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All Statuses</SelectItem>
              <SelectItem value="verified">Verified</SelectItem>
              <SelectItem value="unverified">Unverified</SelectItem>
              <SelectItem value="unsubscribed">Unsubscribed</SelectItem>
            </SelectContent>
          </Select>
          <div className="sm:ml-auto">
            <PerPageSelector
              value={filters.per_page ?? 50}
              onChange={(perPage) => updateFilter({ per_page: perPage })}
            />
          </div>
        </fieldset>

        <ChartErrorBoundary label="Unable to load subscribers table">
          <AdminDataTable
            isEmpty={subscribers.data.length === 0}
            isNavigating={isNavigating}
            isLoading={isNavigating}
            pagination={subscribers}
            onPage={handlePage}
            paginationLabel="subscribers"
            emptyIcon={Search}
            emptyTitle="No subscribers found"
            emptyDescription="Subscribers will appear here once users sign up or you import them via CSV."
          >
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>ID</TableHead>
                  <SortHeader column="email" label="Email" currentSort={filters.sort} currentDir={filters.dir} onSort={handleSort} />
                  <SortHeader column="name" label="Name" currentSort={filters.sort} currentDir={filters.dir} onSort={handleSort} />
                  <SortHeader column="status" label="Status" currentSort={filters.sort} currentDir={filters.dir} onSort={handleSort} />
                  <SortHeader column="created_at" label="Subscribed" currentSort={filters.sort} currentDir={filters.dir} onSort={handleSort} />
                  <TableHead className="w-20">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {subscribers.data.map((subscriber) => (
                  <TableRow key={subscriber.id}>
                    <TableCell className="font-mono text-xs text-muted-foreground">#{subscriber.id}</TableCell>
                    <TableCell className="font-medium text-sm">{subscriber.email}</TableCell>
                    <TableCell className="text-sm text-muted-foreground">
                      {subscriber.name ?? <span className="text-xs">—</span>}
                    </TableCell>
                    <TableCell>
                      <Badge variant={statusBadgeVariant(subscriber.status)}>
                        {subscriber.status}
                      </Badge>
                    </TableCell>
                    <TableCell className="text-sm text-muted-foreground whitespace-nowrap">
                      {subscriber.created_at ? formatRelativeTime(subscriber.created_at) : '—'}
                    </TableCell>
                    <TableCell>
                      {subscriber.status !== 'unsubscribed' && (
                        <Button
                          variant="ghost"
                          size="sm"
                          className="h-7 px-2 text-xs text-muted-foreground hover:text-destructive"
                          onClick={() => handleUnsubscribe(subscriber)}
                          aria-label={`Unsubscribe ${subscriber.email}`}
                        >
                          <UserMinus className="h-3.5 w-3.5" />
                        </Button>
                      )}
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </AdminDataTable>
        </ChartErrorBoundary>
      </div>
    </AdminLayout>
  );
}
