import { useState } from 'react';
import {
  Title, Table, Group, Button, Stack, Text, Badge, Modal,
  NumberInput, Select, TextInput, Loader, Center, ActionIcon, Tooltip,
} from '@mantine/core';
import { DateInput } from '@mantine/dates';
import { useForm } from '@mantine/form';
import { useDisclosure } from '@mantine/hooks';
import { notifications } from '@mantine/notifications';
import { IconPlus, IconEdit, IconTrash } from '@tabler/icons-react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import api from '../../services/api';
import { useIsReadOnly } from '../../stores/authStore';

interface Payment {
  id: string; unit_id: string; unit_number: string; invoice_id: string;
  invoice_number: string; payment_date: string; amount: string;
  payment_method: string; reference_number: string; status: string; notes: string;
}

export function PaymentsPage() {
  const [opened, { open, close }] = useDisclosure(false);
  const [editing, setEditing] = useState<Payment | null>(null);
  const [deleteConfirm, setDeleteConfirm] = useState<Payment | null>(null);
  const queryClient = useQueryClient();
  const isReadOnly = useIsReadOnly();

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

  const { data: invoices = [] } = useQuery<any[]>({
    queryKey: ['invoices-unpaid'],
    queryFn: async () => {
      const { data } = await api.get('/invoices');
      return data.filter((i: any) => i.status !== 'paid' && i.status !== 'void');
    },
  });

  const form = useForm({
    initialValues: {
      invoice_id: '', amount: 0, payment_method: 'check',
      reference_number: '', payment_date: new Date(), notes: '',
    },
  });

  const invalidateAll = () => {
    queryClient.invalidateQueries({ queryKey: ['payments'] });
    queryClient.invalidateQueries({ queryKey: ['invoices'] });
    queryClient.invalidateQueries({ queryKey: ['invoices-unpaid'] });
    queryClient.invalidateQueries({ queryKey: ['accounts'] });
    queryClient.invalidateQueries({ queryKey: ['journal-entries'] });
  };

  const createMutation = useMutation({
    mutationFn: (values: any) => {
      const inv = invoices.find((i: any) => i.id === values.invoice_id);
      return api.post('/payments', {
        ...values,
        unit_id: inv?.unit_id,
        payment_date: values.payment_date.toISOString().split('T')[0],
      });
    },
    onSuccess: () => {
      invalidateAll();
      notifications.show({ message: 'Payment recorded', color: 'green' });
      close(); setEditing(null); form.reset();
    },
    onError: (err: any) => { notifications.show({ message: err.response?.data?.message || 'Error', color: 'red' }); },
  });

  const updateMutation = useMutation({
    mutationFn: (values: any) => {
      return api.put(`/payments/${editing!.id}`, {
        payment_date: values.payment_date.toISOString().split('T')[0],
        amount: values.amount,
        payment_method: values.payment_method,
        reference_number: values.reference_number,
        notes: values.notes,
      });
    },
    onSuccess: () => {
      invalidateAll();
      notifications.show({ message: 'Payment updated', color: 'green' });
      close(); setEditing(null); form.reset();
    },
    onError: (err: any) => { notifications.show({ message: err.response?.data?.message || 'Error', color: 'red' }); },
  });

  const deleteMutation = useMutation({
    mutationFn: (id: string) => api.delete(`/payments/${id}`),
    onSuccess: () => {
      invalidateAll();
      notifications.show({ message: 'Payment deleted', color: 'orange' });
      setDeleteConfirm(null);
      close(); setEditing(null); form.reset();
    },
    onError: (err: any) => { notifications.show({ message: err.response?.data?.message || 'Error', color: 'red' }); },
  });

  const handleEdit = (payment: Payment) => {
    setEditing(payment);
    form.setValues({
      invoice_id: payment.invoice_id || '',
      amount: parseFloat(payment.amount || '0'),
      payment_method: payment.payment_method || 'check',
      reference_number: payment.reference_number || '',
      payment_date: new Date(payment.payment_date),
      notes: payment.notes || '',
    });
    open();
  };

  const handleNew = () => {
    setEditing(null);
    form.reset();
    open();
  };

  const handleSubmit = (values: any) => {
    if (editing) {
      updateMutation.mutate(values);
    } else {
      createMutation.mutate(values);
    }
  };

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

  const formatPeriod = (inv: any) => {
    if (inv.period_start && inv.period_end) {
      const start = new Date(inv.period_start).toLocaleDateString(undefined, { month: 'short' });
      const end = new Date(inv.period_end).toLocaleDateString(undefined, { month: 'short', year: 'numeric' });
      return inv.period_start === inv.period_end ? start : `${start}-${end}`;
    }
    return '';
  };

  const invoiceOptions = invoices.map((i: any) => {
    const period = formatPeriod(i);
    const periodStr = period ? ` - ${period}` : '';
    return {
      value: i.id,
      label: `${i.invoice_number} - ${i.unit_number || 'Unit'}${periodStr} - Balance: $${parseFloat(i.balance_due || i.amount).toFixed(2)}`,
    };
  });

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

  return (
    <Stack>
      <Group justify="space-between">
        <Title order={2}>Payments</Title>
        {!isReadOnly && <Button leftSection={<IconPlus size={16} />} onClick={handleNew}>Record Payment</Button>}
      </Group>
      <Table striped highlightOnHover>
        <Table.Thead>
          <Table.Tr>
            <Table.Th>Date</Table.Th><Table.Th>Unit</Table.Th><Table.Th>Invoice</Table.Th>
            <Table.Th ta="right">Amount</Table.Th><Table.Th>Method</Table.Th>
            <Table.Th>Reference</Table.Th><Table.Th>Status</Table.Th>
            {!isReadOnly && <Table.Th></Table.Th>}
          </Table.Tr>
        </Table.Thead>
        <Table.Tbody>
          {payments.map((p) => (
            <Table.Tr key={p.id}>
              <Table.Td>{new Date(p.payment_date).toLocaleDateString()}</Table.Td>
              <Table.Td>{p.unit_number}</Table.Td>
              <Table.Td>{p.invoice_number}</Table.Td>
              <Table.Td ta="right" ff="monospace" fw={500}>{fmt(p.amount)}</Table.Td>
              <Table.Td><Badge size="sm" variant="light">{p.payment_method}</Badge></Table.Td>
              <Table.Td>{p.reference_number}</Table.Td>
              <Table.Td><Badge color={p.status === 'completed' ? 'green' : 'yellow'} size="sm">{p.status}</Badge></Table.Td>
              {!isReadOnly && (
                <Table.Td>
                  <Tooltip label="Edit payment">
                    <ActionIcon variant="subtle" onClick={() => handleEdit(p)}>
                      <IconEdit size={16} />
                    </ActionIcon>
                  </Tooltip>
                </Table.Td>
              )}
            </Table.Tr>
          ))}
          {payments.length === 0 && (
            <Table.Tr><Table.Td colSpan={isReadOnly ? 7 : 8}><Text ta="center" c="dimmed" py="lg">No payments recorded yet</Text></Table.Td></Table.Tr>
          )}
        </Table.Tbody>
      </Table>

      {/* Create / Edit Payment Modal */}
      <Modal opened={opened} onClose={() => { close(); setEditing(null); form.reset(); }} title={editing ? 'Edit Payment' : 'Record Payment'}>
        <form onSubmit={form.onSubmit(handleSubmit)}>
          <Stack>
            {!editing && (
              <Select label="Invoice" required data={invoiceOptions} searchable
                {...form.getInputProps('invoice_id')} />
            )}
            {editing && (
              <TextInput label="Invoice" value={editing.invoice_number || 'N/A'} disabled />
            )}
            <DateInput label="Payment Date" required {...form.getInputProps('payment_date')} />
            <NumberInput label="Amount" required prefix="$" decimalScale={2} min={0.01}
              {...form.getInputProps('amount')} />
            <Select label="Payment Method" data={[
              { value: 'check', label: 'Check' }, { value: 'ach', label: 'ACH' },
              { value: 'credit_card', label: 'Credit Card' }, { value: 'cash', label: 'Cash' },
              { value: 'wire', label: 'Wire' }, { value: 'other', label: 'Other' },
            ]} {...form.getInputProps('payment_method')} />
            <TextInput label="Reference Number" placeholder="Check # or transaction ID"
              {...form.getInputProps('reference_number')} />
            <TextInput label="Notes" placeholder="Optional notes"
              {...form.getInputProps('notes')} />

            <Group justify="space-between">
              {editing ? (
                <>
                  <Button
                    variant="outline"
                    color="red"
                    leftSection={<IconTrash size={16} />}
                    onClick={() => setDeleteConfirm(editing)}
                  >
                    Delete Payment
                  </Button>
                  <Button type="submit" loading={updateMutation.isPending}>
                    Update Payment
                  </Button>
                </>
              ) : (
                <Button type="submit" fullWidth loading={createMutation.isPending}>Record Payment</Button>
              )}
            </Group>
          </Stack>
        </form>
      </Modal>

      {/* Delete Confirmation Modal */}
      <Modal
        opened={!!deleteConfirm}
        onClose={() => setDeleteConfirm(null)}
        title="Delete Payment"
        size="sm"
      >
        <Stack>
          <Text size="sm">
            Are you sure you want to delete this payment of{' '}
            <Text span fw={700}>{deleteConfirm ? fmt(deleteConfirm.amount) : ''}</Text>{' '}
            for unit {deleteConfirm?.unit_number}?
          </Text>
          <Text size="xs" c="dimmed">
            This will also remove the associated journal entry and recalculate the invoice balance.
          </Text>
          <Group justify="flex-end">
            <Button variant="default" onClick={() => setDeleteConfirm(null)}>Cancel</Button>
            <Button
              color="red"
              loading={deleteMutation.isPending}
              onClick={() => deleteConfirm && deleteMutation.mutate(deleteConfirm.id)}
            >
              Delete Payment
            </Button>
          </Group>
        </Stack>
      </Modal>
    </Stack>
  );
}
