import { useState } from 'react';
import {
  ActionIcon,
  Badge,
  Button,
  Card,
  Group,
  Modal,
  NumberInput,
  Select,
  Stack,
  Tabs,
  Text,
  TextInput,
} from '@mantine/core';
import { Plus, Trash2 } from 'lucide-react';
import { DataTable, type ColumnDef } from '@edr/ui-common';

import { PageContainer, PageHeader } from '@/components/page';
import { useMutation, useQuery } from '@tanstack/react-query';

import { api } from '@/services/api';
import { useToast } from '@/hooks/use-toast';
import { FEE_RULE_TYPES, type FeeRuleType } from '@/types/warehouse';

const FREIGHT = [
  { value: 'CONTAINER', label: 'Container' },
  { value: 'BULK', label: 'Bulk' },
];
const TRADE = [
  { value: 'IMPORT', label: 'Import' },
  { value: 'EXPORT', label: 'Export' },
  { value: 'DOMESTIC', label: 'Domestic' },
];

const clean = (s: string) => s.trim() || undefined;

export default function WarehouseRulesPage() {
  return (
    <PageContainer>
      <PageHeader
        title="Allocation & Fee Rules"
        subtitle="Configure deterministic yard allocation and storage / demurrage free time and rates."
      />
      <Card>
        <Tabs defaultValue="allocation">
          <Tabs.List>
            <Tabs.Tab value="allocation">Allocation Rules</Tabs.Tab>
            <Tabs.Tab value="fees">Storage / Demurrage Fees</Tabs.Tab>
          </Tabs.List>
          <Tabs.Panel value="allocation" pt="md">
            <AllocationRules />
          </Tabs.Panel>
          <Tabs.Panel value="fees" pt="md">
            <FeeRules />
          </Tabs.Panel>
        </Tabs>
      </Card>
    </PageContainer>
  );
}

function AllocationRules() {
  const { toast } = useToast();
  const { data, isLoading } = useQuery(
    api.warehouses.allocationRules.queryOptions(),
  );
  const create = useMutation(api.warehouses.createAllocationRule.mutationOptions());
  const remove = useMutation(api.warehouses.deleteAllocationRule.mutationOptions());
  const [open, setOpen] = useState(false);
  const [form, setForm] = useState({
    name: '',
    priority: 100,
    freightType: '',
    tradeDirection: '',
    cargoTypeCode: '',
    containerStatus: '',
    targetYardCode: '',
    storageType: '',
  });
  const rules = data ?? [];

  const submit = async () => {
    if (!form.name.trim() || !form.targetYardCode.trim()) {
      toast({ variant: 'destructive', title: 'Name and target yard code are required' });
      return;
    }
    await create.mutateAsync({
      name: form.name.trim(),
      priority: form.priority,
      freightType: clean(form.freightType) ?? null,
      tradeDirection: clean(form.tradeDirection) ?? null,
      cargoTypeCode: clean(form.cargoTypeCode) ?? null,
      containerStatus: clean(form.containerStatus) ?? null,
      targetYardCode: form.targetYardCode.trim(),
      storageType: clean(form.storageType) ?? null,
      isActive: true,
    } as never);
    toast({ title: 'Allocation rule created' });
    setOpen(false);
    setForm({ name: '', priority: 100, freightType: '', tradeDirection: '', cargoTypeCode: '', containerStatus: '', targetYardCode: '', storageType: '' });
  };

  const columns: ColumnDef<(typeof rules)[number]>[] = [
    { id: 'priority', header: 'Priority', cell: ({ row }) => row.original.priority },
    { id: 'name', header: 'Name', cell: ({ row }) => row.original.name },
    { id: 'freight', header: 'Freight', cell: ({ row }) => row.original.freightType ?? '—' },
    { id: 'trade', header: 'Trade', cell: ({ row }) => row.original.tradeDirection ?? '—' },
    { id: 'cargo', header: 'Cargo code', cell: ({ row }) => row.original.cargoTypeCode ?? '—' },
    {
      id: 'targetYard',
      header: 'Target yard',
      cell: ({ row }) => <Badge variant="light">{row.original.targetYardCode}</Badge>,
    },
    {
      id: 'active',
      header: 'Active',
      cell: ({ row }) => (
        <Badge color={row.original.isActive ? 'edr-green' : 'gray'} variant="light">
          {row.original.isActive ? 'Yes' : 'No'}
        </Badge>
      ),
    },
    {
      id: 'actions',
      header: '',
      cell: ({ row }) => (
        <Group justify="flex-end" onClick={(e) => e.stopPropagation()}>
          <ActionIcon variant="subtle" color="red" onClick={() => remove.mutate(row.original.id)} title="Delete">
            <Trash2 size={16} />
          </ActionIcon>
        </Group>
      ),
    },
  ];

  return (
    <>
      <Group justify="space-between" mb="sm">
        <Text c="dimmed" size="sm">{rules.length} rule(s) — matched by ascending priority</Text>
        <Button leftSection={<Plus size={16} />} onClick={() => setOpen(true)}>New allocation rule</Button>
      </Group>
      <DataTable
        columns={columns}
        data={rules}
        status={isLoading ? 'loading' : 'success'}
        emptyMessage="No allocation rules yet."
        containerClassName="border-0 shadow-none"
      />

      <Modal opened={open} onClose={() => setOpen(false)} title="New allocation rule" centered size="lg">
        <Stack gap="sm">
          <Group grow>
            <TextInput label="Name" required value={form.name} onChange={(e) => setForm((f) => ({ ...f, name: e.currentTarget.value }))} />
            <NumberInput label="Priority" value={form.priority} onChange={(v) => setForm((f) => ({ ...f, priority: Number(v) || 100 }))} />
          </Group>
          <Group grow>
            <Select label="Freight type" data={FREIGHT} value={form.freightType || null} onChange={(v) => setForm((f) => ({ ...f, freightType: v ?? '' }))} clearable />
            <Select label="Trade direction" data={TRADE} value={form.tradeDirection || null} onChange={(v) => setForm((f) => ({ ...f, tradeDirection: v ?? '' }))} clearable />
          </Group>
          <Group grow>
            <TextInput label="Cargo type code" value={form.cargoTypeCode} onChange={(e) => setForm((f) => ({ ...f, cargoTypeCode: e.currentTarget.value }))} />
            <TextInput label="Container status" placeholder="e.g. MAINTENANCE" value={form.containerStatus} onChange={(e) => setForm((f) => ({ ...f, containerStatus: e.currentTarget.value }))} />
          </Group>
          <Group grow>
            <TextInput label="Target yard code" required value={form.targetYardCode} onChange={(e) => setForm((f) => ({ ...f, targetYardCode: e.currentTarget.value }))} />
            <TextInput label="Storage type" value={form.storageType} onChange={(e) => setForm((f) => ({ ...f, storageType: e.currentTarget.value }))} />
          </Group>
          <Group justify="flex-end" mt="sm">
            <Button variant="default" onClick={() => setOpen(false)}>Cancel</Button>
            <Button loading={create.isPending} onClick={submit}>Create</Button>
          </Group>
        </Stack>
      </Modal>
    </>
  );
}

function FeeRules() {
  const { toast } = useToast();
  const { data, isLoading } = useQuery(api.warehouses.feeRules.queryOptions());
  const create = useMutation(api.warehouses.createFeeRule.mutationOptions());
  const remove = useMutation(api.warehouses.deleteFeeRule.mutationOptions());
  const [open, setOpen] = useState(false);
  const [form, setForm] = useState({
    name: '',
    ruleType: 'DEMURRAGE_FEE' as FeeRuleType,
    freightType: '',
    tradeDirection: '',
    cargoTypeCode: '',
    freeDays: 3,
    ratePerDay: 0,
    currency: 'USD',
  });
  const rules = data ?? [];

  const submit = async () => {
    if (!form.name.trim()) {
      toast({ variant: 'destructive', title: 'Name is required' });
      return;
    }
    await create.mutateAsync({
      name: form.name.trim(),
      ruleType: form.ruleType,
      freightType: clean(form.freightType) ?? null,
      tradeDirection: clean(form.tradeDirection) ?? null,
      cargoTypeCode: clean(form.cargoTypeCode) ?? null,
      freeDays: form.freeDays,
      ratePerDay: form.ratePerDay,
      currency: form.currency || 'USD',
      isActive: true,
    } as never);
    toast({ title: 'Fee rule created' });
    setOpen(false);
  };

  const columns: ColumnDef<(typeof rules)[number]>[] = [
    {
      id: 'type',
      header: 'Type',
      cell: ({ row }) => (
        <Badge color={row.original.ruleType === 'DEMURRAGE_FEE' ? 'orange' : 'teal'} variant="light">
          {row.original.ruleType === 'DEMURRAGE_FEE' ? 'Demurrage' : 'Storage'}
        </Badge>
      ),
    },
    { id: 'name', header: 'Name', cell: ({ row }) => row.original.name },
    { id: 'freight', header: 'Freight', cell: ({ row }) => row.original.freightType ?? '—' },
    { id: 'trade', header: 'Trade', cell: ({ row }) => row.original.tradeDirection ?? '—' },
    { id: 'freeDays', header: 'Free days', cell: ({ row }) => row.original.freeDays },
    {
      id: 'rate',
      header: 'Rate / day',
      cell: ({ row }) => `${Number(row.original.ratePerDay).toLocaleString()} ${row.original.currency}`,
    },
    {
      id: 'active',
      header: 'Active',
      cell: ({ row }) => (
        <Badge color={row.original.isActive ? 'edr-green' : 'gray'} variant="light">
          {row.original.isActive ? 'Yes' : 'No'}
        </Badge>
      ),
    },
    {
      id: 'actions',
      header: '',
      cell: ({ row }) => (
        <Group justify="flex-end" onClick={(e) => e.stopPropagation()}>
          <ActionIcon variant="subtle" color="red" onClick={() => remove.mutate(row.original.id)} title="Delete">
            <Trash2 size={16} />
          </ActionIcon>
        </Group>
      ),
    },
  ];

  return (
    <>
      <Group justify="space-between" mb="sm">
        <Text c="dimmed" size="sm">{rules.length} rule(s) — most specific match applies</Text>
        <Button leftSection={<Plus size={16} />} onClick={() => setOpen(true)}>New fee rule</Button>
      </Group>
      <DataTable
        columns={columns}
        data={rules}
        status={isLoading ? 'loading' : 'success'}
        emptyMessage="No fee rules yet."
        containerClassName="border-0 shadow-none"
      />

      <Modal opened={open} onClose={() => setOpen(false)} title="New fee rule" centered size="lg">
        <Stack gap="sm">
          <Group grow>
            <TextInput label="Name" required value={form.name} onChange={(e) => setForm((f) => ({ ...f, name: e.currentTarget.value }))} />
            <Select label="Rule type" data={FEE_RULE_TYPES.map((t) => ({ value: t, label: t === 'DEMURRAGE_FEE' ? 'Demurrage' : 'Storage' }))} value={form.ruleType} onChange={(v) => setForm((f) => ({ ...f, ruleType: (v as FeeRuleType) ?? 'DEMURRAGE_FEE' }))} allowDeselect={false} />
          </Group>
          <Group grow>
            <Select label="Freight type" data={FREIGHT} value={form.freightType || null} onChange={(v) => setForm((f) => ({ ...f, freightType: v ?? '' }))} clearable />
            <Select label="Trade direction" data={TRADE} value={form.tradeDirection || null} onChange={(v) => setForm((f) => ({ ...f, tradeDirection: v ?? '' }))} clearable />
            <TextInput label="Cargo type code" value={form.cargoTypeCode} onChange={(e) => setForm((f) => ({ ...f, cargoTypeCode: e.currentTarget.value }))} />
          </Group>
          <Group grow>
            <NumberInput label="Free days" min={0} value={form.freeDays} onChange={(v) => setForm((f) => ({ ...f, freeDays: Number(v) || 0 }))} />
            <NumberInput label="Rate / day" min={0} value={form.ratePerDay} onChange={(v) => setForm((f) => ({ ...f, ratePerDay: Number(v) || 0 }))} />
            <TextInput label="Currency" value={form.currency} onChange={(e) => setForm((f) => ({ ...f, currency: e.currentTarget.value }))} />
          </Group>
          <Group justify="flex-end" mt="sm">
            <Button variant="default" onClick={() => setOpen(false)}>Cancel</Button>
            <Button loading={create.isPending} onClick={submit}>Create</Button>
          </Group>
        </Stack>
      </Modal>
    </>
  );
}
