import {
  AlertTriangle,
  ChevronDown,
  ChevronRight,
  Flag,
  Lock,
  RefreshCw,
  Users,
} from 'lucide-react';
import { toast } from 'sonner';

import { Fragment, useState } from 'react';

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

import { AdminDataTable } from '@/Components/admin/AdminDataTable';
import { SortHeader } from '@/Components/admin/SortHeader';
import UserOverridesSection from '@/Components/admin/UserOverridesSection';
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 { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/Components/ui/card';
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 { Switch } from '@/Components/ui/switch';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/Components/ui/table';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/Components/ui/tooltip';
import { useAdminFilters } from '@/hooks/useAdminFilters';
import { useAdminKeyboardShortcuts } from '@/hooks/useAdminKeyboardShortcuts';
import { useNavigationState } from '@/hooks/useNavigationState';
import AdminLayout from '@/Layouts/AdminLayout';
import { couldnt } from '@/lib/messages';
import type { PageProps } from '@/types';
import type {
  AdminFeatureFlagsIndexProps,
  FeatureFlagAdmin,
  FeatureFlagUserOverride,
} from '@/types/admin';

export default function FeatureFlagsIndex({ flags, filters }: AdminFeatureFlagsIndexProps) {
  const { auth } = usePage<PageProps>().props;
  const canMutate = auth.user?.admin_role != null && auth.user.admin_role !== 'viewer';
  const [expandedFlag, setExpandedFlag] = useState<string | null>(null);
  const [userOverrides, setUserOverrides] = useState<Record<string, FeatureFlagUserOverride[]>>({});
  const [loadingUsers, setLoadingUsers] = useState<string | null>(null);
  const [confirmDialog, setConfirmDialog] = useState<{
    open: boolean;
    title: string;
    description: string;
    onConfirm: () => Promise<void>;
    variant?: 'default' | 'destructive';
  }>({ open: false, title: '', description: '', onConfirm: async () => {} });

  useAdminKeyboardShortcuts({});
  const isNavigating = useNavigationState();

  const { handleSort } = useAdminFilters({
    route: '/admin/feature-flags',
    filters: filters ?? {},
  });

  const handleToggleGlobal = async (flag: FeatureFlagAdmin, newValue: boolean) => {
    return new Promise<void>((resolve, reject) => {
      router.patch(
        `/admin/feature-flags/${flag.flag}`,
        { enabled: newValue },
        {
          preserveState: true,
          onSuccess: () => {
            toast.success(`${flag.flag} is now ${newValue ? 'enabled' : 'disabled'} globally.`);
            resolve();
          },
          onError: (errors) => {
            toast.error((Object.values(errors)[0] as string) || couldnt('update', 'feature flag'));
            reject(new Error('Failed to update'));
          },
        },
      );
    });
  };

  const handleResetToDefault = async (flag: FeatureFlagAdmin) => {
    return new Promise<void>((resolve, reject) => {
      router.delete(`/admin/feature-flags/${flag.flag}`, {
        preserveState: true,
        onSuccess: () => {
          toast.success(`${flag.flag} reset to environment default.`);
          resolve();
        },
        onError: () => {
          toast.error(couldnt('reset', 'feature flag'));
          reject(new Error('Failed to reset'));
        },
      });
    });
  };

  const loadUserOverrides = async (flag: string) => {
    setLoadingUsers(flag);
    try {
      const response = await fetch(`/admin/feature-flags/${flag}/users`);
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      const data = await response.json();
      setUserOverrides((prev) => ({ ...prev, [flag]: data }));
    } catch {
      toast.error(couldnt('load', 'user overrides'));
    } finally {
      setLoadingUsers(null);
    }
  };

  const handleExpandFlag = (flag: string) => {
    if (expandedFlag === flag) {
      setExpandedFlag(null);
    } else {
      setExpandedFlag(flag);
      if (!userOverrides[flag]) {
        loadUserOverrides(flag);
      }
    }
  };

  const handleAddUserOverride = async (flag: string, userId: number, enabled: boolean) => {
    return new Promise<void>((resolve, reject) => {
      router.post(
        `/admin/feature-flags/${flag}/users`,
        { user_id: userId, enabled },
        {
          preserveState: true,
          onSuccess: () => {
            toast.success('User override added.');
            loadUserOverrides(flag);
            resolve();
          },
          onError: () => {
            toast.error(couldnt('add', 'user override'));
            reject(new Error('Failed to add'));
          },
        },
      );
    });
  };

  const handleRemoveUserOverride = async (flag: string, userId: number) => {
    return new Promise<void>((resolve, reject) => {
      router.delete(`/admin/feature-flags/${flag}/users/${userId}`, {
        preserveState: true,
        onSuccess: () => {
          toast.success('User override removed.');
          loadUserOverrides(flag);
          resolve();
        },
        onError: () => {
          toast.error(couldnt('remove', 'user override'));
          reject(new Error('Failed to remove'));
        },
      });
    });
  };

  const handleRemoveAllUserOverrides = async (flag: string) => {
    return new Promise<void>((resolve, reject) => {
      router.delete(`/admin/feature-flags/${flag}/users`, {
        preserveState: true,
        onSuccess: () => {
          toast.success('All user overrides removed.');
          loadUserOverrides(flag);
          resolve();
        },
        onError: () => {
          toast.error(couldnt('remove', 'user overrides'));
          reject(new Error('Failed to remove'));
        },
      });
    });
  };

  const openConfirmDialog = (config: Omit<typeof confirmDialog, 'open'>) => {
    setConfirmDialog({ ...config, open: true });
  };

  return (
    <AdminLayout>
      <Head title="Admin - Feature Flags" />

      <div className="container py-6 space-y-6">
        <Breadcrumb>
          <BreadcrumbList>
            <BreadcrumbItem>
              <BreadcrumbLink asChild>
                <Link href="/admin">Admin</Link>
              </BreadcrumbLink>
            </BreadcrumbItem>
            <BreadcrumbSeparator />
            <BreadcrumbItem>
              <BreadcrumbPage>Feature Flags</BreadcrumbPage>
            </BreadcrumbItem>
          </BreadcrumbList>
        </Breadcrumb>

        <PageHeader
          title="Feature Flags"
          subtitle="Manage feature toggles and per-user targeting"
          actions={<ExportButton href={route('admin.feature-flags.export')} />}
        />

        <div className="rounded-lg border border-border bg-muted/30 p-4 text-sm text-muted-foreground">
          <p className="font-medium text-foreground">How feature flags resolve</p>
          <p className="mt-1">
            Feature flags resolve in order: <strong>User override</strong> &rarr;{' '}
            <strong>Global override</strong> &rarr; <strong>Environment config</strong>.
            Config-based flags (set via{' '}
            <code className="rounded bg-muted px-1 py-0.5 text-xs">FEATURE_*</code> env vars)
            require a deployment to change. Global overrides (set below) take effect immediately via
            cache.
          </p>
        </div>

        <Card>
          <CardHeader>
            <CardTitle>Feature Flags</CardTitle>
            <CardDescription>
              Override feature flags globally or target specific users. Protected flags cannot be
              modified.
            </CardDescription>
          </CardHeader>
          <CardContent>
            <AdminDataTable
              isEmpty={flags.length === 0}
              isNavigating={isNavigating}
              emptyIcon={Flag}
              emptyTitle="No feature flags found"
              emptyDescription="No feature flags are registered in this application."
            >
              <div className="overflow-x-auto">
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead className="w-8"></TableHead>
                      <SortHeader
                        column="key"
                        label="Flag"
                        currentSort={filters?.sort}
                        currentDir={filters?.dir}
                        onSort={handleSort}
                      />
                      <TableHead>Env Default</TableHead>
                      <TableHead>Global Override</TableHead>
                      <TableHead>Effective</TableHead>
                      <TableHead>User Overrides</TableHead>
                      <TableHead className="text-right">Actions</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {flags.map((flag) => (
                      <Fragment key={flag.flag}>
                        <TableRow>
                          <TableCell>
                            {flag.user_override_count > 0 ? (
                              <button
                                onClick={() => handleExpandFlag(flag.flag)}
                                aria-label={
                                  expandedFlag === flag.flag
                                    ? `Collapse user overrides for ${flag.flag}`
                                    : `Expand user overrides for ${flag.flag}`
                                }
                                aria-expanded={expandedFlag === flag.flag}
                                aria-controls={`overrides-${flag.flag}`}
                                className="p-1 hover:bg-muted rounded"
                              >
                                {expandedFlag === flag.flag ? (
                                  <ChevronDown className="h-4 w-4" />
                                ) : (
                                  <ChevronRight className="h-4 w-4" />
                                )}
                              </button>
                            ) : (
                              <button
                                onClick={() => handleExpandFlag(flag.flag)}
                                aria-label={`No user overrides available for ${flag.flag}`}
                                className="p-1 hover:bg-muted rounded opacity-50"
                              >
                                <ChevronRight className="h-4 w-4" />
                              </button>
                            )}
                          </TableCell>
                          <TableCell>
                            <div className="flex items-center gap-2">
                              <code className="font-mono text-sm">{flag.flag}</code>
                              {flag.is_protected && (
                                <Badge variant="outline" className="gap-1">
                                  <Lock className="h-3 w-3" />
                                  Protected
                                </Badge>
                              )}
                              {flag.is_route_dependent &&
                                !flag.env_default &&
                                flag.global_override === true && (
                                  <TooltipProvider>
                                    <Tooltip>
                                      <TooltipTrigger asChild>
                                        <Badge variant="destructive" className="gap-1 cursor-help">
                                          <AlertTriangle className="h-3 w-3" />
                                          Route unavailable
                                        </Badge>
                                      </TooltipTrigger>
                                      <TooltipContent side="bottom" className="max-w-xs">
                                        <p>The environment variable for this feature is not set.</p>
                                        <p className="mt-1">
                                          Enable it in your{' '}
                                          <code className="rounded bg-muted px-1 py-0.5 text-xs">
                                            .env
                                          </code>{' '}
                                          file and restart the server.
                                        </p>
                                      </TooltipContent>
                                    </Tooltip>
                                  </TooltipProvider>
                                )}
                            </div>
                          </TableCell>
                          <TableCell>
                            <Badge variant={flag.env_default ? 'success' : 'secondary'}>
                              {flag.env_default ? 'ON' : 'OFF'}
                            </Badge>
                          </TableCell>
                          <TableCell>
                            {flag.global_override === null ? (
                              <Badge variant="outline" className="text-muted-foreground">
                                —
                              </Badge>
                            ) : (
                              <Badge variant={flag.global_override ? 'success' : 'destructive'}>
                                {flag.global_override ? 'ON' : 'OFF'}
                              </Badge>
                            )}
                          </TableCell>
                          <TableCell>
                            <Badge variant={flag.effective ? 'success' : 'secondary'}>
                              {flag.effective ? 'ON' : 'OFF'}
                            </Badge>
                          </TableCell>
                          <TableCell>
                            {flag.user_override_count > 0 ? (
                              <button
                                onClick={() => handleExpandFlag(flag.flag)}
                                className="flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
                              >
                                <Users className="h-4 w-4" />
                                {flag.user_override_count} user
                                {flag.user_override_count !== 1 ? 's' : ''}
                              </button>
                            ) : (
                              <span className="text-sm text-muted-foreground">—</span>
                            )}
                          </TableCell>
                          <TableCell className="text-right">
                            <div className="flex items-center justify-end gap-2">
                              {canMutate && (
                                <Switch
                                  checked={flag.global_override ?? flag.env_default}
                                  disabled={flag.is_protected}
                                  onCheckedChange={(checked) => {
                                    openConfirmDialog({
                                      title: checked ? 'Enable feature' : 'Disable feature',
                                      description: `Are you sure you want to ${checked ? 'enable' : 'disable'} "${flag.flag}" globally?`,
                                      variant: 'default',
                                      onConfirm: () => handleToggleGlobal(flag, checked),
                                    });
                                  }}
                                />
                              )}
                              {canMutate && (
                                <DropdownMenu>
                                  <DropdownMenuTrigger asChild>
                                    <Button
                                      variant="ghost"
                                      size="sm"
                                      disabled={flag.is_protected}
                                      aria-label={`Options for ${flag.flag} feature flag`}
                                    >
                                      <ChevronDown className="h-4 w-4" />
                                    </Button>
                                  </DropdownMenuTrigger>
                                  <DropdownMenuContent align="end">
                                    <DropdownMenuItem
                                      onClick={() => {
                                        openConfirmDialog({
                                          title: 'Reset to default',
                                          description: `Reset "${flag.flag}" to its environment default value?`,
                                          variant: 'default',
                                          onConfirm: () => handleResetToDefault(flag),
                                        });
                                      }}
                                      disabled={flag.global_override === null}
                                    >
                                      <RefreshCw className="mr-2 h-4 w-4" />
                                      Reset to env default
                                    </DropdownMenuItem>
                                    <DropdownMenuItem onClick={() => handleExpandFlag(flag.flag)}>
                                      <Users className="mr-2 h-4 w-4" />
                                      Manage user targeting
                                    </DropdownMenuItem>
                                  </DropdownMenuContent>
                                </DropdownMenu>
                              )}
                            </div>
                          </TableCell>
                        </TableRow>
                        {expandedFlag === flag.flag && (
                          <TableRow
                            key={`${flag.flag}-expanded`}
                            id={`overrides-${flag.flag}`}
                            className="animate-in fade-in duration-200"
                          >
                            <TableCell colSpan={7} className="bg-muted/50 p-4">
                              <UserOverridesSection
                                flagKey={flag.flag}
                                isProtected={flag.is_protected || !canMutate}
                                overrides={userOverrides[flag.flag] ?? []}
                                isLoading={loadingUsers === flag.flag}
                                onAdd={(userId, enabled) =>
                                  handleAddUserOverride(flag.flag, userId, enabled)
                                }
                                onRemove={(userId) => handleRemoveUserOverride(flag.flag, userId)}
                                onRemoveAll={() => handleRemoveAllUserOverrides(flag.flag)}
                              />
                            </TableCell>
                          </TableRow>
                        )}
                      </Fragment>
                    ))}
                  </TableBody>
                </Table>
              </div>
            </AdminDataTable>
          </CardContent>
        </Card>
      </div>

      <ConfirmDialog
        open={confirmDialog.open}
        onOpenChange={(open) => setConfirmDialog((prev) => ({ ...prev, open }))}
        title={confirmDialog.title}
        description={confirmDialog.description}
        variant={confirmDialog.variant}
        onConfirm={confirmDialog.onConfirm}
      />
    </AdminLayout>
  );
}
