import { ChevronDown, Search } from 'lucide-react';

import { useRef, useState } from 'react';

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

import { AdminDataTable } from '@/Components/admin/AdminDataTable';
import PageHeader from '@/Components/layout/PageHeader';
import { Badge } from '@/Components/ui/badge';
import { Button } from '@/Components/ui/button';
import { Checkbox } from '@/Components/ui/checkbox';
import { ConfirmDialog } from '@/Components/ui/confirm-dialog';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/Components/ui/dropdown-menu';
import { ExportButton } from '@/Components/ui/export-button';
import { Input } from '@/Components/ui/input';
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 { ADMIN_FEATURE_REQUEST_STATUS_LABELS as STATUS_LABELS } from '@/lib/status';
import { PaginatedResponse } from '@/types';

interface FeedbackTagItem {
  id: number;
  name: string;
  color: string | null;
}

interface FeatureRequestItem {
  id: number;
  title: string;
  description: string | null;
  status: string;
  vote_count: number;
  votes_count: number;
  created_at: string;
  user: { id: number; name: string; email: string } | null;
  tags: FeedbackTagItem[];
}

interface StatusCounts {
  [key: string]: number;
}

interface Filters {
  status: string;
  search: string;
  sort: string;
  [key: string]: string | number | boolean | undefined;
}

interface Props {
  feature_requests: PaginatedResponse<FeatureRequestItem>;
  status_counts: StatusCounts;
  filters: Filters;
}

const ALL_STATUSES = ['open', 'planned', 'in_progress', 'shipped', 'declined'];

const DESTRUCTIVE_STATUSES = new Set(['declined', 'shipped']);

function statusVariant(status: string) {
  switch (status) {
    case 'shipped':
      return 'success';
    case 'in_progress':
      return 'warning';
    case 'planned':
      return 'secondary';
    case 'declined':
      return 'secondary';
    case 'open':
    default:
      return 'outline';
  }
}

export default function FeatureRequestsIndex({ feature_requests, status_counts, filters }: Props) {
  const searchInputRef = useRef<HTMLInputElement>(null);
  const [selectedIds, setSelectedIds] = useState<number[]>([]);
  const [bulkStatus, setBulkStatus] = useState('declined');
  const [bulkConfirmOpen, setBulkConfirmOpen] = useState(false);
  const [pendingStatusChange, setPendingStatusChange] = useState<{
    id: number;
    status: string;
  } | null>(null);

  function toggleSelect(id: number) {
    setSelectedIds((prev) =>
      prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id],
    );
  }

  function handleBulkUpdate() {
    router.post(
      route('admin.feature-requests.bulk-update-status'),
      { feature_request_ids: selectedIds, status: bulkStatus },
      { onSuccess: () => { setSelectedIds([]); setBulkConfirmOpen(false); } },
    );
  }

  const { search, setSearch, updateFilter, handlePage } = useAdminFilters({
    route: 'admin.feature-requests.index',
    filters,
  });
  const isNavigating = useNavigationState();

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

  function handleStatusFilter(status: string) {
    updateFilter({ status: status || undefined });
  }

  function handleUpdateStatus(featureRequestId: number, newStatus: string) {
    router.patch(
      route('admin.feature-requests.update-status', { featureRequest: featureRequestId }),
      { status: newStatus },
      { preserveState: true },
    );
  }

  function requestStatusChange(id: number, status: string) {
    if (DESTRUCTIVE_STATUSES.has(status)) {
      setPendingStatusChange({ id, status });
    } else {
      handleUpdateStatus(id, status);
    }
  }

  const items = feature_requests.data;

  return (
    <AdminLayout>
      <Head title="Feature Requests" />

      <div className="container py-6 space-y-6">
        <PageHeader
          title="Feature Requests"
          description="Manage and prioritize user feature requests"
        />

        {/* Filters */}
        <div className="flex flex-wrap items-center gap-3">
          <div className="relative">
            <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
            <Input
              ref={searchInputRef}
              placeholder="Search requests..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="pl-9 w-64"
            />
          </div>

          <Select
            value={filters.status || 'all'}
            onValueChange={(val) => handleStatusFilter(val === 'all' ? '' : val)}
          >
            <SelectTrigger className="w-[180px]">
              <SelectValue placeholder="All Statuses" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All Statuses</SelectItem>
              {ALL_STATUSES.map((status) => (
                <SelectItem key={status} value={status}>
                  {STATUS_LABELS[status]} ({status_counts[status] ?? 0})
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          <ExportButton
            href={route('admin.feature-requests.export')}
            params={Object.fromEntries(
              [['status', filters.status], ['search', filters.search]].filter(([, v]) => Boolean(v)) as [string, string][]
            )}
          />
        </div>

        {selectedIds.length > 0 && (
          <div className="flex items-center gap-3 p-3 rounded-lg border bg-muted/40">
            <span className="text-sm text-muted-foreground">{selectedIds.length} selected</span>
            <Select value={bulkStatus} onValueChange={setBulkStatus}>
              <SelectTrigger className="w-[160px] h-8">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {ALL_STATUSES.map((s) => (
                  <SelectItem key={s} value={s}>{STATUS_LABELS[s]}</SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Button size="sm" onClick={() => setBulkConfirmOpen(true)}>
              Update Status
            </Button>
            <Button size="sm" variant="ghost" onClick={() => setSelectedIds([])}>
              Clear
            </Button>
          </div>
        )}

        {/* Table */}
        <AdminDataTable
          isEmpty={items.length === 0}
          isNavigating={isNavigating}
          pagination={{
            current_page: feature_requests.current_page,
            last_page: feature_requests.last_page,
            from: feature_requests.from,
            to: feature_requests.to,
            total: feature_requests.total,
          }}
          onPage={handlePage}
          paginationLabel="requests"
          emptyTitle="No feature requests"
          emptyDescription="No feature requests match your filters."
        >
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-8" />
                <TableHead>Title</TableHead>
                <TableHead>Submitted By</TableHead>
                <TableHead className="text-center">Votes</TableHead>
                <TableHead>Tags</TableHead>
                <TableHead>Status</TableHead>
                <TableHead>Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {items.map((fr) => (
                <TableRow key={fr.id}>
                  <TableCell>
                    <Checkbox
                      checked={selectedIds.includes(fr.id)}
                      onCheckedChange={() => toggleSelect(fr.id)}
                      aria-label={`Select ${fr.title}`}
                    />
                  </TableCell>
                  <TableCell>
                    <div>
                      <p className="font-medium">{fr.title}</p>
                      {fr.description && (
                        <p className="text-xs text-muted-foreground line-clamp-2 mt-0.5">
                          {fr.description}
                        </p>
                      )}
                    </div>
                  </TableCell>
                  <TableCell className="text-sm text-muted-foreground">
                    {fr.user?.name ?? 'Unknown'}
                  </TableCell>
                  <TableCell className="text-center">
                    <Badge variant="secondary">{fr.vote_count}</Badge>
                  </TableCell>
                  <TableCell>
                    {fr.tags && fr.tags.length > 0 ? (
                      <div className="flex flex-wrap gap-1">
                        {fr.tags.map((tag) => (
                          <Badge
                            key={tag.id}
                            variant="outline"
                            className="text-xs"
                            style={tag.color ? { borderColor: tag.color, color: tag.color } : undefined}
                          >
                            {tag.name}
                          </Badge>
                        ))}
                      </div>
                    ) : (
                      <span className="text-muted-foreground text-xs">—</span>
                    )}
                  </TableCell>
                  <TableCell>
                    <Badge variant={statusVariant(fr.status)}>
                      {STATUS_LABELS[fr.status] ?? fr.status}
                    </Badge>
                  </TableCell>
                  <TableCell>
                    <DropdownMenu>
                      <DropdownMenuTrigger asChild>
                        <Button variant="ghost" size="sm">
                          Change Status <ChevronDown className="ml-1 h-3 w-3" />
                        </Button>
                      </DropdownMenuTrigger>
                      <DropdownMenuContent>
                        {ALL_STATUSES.filter((s) => s !== fr.status).map((status) => (
                          <DropdownMenuItem
                            key={status}
                            onClick={() => requestStatusChange(fr.id, status)}
                          >
                            {STATUS_LABELS[status]}
                          </DropdownMenuItem>
                        ))}
                      </DropdownMenuContent>
                    </DropdownMenu>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </AdminDataTable>
      </div>

      <ConfirmDialog
        open={pendingStatusChange !== null}
        onOpenChange={(open) => {
          if (!open) setPendingStatusChange(null);
        }}
        title={`Mark as ${pendingStatusChange?.status}?`}
        description={`Changing this request to "${pendingStatusChange?.status}" is a significant action. Continue?`}
        confirmLabel="Confirm"
        onConfirm={() => {
          if (pendingStatusChange) {
            handleUpdateStatus(pendingStatusChange.id, pendingStatusChange.status);
          }
          setPendingStatusChange(null);
        }}
      />
      <ConfirmDialog
        open={bulkConfirmOpen}
        onOpenChange={setBulkConfirmOpen}
        title="Bulk Update Status"
        description={`Update ${selectedIds.length} feature request(s) to "${STATUS_LABELS[bulkStatus] ?? bulkStatus}"?`}
        confirmLabel="Update"
        onConfirm={handleBulkUpdate}
      />
    </AdminLayout>
  );
}
