import { useState } from "react";
import {
  AlertCircle,
  Banknote,
  FileSignature,
  FileText,
  Train,
  UserCheck,
  Users,
} from "lucide-react";
import {
  Alert,
  Badge,
  Button,
  Container,
  Paper,
  Skeleton,
  Stack,
  Tabs,
} from "@mantine/core";
import { useQueryClient } from "@tanstack/react-query";

import { useAuth } from "@/auth/useAuth";
import { OverviewPageHeader } from "@/components/overview/OverviewPageHeader";
import { OverviewQuickLinks } from "@/components/overview/OverviewQuickLinks";
import { OverviewTabContent } from "@/components/overview/OverviewTabContent";
import "@/components/overview/overview.css";
import { QUERY_KEYS } from "@/constants/QUERY_KEYS";
import { useOverview } from "@/hooks/useOverview";
import { FREIGHT_PERMS, hasPermission } from "@/lib/permissions";
import type { OverviewRange, OverviewTabKey } from "@/types/overview";

const TAB_ITEMS: Array<{
  value: OverviewTabKey;
  label: string;
  icon: typeof FileText;
  kpiKey:
    | "bookings"
    | "contracts"
    | "billing"
    | "operations"
    | "customers"
    | "staff";
  metricKey: string;
  /** Any of these keys grants the tab. */
  permission: string[];
}> = [
  {
    value: "bookings",
    label: "Bookings",
    icon: FileText,
    kpiKey: "bookings",
    metricKey: "totalActive",
    permission: [FREIGHT_PERMS.bookings.view],
  },
  {
    value: "contracts",
    label: "Contracts",
    icon: FileSignature,
    kpiKey: "contracts",
    metricKey: "totalActive",
    permission: [FREIGHT_PERMS.contracts.view],
  },
  {
    value: "billing",
    label: "Billing",
    icon: Banknote,
    kpiKey: "billing",
    metricKey: "successfulPaymentsMtd",
    permission: [FREIGHT_PERMS.bookings.view, FREIGHT_PERMS.payments.view],
  },
  {
    value: "operations",
    label: "Operations",
    icon: Train,
    kpiKey: "operations",
    metricKey: "trainsActive",
    permission: [
      FREIGHT_PERMS.trainScheduling.view,
      FREIGHT_PERMS.warehouseInventory.view,
      FREIGHT_PERMS.firstMile.view,
      FREIGHT_PERMS.lastMile.view,
    ],
  },
  {
    value: "customers",
    label: "Customers",
    icon: Users,
    kpiKey: "customers",
    metricKey: "totalCustomers",
    permission: [FREIGHT_PERMS.customers.view],
  },
  {
    value: "staff",
    label: "Staff",
    icon: UserCheck,
    kpiKey: "staff",
    metricKey: "activeEmployees",
    permission: [
      FREIGHT_PERMS.admin,
      FREIGHT_PERMS.staff.roles.view,
      FREIGHT_PERMS.staff.employeeRegistration.view,
      FREIGHT_PERMS.staff.roleAssignment.view,
    ],
  },
];

function HeaderSkeleton() {
  return (
    <Stack gap="md">
      <Skeleton height={48} radius="md" />
      <Skeleton height={52} radius="lg" />
    </Stack>
  );
}

const OverviewPage = () => {
  const [range, setRange] = useState<OverviewRange>("30d");
  const [activeTab, setActiveTab] = useState<OverviewTabKey>("bookings");
  const queryClient = useQueryClient();
  const { user } = useAuth();
  const { data: summary, isLoading, isError, error, refetch, isFetching } = useOverview(range);

  // Permission-scoped view: only tabs the user may see; a restricted role
  // (e.g. operations) gets a summary 403 — that is not a connection problem.
  const visibleTabs = TAB_ITEMS.filter((tab) =>
    tab.permission.some((key) => hasPermission(user, key)),
  );
  const currentTab = visibleTabs.some((t) => t.value === activeTab)
    ? activeTab
    : visibleTabs[0]?.value;
  const accessDenied =
    (error as { response?: { status?: number } } | null)?.response?.status === 403;

  const handleRefresh = () => {
    void refetch();
    void queryClient.invalidateQueries({ queryKey: QUERY_KEYS.OVERVIEW.ROOT });
  };

  const getTabBadge = (tab: (typeof TAB_ITEMS)[number]) => {
    if (!summary?.kpis) return 0;
    const group = summary.kpis[tab.kpiKey] as unknown as Record<string, number>;
    return group[tab.metricKey] ?? 0;
  };

  return (
    <Container fluid px="md" py="md">
      <Stack gap="lg">
        {isLoading && !summary ? (
          <HeaderSkeleton />
        ) : (
          <OverviewPageHeader
            range={range}
            onRangeChange={setRange}
            generatedAt={summary?.generatedAt}
            onRefresh={handleRefresh}
            isRefreshing={isFetching && !isLoading}
          />
        )}

        {isError && !accessDenied && (
          <Alert
            icon={<AlertCircle size={16} />}
            color="red"
            title="Unable to load dashboard summary"
            variant="light"
          >
            <Stack gap="sm" align="flex-start">
              <span>Check your connection and try again.</span>
              <Button size="xs" variant="light" color="red" onClick={() => void refetch()}>
                Retry
              </Button>
            </Stack>
          </Alert>
        )}

        {visibleTabs.length > 0 && (
          <Tabs
            value={currentTab}
            onChange={(value) =>
              setActiveTab((value as OverviewTabKey) ?? visibleTabs[0].value)
            }
            variant="pills"
            color="edr-green"
            keepMounted={false}
            classNames={{ list: "ov-tablist", tab: "ov-tab" }}
          >
            <Tabs.List>
              {visibleTabs.map((tab) => {
                const Icon = tab.icon;
                const isActive = currentTab === tab.value;
                return (
                  <Tabs.Tab
                    key={tab.value}
                    value={tab.value}
                    leftSection={<Icon size={17} />}
                    rightSection={
                      summary ? (
                        <Badge
                          size="sm"
                          radius="sm"
                          variant={isActive ? "white" : "light"}
                          color={isActive ? "edr-green" : "gray"}
                        >
                          {getTabBadge(tab)}
                        </Badge>
                      ) : undefined
                    }
                  >
                    {tab.label}
                  </Tabs.Tab>
                );
              })}
            </Tabs.List>

            {visibleTabs.map((tab) => (
              <Tabs.Panel key={tab.value} value={tab.value} pt="lg">
                <OverviewTabContent tab={tab.value} range={range} />
              </Tabs.Panel>
            ))}
          </Tabs>
        )}

        <Paper p="lg" radius="lg" withBorder>
          <OverviewQuickLinks />
        </Paper>
      </Stack>
    </Container>
  );
};

export default OverviewPage;
