import { CheckCircle, Clock, Edit2, Plus, Search, Star, Trash2, Upload, XCircle } 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 TestimonialRow {
  id: number;
  name: string;
  role: string | null;
  company: string | null;
  quote: string;
  rating: number;
  source: string | null;
  featured: boolean;
  status: string;
  created_at: string;
}

interface Stats {
  total: number;
  featured: number;
  pending: number;
  avg_rating: number;
}

interface Props {
  testimonials: PaginatedResponse<TestimonialRow>;
  filters: {
    search?: string;
    source?: string;
    status?: string;
    featured_only?: string;
    sort?: string;
    dir?: string;
    per_page?: number;
  };
  stats: Stats;
  sources: string[];
}

function StarRating({ rating }: { rating: number }) {
  return (
    <div className="flex items-center gap-0.5" aria-label={`${rating} out of 5 stars`}>
      {[1, 2, 3, 4, 5].map((star) => (
        <Star
          key={star}
          className={`h-3.5 w-3.5 ${star <= rating ? 'fill-yellow-400 text-yellow-400' : 'text-muted-foreground/30'}`}
        />
      ))}
    </div>
  );
}

function StatusBadge({ status }: { status: string }) {
  if (status === 'approved') return (
    <Badge variant="default" className="bg-green-600 text-white dark:bg-green-700">
      <CheckCircle className="mr-1 h-3 w-3" aria-hidden="true" />
      Approved
    </Badge>
  );
  if (status === 'rejected') return (
    <Badge variant="destructive">
      <XCircle className="mr-1 h-3 w-3" aria-hidden="true" />
      Rejected
    </Badge>
  );
  return (
    <Badge variant="outline" className="border-yellow-500 text-yellow-600 dark:border-yellow-400 dark:text-yellow-400">
      <Clock className="mr-1 h-3 w-3" aria-hidden="true" />
      Pending
    </Badge>
  );
}

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.testimonials.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-lg">
        <DialogHeader>
          <DialogTitle>Import Testimonials</DialogTitle>
          <DialogDescription>
            Upload a CSV file to bulk-import testimonials.
          </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">
              name*, quote*, role, company, rating, source, featured
            </div>
            <p className="text-xs text-muted-foreground">
              * Required. <code>rating</code> defaults to 5 (1–5). <code>featured</code> accepts{' '}
              <code>true</code>, <code>1</code>, or <code>yes</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 AdminTestimonialsIndex({ testimonials, filters, stats, sources }: Props) {
  const searchInputRef = useRef<HTMLInputElement>(null);
  const { search, setSearch, updateFilter, handleSort, handlePage } = useAdminFilters({
    route: '/admin/testimonials',
    filters,
  });
  const isNavigating = useNavigationState();

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

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

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

      <PageHeader
        title="Testimonials"
        subtitle="Customer testimonials shown on the marketing site"
        actions={
          <div className="flex items-center gap-2">
            <ImportDialog />
            <ExportButton href={route('admin.testimonials.export')} params={exportParams} />
            <Button asChild size="sm">
              <Link href={route('admin.testimonials.create')}>
                <Plus className="mr-2 h-4 w-4" />
                Add Testimonial
              </Link>
            </Button>
          </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">Featured</div>
            <div className="text-2xl font-bold text-yellow-600">{stats.featured}</div>
          </div>
          <div className="rounded-lg border bg-card p-4 space-y-1">
            <div className="text-xs text-muted-foreground">Pending Review</div>
            <div className={`text-2xl font-bold ${stats.pending > 0 ? 'text-orange-600' : ''}`}>{stats.pending}</div>
          </div>
          <div className="rounded-lg border bg-card p-4 space-y-1">
            <div className="text-xs text-muted-foreground">Avg Rating</div>
            <div className="text-2xl font-bold">{stats.avg_rating}</div>
          </div>
        </div>

        {/* Filters */}
        <fieldset className="flex flex-col sm:flex-row gap-3 sm:items-center flex-wrap">
          <legend className="sr-only">Testimonial Filters</legend>
          <Input
            ref={searchInputRef}
            placeholder="Search by name, company or quote..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="max-w-sm"
            aria-label="Search testimonials"
          />
          <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="pending">Pending</SelectItem>
              <SelectItem value="approved">Approved</SelectItem>
              <SelectItem value="rejected">Rejected</SelectItem>
            </SelectContent>
          </Select>
          {sources.length > 0 && (
            <Select
              value={filters.source ?? 'all'}
              onValueChange={(v) => updateFilter({ source: v === 'all' ? undefined : v })}
            >
              <SelectTrigger className="w-[160px]" aria-label="Filter by source">
                <SelectValue placeholder="All Sources" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">All Sources</SelectItem>
                {sources.map((s) => (
                  <SelectItem key={s} value={s}>{s}</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 testimonials table">
          <AdminDataTable
            isEmpty={testimonials.data.length === 0}
            isNavigating={isNavigating}
            isLoading={isNavigating}
            pagination={testimonials}
            onPage={handlePage}
            paginationLabel="testimonials"
            emptyIcon={Search}
            emptyTitle="No testimonials found"
            emptyDescription="Testimonials will appear here once added or submitted via the NPS flow."
          >
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>ID</TableHead>
                  <SortHeader column="name" label="Name" currentSort={filters.sort} currentDir={filters.dir} onSort={handleSort} />
                  <TableHead>Role / Company</TableHead>
                  <TableHead className="max-w-xs">Quote</TableHead>
                  <SortHeader column="rating" label="Rating" currentSort={filters.sort} currentDir={filters.dir} onSort={handleSort} />
                  <SortHeader column="source" label="Source" currentSort={filters.sort} currentDir={filters.dir} onSort={handleSort} />
                  <TableHead>Status</TableHead>
                  <TableHead>Featured</TableHead>
                  <SortHeader column="created_at" label="Added" currentSort={filters.sort} currentDir={filters.dir} onSort={handleSort} />
                  <TableHead className="w-[130px]">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {testimonials.data.map((t) => (
                  <TableRow key={t.id}>
                    <TableCell className="font-mono text-xs text-muted-foreground">#{t.id}</TableCell>
                    <TableCell className="font-medium text-sm">{t.name}</TableCell>
                    <TableCell className="text-sm text-muted-foreground">
                      {t.role && <div>{t.role}</div>}
                      {t.company && <div className="text-xs">{t.company}</div>}
                      {!t.role && !t.company && <span className="text-xs">—</span>}
                    </TableCell>
                    <TableCell className="max-w-xs">
                      <span className="text-sm text-muted-foreground line-clamp-2">{t.quote}</span>
                    </TableCell>
                    <TableCell>
                      <StarRating rating={t.rating} />
                    </TableCell>
                    <TableCell>
                      {t.source ? (
                        <Badge variant="outline">{t.source}</Badge>
                      ) : (
                        <span className="text-xs text-muted-foreground">—</span>
                      )}
                    </TableCell>
                    <TableCell>
                      <StatusBadge status={t.status} />
                    </TableCell>
                    <TableCell>
                      {t.featured ? (
                        <Badge variant="default">Featured</Badge>
                      ) : (
                        <span className="text-xs text-muted-foreground">—</span>
                      )}
                    </TableCell>
                    <TableCell className="text-sm text-muted-foreground whitespace-nowrap">
                      {t.created_at ? formatRelativeTime(t.created_at) : '—'}
                    </TableCell>
                    <TableCell>
                      <div className="flex items-center gap-1">
                        {t.status === 'pending' && (
                          <>
                            <Button
                              variant="ghost"
                              size="icon"
                              className="h-7 w-7 text-green-600 hover:text-green-700"
                              aria-label={`Approve testimonial from ${t.name}`}
                              onClick={() => router.post(route('admin.testimonials.approve', t.id))}
                            >
                              <CheckCircle className="h-3.5 w-3.5" />
                            </Button>
                            <Button
                              variant="ghost"
                              size="icon"
                              className="h-7 w-7 text-destructive hover:text-destructive"
                              aria-label={`Reject testimonial from ${t.name}`}
                              onClick={() => router.post(route('admin.testimonials.reject', t.id))}
                            >
                              <XCircle className="h-3.5 w-3.5" />
                            </Button>
                          </>
                        )}
                        <Button variant="ghost" size="icon" className="h-7 w-7" asChild>
                          <Link href={route('admin.testimonials.edit', t.id)} aria-label={`Edit testimonial from ${t.name}`}>
                            <Edit2 className="h-3.5 w-3.5" />
                          </Link>
                        </Button>
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-7 w-7 text-destructive hover:text-destructive"
                          aria-label={`Delete testimonial from ${t.name}`}
                          onClick={() => {
                            if (confirm(`Delete testimonial from "${t.name}"?`)) {
                              router.delete(route('admin.testimonials.destroy', t.id));
                            }
                          }}
                        >
                          <Trash2 className="h-3.5 w-3.5" />
                        </Button>
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </AdminDataTable>
        </ChartErrorBoundary>
      </div>
    </AdminLayout>
  );
}
