import { useMemo } from 'react';
import { ActionIcon, Badge, Card, Group, Loader, Menu, SimpleGrid, Stack, Table, Text, ThemeIcon } from '@mantine/core';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { AlertTriangle, Bell, BellOff, Check, Clock, DollarSign, MoreVertical } from 'lucide-react';

import { useAccrualDashboard } from '@/hooks/useWarehouses';
import { warehouseService } from '@/services/warehouse.service';
import { useToast } from '@/hooks/use-toast';
import type { AccrualAlert, AccrualDashboardRow } from '@/types/warehouse';

const ALERT_META: Record<AccrualAlert, { color: string; label: string }> = {
  CHARGING: { color: 'red', label: 'Charging' },
  WARNING: { color: 'orange', label: 'Free days ending' },
  OK: { color: 'teal', label: 'Within free days' },
};

function money(amount: number, currency: string): string {
  return `${amount.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} ${currency}`;
}

function freeDaysLabel(row: AccrualDashboardRow): string {
  if (row.charging) return 'charging now';
  if (row.freeDaysLeft == null) return '—';
  return `${row.freeDaysLeft} day${row.freeDaysLeft === 1 ? '' : 's'} left`;
}

/**
 * Live accrual dashboard: storage / demurrage ticking per in-warehouse item,
 * sorted so items already charging (or about to) surface first. Read-only.
 */
export function AccrualDashboard() {
  const { data: rows = [], isLoading } = useAccrualDashboard();
  const { toast } = useToast();
  const qc = useQueryClient();

  const refresh = () =>
    qc.invalidateQueries({ queryKey: ['warehouse-fees', 'accrual-dashboard'] });

  const ack = useMutation({
    mutationFn: ({ id, snoozeDays }: { id: string; snoozeDays?: number }) =>
      warehouseService.acknowledgeAccrual(id, snoozeDays ? { snoozeDays } : {}),
    onSuccess: (_r, v) => {
      toast({ title: v.snoozeDays ? `Snoozed ${v.snoozeDays} days` : 'Marked reviewed' });
      void refresh();
    },
    onError: () => toast({ variant: 'destructive', title: 'Could not acknowledge' }),
  });
  const unack = useMutation({
    mutationFn: (id: string) => warehouseService.unacknowledgeAccrual(id),
    onSuccess: () => {
      toast({ title: 'Acknowledgement removed' });
      void refresh();
    },
    onError: () => toast({ variant: 'destructive', title: 'Could not un-acknowledge' }),
  });

  const summary = useMemo(() => {
    const currency = rows[0]?.currency ?? 'USD';
    return {
      currency,
      charging: rows.filter((r) => r.alert === 'CHARGING').length,
      atRisk: rows.filter((r) => r.alert === 'WARNING').length,
      totalAccruing: Math.round(rows.reduce((s, r) => s + r.accruedAmount, 0) * 100) / 100,
    };
  }, [rows]);

  if (isLoading) {
    return (
      <Group justify="center" py="xl">
        <Loader />
      </Group>
    );
  }

  return (
    <Stack gap="md">
      <SimpleGrid cols={{ base: 1, xs: 3 }} spacing="sm">
        <StatCard
          icon={<DollarSign size={18} />}
          label="Accruing now"
          value={money(summary.totalAccruing, summary.currency)}
          color="edr-green"
        />
        <StatCard
          icon={<AlertTriangle size={18} />}
          label="Charging"
          value={summary.charging}
          color={summary.charging > 0 ? 'red' : 'gray'}
        />
        <StatCard
          icon={<Clock size={18} />}
          label="Free days ending (≤2d)"
          value={summary.atRisk}
          color={summary.atRisk > 0 ? 'orange' : 'gray'}
        />
      </SimpleGrid>

      <Card withBorder radius="md" padding={0}>
        {rows.length === 0 ? (
          <Text c="dimmed" ta="center" py="xl" size="sm">
            No in-warehouse items are accruing fees.
          </Text>
        ) : (
          <Table.ScrollContainer minWidth={900}>
            <Table verticalSpacing="sm" highlightOnHover striped>
              <Table.Thead>
                <Table.Tr>
                  <Table.Th>Booking</Table.Th>
                  <Table.Th>Customer</Table.Th>
                  <Table.Th>Location</Table.Th>
                  <Table.Th>Status</Table.Th>
                  <Table.Th ta="right">Accrued</Table.Th>
                  <Table.Th>Free days</Table.Th>
                  <Table.Th>Alert</Table.Th>
                  <Table.Th ta="right" />
                </Table.Tr>
              </Table.Thead>
              <Table.Tbody>
                {rows.map((row) => {
                  const meta = ALERT_META[row.alert];
                  const busy = ack.isPending || unack.isPending;
                  return (
                    <Table.Tr key={row.inventoryId} style={{ opacity: row.acknowledged ? 0.55 : 1 }}>
                      <Table.Td>
                        <Text fw={600} size="sm">
                          {row.bookingReference ?? row.inventoryId.slice(0, 8)}
                        </Text>
                      </Table.Td>
                      <Table.Td>{row.customerName ?? '—'}</Table.Td>
                      <Table.Td>
                        <Text size="sm">
                          {[row.warehouseCode, row.zoneCode].filter(Boolean).join(' · ') || '—'}
                        </Text>
                      </Table.Td>
                      <Table.Td>
                        <Badge variant="light" color="gray" size="sm">
                          {row.status}
                        </Badge>
                      </Table.Td>
                      <Table.Td ta="right">
                        <Text fw={600} size="sm" c={row.accruedAmount > 0 ? 'red' : undefined}>
                          {money(row.accruedAmount, row.currency)}
                        </Text>
                      </Table.Td>
                      <Table.Td>
                        <Text size="sm" c={row.charging ? 'red' : undefined}>
                          {freeDaysLabel(row)}
                        </Text>
                      </Table.Td>
                      <Table.Td>
                        {row.acknowledged ? (
                          <Badge color="gray" variant="light" size="sm" leftSection={<Check size={11} />}>
                            Reviewed{row.snoozeUntil ? ' (snoozed)' : ''}
                          </Badge>
                        ) : (
                          <Badge color={meta.color} variant={row.alert === 'OK' ? 'light' : 'filled'} size="sm">
                            {meta.label}
                          </Badge>
                        )}
                      </Table.Td>
                      <Table.Td ta="right">
                        <Menu shadow="md" position="bottom-end" withinPortal>
                          <Menu.Target>
                            <ActionIcon variant="subtle" color="gray" loading={busy} aria-label="Accrual actions">
                              <MoreVertical size={16} />
                            </ActionIcon>
                          </Menu.Target>
                          <Menu.Dropdown>
                            {row.acknowledged ? (
                              <Menu.Item
                                leftSection={<Bell size={14} />}
                                onClick={() => unack.mutate(row.inventoryId)}
                              >
                                Un-acknowledge
                              </Menu.Item>
                            ) : (
                              <>
                                <Menu.Item
                                  leftSection={<Check size={14} />}
                                  onClick={() => ack.mutate({ id: row.inventoryId })}
                                >
                                  Mark reviewed
                                </Menu.Item>
                                <Menu.Item
                                  leftSection={<BellOff size={14} />}
                                  onClick={() => ack.mutate({ id: row.inventoryId, snoozeDays: 3 })}
                                >
                                  Snooze 3 days
                                </Menu.Item>
                                <Menu.Item
                                  leftSection={<BellOff size={14} />}
                                  onClick={() => ack.mutate({ id: row.inventoryId, snoozeDays: 7 })}
                                >
                                  Snooze 7 days
                                </Menu.Item>
                              </>
                            )}
                          </Menu.Dropdown>
                        </Menu>
                      </Table.Td>
                    </Table.Tr>
                  );
                })}
              </Table.Tbody>
            </Table>
          </Table.ScrollContainer>
        )}
      </Card>
    </Stack>
  );
}

function StatCard({
  icon,
  label,
  value,
  color,
}: {
  icon: React.ReactNode;
  label: string;
  value: React.ReactNode;
  color: string;
}) {
  return (
    <Card withBorder radius="md" padding="md">
      <Group gap="sm" wrap="nowrap">
        <ThemeIcon color={color} variant="light" size={40} radius="md">
          {icon}
        </ThemeIcon>
        <Stack gap={0} style={{ minWidth: 0 }}>
          <Text size="xs" c="dimmed" tt="uppercase" fw={700}>
            {label}
          </Text>
          <Text fw={800} fz={20} lh={1.1} truncate>
            {value}
          </Text>
        </Stack>
      </Group>
    </Card>
  );
}
