import { useState, useEffect } from 'react';
import {
  Title, Table, Group, Button, Stack, Text, Badge, Modal,
  NumberInput, Select, Loader, Center, Card, Alert,
} from '@mantine/core';
import { useForm } from '@mantine/form';
import { useDisclosure } from '@mantine/hooks';
import { notifications } from '@mantine/notifications';
import { IconSend, IconInfoCircle, IconCheck, IconX } from '@tabler/icons-react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import api from '../../services/api';

interface Invoice {
  id: string; invoice_number: string; unit_number: string; unit_id: string;
  invoice_date: string; due_date: string; invoice_type: string;
  description: string; amount: string; amount_paid: string; balance_due: string;
  status: string; period_start: string; period_end: string;
  assessment_group_name: string; frequency: string; owner_name: string;
}

interface PreviewGroup {
  id: string;
  name: string;
  frequency: string;
  active_units: number;
  regular_assessment: string;
  special_assessment: string;
  is_billing_month: boolean;
  total_amount: number;
  period_description: string;
}

interface Preview {
  month: number;
  year: number;
  month_name: string;
  groups: PreviewGroup[];
  summary: {
    total_groups_billing: number;
    total_invoices: number;
    total_amount: number;
  };
}

const statusColors: Record<string, string> = {
  draft: 'gray', pending: 'blue', paid: 'green', partial: 'yellow', overdue: 'red', void: 'dark',
};

const frequencyColors: Record<string, string> = {
  monthly: 'blue', quarterly: 'teal', annual: 'violet',
};

const fmt = (v: string | number) => parseFloat(String(v || '0')).toLocaleString('en-US', { style: 'currency', currency: 'USD' });

/** Extract last name from "First Last" format */
const getLastName = (ownerName: string | null) => {
  if (!ownerName) return '-';
  const parts = ownerName.trim().split(/\s+/);
  return parts.length > 1 ? parts[parts.length - 1] : ownerName;
};

export function InvoicesPage() {
  const [bulkOpened, { open: openBulk, close: closeBulk }] = useDisclosure(false);
  const [preview, setPreview] = useState<Preview | null>(null);
  const [previewLoading, setPreviewLoading] = useState(false);
  const queryClient = useQueryClient();

  const { data: invoices = [], isLoading } = useQuery<Invoice[]>({
    queryKey: ['invoices'],
    queryFn: async () => { const { data } = await api.get('/invoices'); return data; },
  });

  const bulkForm = useForm({
    initialValues: { month: new Date().getMonth() + 1, year: new Date().getFullYear() },
  });

  // Fetch preview when month/year changes
  const fetchPreview = async (month: number, year: number) => {
    setPreviewLoading(true);
    try {
      const { data } = await api.post('/invoices/generate-preview', { month, year });
      setPreview(data);
    } catch {
      setPreview(null);
    }
    setPreviewLoading(false);
  };

  useEffect(() => {
    if (bulkOpened) {
      fetchPreview(bulkForm.values.month, bulkForm.values.year);
    }
  }, [bulkOpened, bulkForm.values.month, bulkForm.values.year]);

  const bulkMutation = useMutation({
    mutationFn: (values: any) => api.post('/invoices/generate-bulk', values),
    onSuccess: (res) => {
      queryClient.invalidateQueries({ queryKey: ['invoices'] });
      queryClient.invalidateQueries({ queryKey: ['journal-entries'] });
      const groupInfo = res.data.groups?.map((g: any) => `${g.group_name}: ${g.invoices_created}`).join(', ') || '';
      notifications.show({
        message: `Generated ${res.data.created} invoices${groupInfo ? ` (${groupInfo})` : ''}`,
        color: 'green',
      });
      closeBulk();
      setPreview(null);
    },
    onError: (err: any) => { notifications.show({ message: err.response?.data?.message || 'Error', color: 'red' }); },
  });

  const lateFeesMutation = useMutation({
    mutationFn: () => api.post('/invoices/apply-late-fees', { grace_period_days: 15, late_fee_amount: 25 }),
    onSuccess: (res) => {
      queryClient.invalidateQueries({ queryKey: ['invoices'] });
      notifications.show({ message: `Applied ${res.data.applied} late fees`, color: 'yellow' });
    },
  });

  if (isLoading) return <Center h={300}><Loader /></Center>;

  const totalOutstanding = invoices.filter(i => i.status !== 'paid' && i.status !== 'void').reduce((s, i) => s + parseFloat(i.balance_due || '0'), 0);

  return (
    <Stack>
      <Group justify="space-between">
        <Title order={2}>Invoices</Title>
        <Group>
          <Button variant="outline" onClick={() => lateFeesMutation.mutate()} loading={lateFeesMutation.isPending}>Apply Late Fees</Button>
          <Button leftSection={<IconSend size={16} />} onClick={openBulk}>Generate Invoices</Button>
        </Group>
      </Group>
      <Group>
        <Card withBorder p="sm"><Text size="xs" c="dimmed">Total Invoices</Text><Text fw={700}>{invoices.length}</Text></Card>
        <Card withBorder p="sm"><Text size="xs" c="dimmed">Outstanding</Text><Text fw={700} c="red">{fmt(totalOutstanding)}</Text></Card>
      </Group>
      <Table striped highlightOnHover>
        <Table.Thead>
          <Table.Tr>
            <Table.Th>Invoice #</Table.Th><Table.Th>Unit</Table.Th><Table.Th>Owner</Table.Th>
            <Table.Th>Group</Table.Th><Table.Th>Date</Table.Th>
            <Table.Th>Due</Table.Th><Table.Th>Period</Table.Th>
            <Table.Th ta="right">Amount</Table.Th>
            <Table.Th ta="right">Paid</Table.Th><Table.Th ta="right">Balance</Table.Th><Table.Th>Status</Table.Th>
          </Table.Tr>
        </Table.Thead>
        <Table.Tbody>
          {invoices.map((i) => (
            <Table.Tr key={i.id}>
              <Table.Td fw={500}>{i.invoice_number}</Table.Td>
              <Table.Td>{i.unit_number}</Table.Td>
              <Table.Td>{getLastName(i.owner_name)}</Table.Td>
              <Table.Td>
                {i.assessment_group_name ? (
                  <Badge size="sm" variant="light" color={frequencyColors[i.frequency] || 'gray'}>
                    {i.assessment_group_name}
                  </Badge>
                ) : (
                  <Badge size="sm" variant="light">{i.invoice_type}</Badge>
                )}
              </Table.Td>
              <Table.Td>{new Date(i.invoice_date).toLocaleDateString()}</Table.Td>
              <Table.Td>{new Date(i.due_date).toLocaleDateString()}</Table.Td>
              <Table.Td>
                {i.period_start && i.period_end ? (
                  <Text size="xs" c="dimmed">
                    {new Date(i.period_start).toLocaleDateString(undefined, { month: 'short', year: 'numeric' })}
                    {i.period_start !== i.period_end && (
                      <> - {new Date(i.period_end).toLocaleDateString(undefined, { month: 'short', year: 'numeric' })}</>
                    )}
                  </Text>
                ) : (
                  <Text size="xs" c="dimmed">-</Text>
                )}
              </Table.Td>
              <Table.Td ta="right" ff="monospace">{fmt(i.amount)}</Table.Td>
              <Table.Td ta="right" ff="monospace">{fmt(i.amount_paid)}</Table.Td>
              <Table.Td ta="right" ff="monospace" fw={500}>{fmt(i.balance_due)}</Table.Td>
              <Table.Td><Badge color={statusColors[i.status] || 'gray'} size="sm">{i.status}</Badge></Table.Td>
            </Table.Tr>
          ))}
          {invoices.length === 0 && <Table.Tr><Table.Td colSpan={11}><Text ta="center" c="dimmed" py="lg">No invoices yet</Text></Table.Td></Table.Tr>}
        </Table.Tbody>
      </Table>

      <Modal opened={bulkOpened} onClose={() => { closeBulk(); setPreview(null); }} title="Generate Assessments" size="lg">
        <form onSubmit={bulkForm.onSubmit((v) => bulkMutation.mutate(v))}>
          <Stack>
            <Group grow>
              <Select label="Month" data={Array.from({length:12},(_,i)=>({value:String(i+1),label:new Date(2026,i).toLocaleString('default',{month:'long'})}))} value={String(bulkForm.values.month)} onChange={(v)=>bulkForm.setFieldValue('month',Number(v))} />
              <NumberInput label="Year" {...bulkForm.getInputProps('year')} />
            </Group>

            {previewLoading && <Center py="md"><Loader size="sm" /></Center>}

            {preview && !previewLoading && (
              <Stack gap="xs">
                <Text size="sm" fw={600}>Billing Preview for {preview.month_name} {preview.year}</Text>

                {preview.groups.map((g) => (
                  <Card key={g.id} withBorder p="xs" style={{ opacity: g.is_billing_month ? 1 : 0.5 }}>
                    <Group justify="space-between">
                      <Group gap="xs">
                        {g.is_billing_month && g.active_units > 0
                          ? <IconCheck size={16} color="green" />
                          : <IconX size={16} color="gray" />
                        }
                        <div>
                          <Group gap={6}>
                            <Text size="sm" fw={500}>{g.name}</Text>
                            <Badge size="xs" color={frequencyColors[g.frequency]} variant="light">
                              {g.frequency}
                            </Badge>
                          </Group>
                          <Text size="xs" c="dimmed">
                            {g.is_billing_month
                              ? `${g.active_units} units - ${g.period_description}`
                              : `Not a billing month for this group`
                            }
                          </Text>
                        </div>
                      </Group>
                      {g.is_billing_month && (
                        <Text size="sm" fw={500} ff="monospace">{fmt(g.total_amount)}</Text>
                      )}
                    </Group>
                  </Card>
                ))}

                {preview.summary.total_invoices > 0 ? (
                  <Alert icon={<IconInfoCircle size={16} />} color="blue" variant="light">
                    Will generate {preview.summary.total_invoices} invoices across{' '}
                    {preview.summary.total_groups_billing} group(s) totaling {fmt(preview.summary.total_amount)}
                  </Alert>
                ) : (
                  <Alert icon={<IconInfoCircle size={16} />} color="yellow" variant="light">
                    No assessment groups have billing scheduled for {preview.month_name}. No invoices will be generated.
                  </Alert>
                )}
              </Stack>
            )}

            <Button
              type="submit"
              loading={bulkMutation.isPending}
              disabled={!preview || preview.summary.total_invoices === 0}
            >
              Generate {preview?.summary.total_invoices || 0} Invoices
            </Button>
          </Stack>
        </form>
      </Modal>
    </Stack>
  );
}
