import { Flag } from 'lucide-react';
import { toast } from 'sonner';

import { useRef, useState } from 'react';

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

import { AdminDataTable } from '@/Components/admin/AdminDataTable';
import AdminPage from '@/Components/admin/AdminPage';
import { PerPageSelector } from '@/Components/admin/PerPageSelector';
import { SortHeader } from '@/Components/admin/SortHeader';
import { Badge } from '@/Components/ui/badge';
import { Button } from '@/Components/ui/button';
import { ConfirmDialog } from '@/Components/ui/confirm-dialog';
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 { useMutationButton } from '@/hooks/useMutationButton';
import { useNavigationState } from '@/hooks/useNavigationState';
import AdminLayout from '@/Layouts/AdminLayout';
import { formatRelativeTime } from '@/lib/format';
import type { AdminFeatureFlagOverridesIndexProps } from '@/types/admin';

/** Per-row revoke button: useMutationButton powers the delete request.
 *  A ConfirmDialog wraps the action; the Promise resolves/rejects via refs
 *  so the dialog stays open when the delete fails (reject-on-error pattern).
 */
function RevokeButton({ overrideId }: { overrideId: number }) {
  const [open, setOpen] = useState(false);
  const resolveRef = useRef<(() => void) | null>(null);
  const rejectRef = useRef<(() => void) | null>(null);

  const { processing, onClick: triggerRevoke } = useMutationButton(
    (opts) => router.delete(route('admin.feature-flag-overrides.destroy', overrideId), {
      ...opts,
      onSuccess: () => {
        toast.success('Override revoked.');
        setOpen(false);
        resolveRef.current?.();
        opts.onFinish?.();
      },
      onError: (errors) => {
        toast.error("Couldn't revoke that override. Retry.");
        rejectRef.current?.();
        opts.onError?.(errors);
      },
    }),
  );

  const handleRevoke = (): Promise<void> =>
    new Promise<void>((resolve, reject) => {
      resolveRef.current = resolve;
      rejectRef.current = reject;
      triggerRevoke();
    });

  return (
    <>
      <Button
        variant="ghost"
        size="sm"
        className="text-destructive hover:text-destructive"
        onClick={() => setOpen(true)}
        disabled={processing}
      >
        Revoke
      </Button>
      <ConfirmDialog
        open={open}
        onOpenChange={setOpen}
        onConfirm={handleRevoke}
        title="Revoke Override"
        description="This will permanently remove this feature flag override. The flag will revert to its default or global value."
        variant="destructive"
        confirmLabel="Revoke"
      />
    </>
  );
}

export default function FeatureFlagOverrides({
  overrides,
  filters,
  known_flags,
}: AdminFeatureFlagOverridesIndexProps) {
  const { updateFilter, handleSort, handlePage, clearFilters } = useAdminFilters({
    route: '/admin/feature-flag-overrides',
    filters,
  });
  const isNavigating = useNavigationState();

  const hasFilters = !!(filters.flag || filters.user_only);

  return (
    <AdminLayout>
      <AdminPage
        title="Feature Flag Overrides"
        subtitle="All active global and user overrides"
        breadcrumbs={[
          { label: 'Admin', href: '/admin' },
          { label: 'Feature Flags', href: '/admin/feature-flags' },
          { label: 'Overrides' },
        ]}
      >
        <fieldset className="flex flex-col sm:flex-row gap-3">
          <legend className="sr-only">Override Filters</legend>
          <Select
            value={filters.flag ?? 'all'}
            onValueChange={(value) => updateFilter({ flag: value === 'all' ? undefined : value })}
          >
            <SelectTrigger className="w-[220px]" aria-label="Filter by flag">
              <SelectValue placeholder="Flag: All" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">Flag: All</SelectItem>
              {known_flags.map((f) => (
                <SelectItem key={f} value={f}>
                  {f}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Select
            value={filters.user_only ? 'user' : 'all'}
            onValueChange={(value) =>
              updateFilter({ user_only: value === 'user' ? true : undefined })
            }
          >
            <SelectTrigger className="w-[160px]" aria-label="Filter by type">
              <SelectValue placeholder="Type: All" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">Type: All</SelectItem>
              <SelectItem value="user">User only</SelectItem>
            </SelectContent>
          </Select>
          {hasFilters && (
            <Button variant="ghost" size="sm" onClick={clearFilters}>
              Clear filters
            </Button>
          )}
          <div className="sm:ml-auto">
            <PerPageSelector
              value={filters.per_page ?? 25}
              onChange={(perPage) => updateFilter({ per_page: perPage })}
            />
          </div>
        </fieldset>

        <AdminDataTable
          isEmpty={overrides.data.length === 0}
          isNavigating={isNavigating}
          pagination={overrides}
          onPage={handlePage}
          paginationLabel="overrides"
          emptyIcon={Flag}
          emptyTitle="No overrides found"
          emptyDescription={
            hasFilters ? 'No overrides match your filters.' : 'No feature flag overrides active.'
          }
          emptyAction={
            hasFilters ? (
              <Button variant="outline" size="sm" onClick={clearFilters}>
                Clear filters
              </Button>
            ) : undefined
          }
        >
          <Table>
            <TableHeader>
              <TableRow>
                <SortHeader
                  column="flag"
                  label="Flag"
                  currentSort={filters.sort}
                  currentDir={filters.dir}
                  onSort={handleSort}
                />
                <TableHead>Enabled</TableHead>
                <TableHead>Scope</TableHead>
                <TableHead>Reason</TableHead>
                <TableHead>Changed By</TableHead>
                <SortHeader
                  column="created_at"
                  label="Created"
                  currentSort={filters.sort}
                  currentDir={filters.dir}
                  onSort={handleSort}
                />
                <TableHead className="w-[80px]" />
              </TableRow>
            </TableHeader>
            <TableBody>
              {overrides.data.map((o) => (
                <TableRow key={o.id}>
                  <TableCell className="font-mono text-sm">{o.flag}</TableCell>
                  <TableCell>
                    <Badge variant={o.enabled ? 'success' : 'destructive'}>
                      {o.enabled ? 'On' : 'Off'}
                    </Badge>
                  </TableCell>
                  <TableCell className="text-sm">
                    {o.user_id ? (
                      <Link href={`/admin/users/${o.user_id}`} className="hover:underline">
                        {o.user_name ?? `User #${o.user_id}`}
                      </Link>
                    ) : (
                      <Badge variant="outline">Global</Badge>
                    )}
                  </TableCell>
                  <TableCell className="text-sm text-muted-foreground max-w-xs truncate">
                    {o.reason ?? '—'}
                  </TableCell>
                  <TableCell className="text-sm text-muted-foreground">
                    {o.changed_by_name ?? '—'}
                  </TableCell>
                  <TableCell className="text-sm text-muted-foreground">
                    {formatRelativeTime(o.created_at)}
                  </TableCell>
                  <TableCell>
                    <RevokeButton overrideId={o.id} />
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </AdminDataTable>
      </AdminPage>
    </AdminLayout>
  );
}
