import { useState } from 'react';
import {
  Typography,
  Button,
  Space,
  DatePicker,
  Select,
  Modal,
  Form,
  Input,
  InputNumber,
  message,
  Tag,
  Tooltip,
  Dropdown,
  Skeleton,
  Empty,
} from 'antd';
import {
  PlusOutlined,
  FilterOutlined,
  EyeOutlined,
  EditOutlined,
  CopyOutlined,
  DeleteOutlined,
  MoreOutlined,
} from '@ant-design/icons';
import type { MenuProps } from 'antd';
import dayjs from 'dayjs';
import DataTable, { DataTableColumn } from '@/components/tables/DataTable';
import { useCompanyStore } from '@/stores/companyStore';
import { useActiveAccounts } from '@/api/queries/accountQueries';
import { useJournalEntryDrafts } from '@/api/queries/draftQueries';
import { formatCurrency } from '@/lib/formatters';
import { PageHeader } from '@/components/shared/PageHeader';
import { validateDoubleEntry } from '@/lib/accounting';
import type { TransactionLine, JournalEntryDraft } from '@/types/accounting';
import { useCreateJournalEntryDraft, useUpdateJournalEntryDraft, useDiscardJournalEntryDraft } from '@/api/mutations/draftMutations';
import { usePeriodStore } from '@/stores/periodStore';

const { Text } = Typography;
const { RangePicker } = DatePicker;

// Display type for journal entry drafts
interface DraftDisplay {
  id: string;
  transactionNumber: string;
  date: string;
  description: string;
  totalDebit: number;
  totalCredit: number;
  isReconciled: boolean;
  isVoided: boolean;
  lines: JournalEntryDraft['lines'];
}

export default function Kassekladde() {
  const { activeCompany } = useCompanyStore();
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [editingDraft, setEditingDraft] = useState<DraftDisplay | null>(null);
  const [dateFilter, setDateFilter] = useState<[dayjs.Dayjs, dayjs.Dayjs] | null>(null);
  const [form] = Form.useForm();
  const [lines, setLines] = useState<Partial<TransactionLine>[]>([
    { debit: 0, credit: 0 },
    { debit: 0, credit: 0 },
  ]);

  const { currentFiscalYear } = usePeriodStore();

  // Mutation hooks
  const createDraftMutation = useCreateJournalEntryDraft();
  const updateDraftMutation = useUpdateJournalEntryDraft();
  const discardDraftMutation = useDiscardJournalEntryDraft();

  // Fetch accounts and drafts from API
  const { data: accounts = [], isLoading: accountsLoading } = useActiveAccounts(activeCompany?.id);
  const { data: drafts = [], isLoading: draftsLoading } = useJournalEntryDrafts(activeCompany?.id);

  const isLoading = accountsLoading || draftsLoading;

  // Convert drafts to display format
  const displayData: DraftDisplay[] = drafts.map(draft => ({
    id: draft.id,
    transactionNumber: draft.voucherNumber || draft.name,
    date: draft.documentDate || draft.createdAt,
    description: draft.description || draft.name,
    lines: draft.lines || [],
    totalDebit: draft.lines?.reduce((sum, l) => sum + (l.debitAmount || 0), 0) ?? 0,
    totalCredit: draft.lines?.reduce((sum, l) => sum + (l.creditAmount || 0), 0) ?? 0,
    isReconciled: draft.status === 'posted',
    isVoided: draft.status === 'discarded',
  }));

  const columns: DataTableColumn<DraftDisplay>[] = [
    {
      dataIndex: 'transactionNumber',
      title: 'Bilagsnr.',
      width: 120,
      sortable: true,
      render: (value) => <Text strong>#{value as string}</Text>,
    },
    {
      dataIndex: 'date',
      title: 'Dato',
      width: 100,
      sortable: true,
      columnType: 'date',
    },
    {
      dataIndex: 'description',
      title: 'Beskrivelse',
      ellipsis: true,
    },
    {
      dataIndex: 'totalDebit',
      title: 'Debet',
      width: 120,
      sortable: true,
      columnType: 'currency',
    },
    {
      dataIndex: 'totalCredit',
      title: 'Kredit',
      width: 120,
      sortable: true,
      columnType: 'currency',
    },
    {
      dataIndex: 'isReconciled',
      title: 'Status',
      width: 100,
      render: (value, record) => {
        if (record.isVoided) {
          return <Tag color="red">Annulleret</Tag>;
        }
        return value ? (
          <Tag color="green">Bogført</Tag>
        ) : (
          <Tag color="orange">Kladde</Tag>
        );
      },
    },
    {
      dataIndex: 'id',
      title: '',
      width: 50,
      render: (_, record) => {
        const menuItems: MenuProps['items'] = [
          {
            key: 'view',
            icon: <EyeOutlined />,
            label: 'Vis detaljer',
          },
          {
            key: 'edit',
            icon: <EditOutlined />,
            label: 'Rediger',
            disabled: record.isReconciled || record.isVoided,
          },
          {
            key: 'copy',
            icon: <CopyOutlined />,
            label: 'Kopier',
          },
          {
            type: 'divider',
          },
          {
            key: 'void',
            icon: <DeleteOutlined />,
            label: 'Annuller',
            danger: true,
            disabled: record.isVoided,
          },
        ];

        return (
          <Dropdown
            menu={{
              items: menuItems,
              onClick: ({ key }) => handleAction(key, record),
            }}
            trigger={['click']}
          >
            <Button type="text" icon={<MoreOutlined />} size="small" />
          </Dropdown>
        );
      },
    },
  ];

  const handleAction = (action: string, record: DraftDisplay) => {
    switch (action) {
      case 'view':
        message.info(`Vis detaljer for bilag ${record.transactionNumber}`);
        break;
      case 'edit':
        setEditingDraft(record);
        setIsModalOpen(true);
        break;
      case 'copy':
        if (!activeCompany) {
          message.error('Ingen virksomhed valgt');
          break;
        }
        (async () => {
          try {
            const draft = await createDraftMutation.mutateAsync({
              companyId: activeCompany.id,
              name: `Kopi af ${record.description}`,
              description: record.description,
              fiscalYearId: currentFiscalYear?.id,
            });
            // Copy lines to the new draft
            if (record.lines && record.lines.length > 0) {
              await updateDraftMutation.mutateAsync({
                id: draft.id,
                lines: record.lines.map((l, idx) => ({
                  lineNumber: idx + 1,
                  accountId: l.accountId,
                  debitAmount: l.debitAmount || 0,
                  creditAmount: l.creditAmount || 0,
                  description: l.description,
                  vatCode: l.vatCode,
                })),
              });
            }
            message.success(`Bilag ${record.transactionNumber} kopieret`);
          } catch (error) {
            if (error instanceof Error) {
              message.error(`Fejl ved kopiering: ${error.message}`);
            }
          }
        })();
        break;
      case 'void':
        Modal.confirm({
          title: 'Annuller bilag',
          content: `Er du sikker på at du vil annullere bilag ${record.transactionNumber}?`,
          okText: 'Annuller bilag',
          okType: 'danger',
          cancelText: 'Fortryd',
          onOk: async () => {
            try {
              await discardDraftMutation.mutateAsync(record.id);
              message.success(`Bilag ${record.transactionNumber} annulleret`);
            } catch (error) {
              if (error instanceof Error) {
                message.error(`Fejl ved annullering: ${error.message}`);
              }
            }
          },
        });
        break;
    }
  };

  const handleAddLine = () => {
    setLines([...lines, { debit: 0, credit: 0 }]);
  };

  const handleRemoveLine = (index: number) => {
    if (lines.length > 2) {
      setLines(lines.filter((_, i) => i !== index));
    }
  };

  const handleLineChange = (index: number, field: string, value: unknown) => {
    const newLines = [...lines];
    newLines[index] = { ...newLines[index], [field]: value };

    // Auto-balance: if debit is entered, clear credit and vice versa
    if (field === 'debit' && value) {
      newLines[index].credit = 0;
    } else if (field === 'credit' && value) {
      newLines[index].debit = 0;
    }

    setLines(newLines);
  };

  const handleSubmit = async () => {
    try {
      const values = await form.validateFields();

      // Validate double-entry
      const validation = validateDoubleEntry(lines as TransactionLine[]);
      if (!validation.valid) {
        message.error(
          `Debet (${formatCurrency(validation.totalDebit)}) skal være lig kredit (${formatCurrency(validation.totalCredit)})`
        );
        return;
      }

      if (!activeCompany) {
        message.error('Ingen virksomhed valgt');
        return;
      }

      if (editingDraft) {
        // Update existing draft
        await updateDraftMutation.mutateAsync({
          id: editingDraft.id,
          name: values.description,
          documentDate: values.date?.format('YYYY-MM-DD'),
          description: values.description,
          fiscalYearId: currentFiscalYear?.id,
          lines: lines
            .filter(l => l.accountId)
            .map((l, idx) => ({
              lineNumber: idx + 1,
              accountId: l.accountId!,
              debitAmount: l.debit || 0,
              creditAmount: l.credit || 0,
              description: l.description,
              vatCode: l.vatCode,
            })),
        });
        message.success('Bilag opdateret');
      } else {
        // Create new draft
        const draft = await createDraftMutation.mutateAsync({
          companyId: activeCompany.id,
          name: values.description,
          documentDate: values.date?.format('YYYY-MM-DD'),
          description: values.description,
          fiscalYearId: currentFiscalYear?.id,
        });

        // Update the draft with lines
        if (lines.some(l => l.accountId)) {
          await updateDraftMutation.mutateAsync({
            id: draft.id,
            lines: lines
              .filter(l => l.accountId)
              .map((l, idx) => ({
                lineNumber: idx + 1,
                accountId: l.accountId!,
                debitAmount: l.debit || 0,
                creditAmount: l.credit || 0,
                description: l.description,
                vatCode: l.vatCode,
              })),
          });
        }
        message.success('Bilag oprettet');
      }

      setIsModalOpen(false);
      form.resetFields();
      setLines([{ debit: 0, credit: 0 }, { debit: 0, credit: 0 }]);
    } catch (error) {
      if (error instanceof Error) {
        message.error(`Fejl: ${error.message}`);
      }
    }
  };

  const balance = validateDoubleEntry(lines as TransactionLine[]);

  if (isLoading) {
    return (
      <div>
        <PageHeader
          title="Kassekladde"
          subtitle={activeCompany?.name}
          breadcrumbs={[{ title: 'Bogføring', path: '/kontooversigt' }, { title: 'Kassekladde' }]}
        />
        <Skeleton active paragraph={{ rows: 10 }} />
      </div>
    );
  }

  return (
    <div>
      <PageHeader
        title="Kassekladde"
        subtitle={activeCompany?.name}
        breadcrumbs={[{ title: 'Bogføring', path: '/kontooversigt' }, { title: 'Kassekladde' }]}
        extra={
          <Button
            type="primary"
            icon={<PlusOutlined />}
            onClick={() => {
              setEditingDraft(null);
              setIsModalOpen(true);
            }}
          >
            Nyt bilag
          </Button>
        }
      />

      {/* Filters */}
      <Space style={{ marginBottom: 16 }} wrap>
        <RangePicker
          placeholder={['Fra dato', 'Til dato']}
          value={dateFilter}
          onChange={(dates) => setDateFilter(dates as [dayjs.Dayjs, dayjs.Dayjs] | null)}
          format="DD/MM/YYYY"
        />
        <Select
          placeholder="Konto"
          style={{ width: 200 }}
          allowClear
          options={accounts.map((acc) => ({
            value: acc.id,
            label: `${acc.accountNumber} - ${acc.name}`,
          }))}
        />
        <Select
          placeholder="Status"
          style={{ width: 120 }}
          allowClear
          options={[
            { value: 'posted', label: 'Bogført' },
            { value: 'draft', label: 'Kladde' },
            { value: 'discarded', label: 'Annulleret' },
          ]}
        />
        <Button icon={<FilterOutlined />}>Flere filtre</Button>
      </Space>

      {/* Data Table */}
      {displayData.length === 0 ? (
        <Empty description="Ingen bilag fundet. Opret et nyt bilag for at komme i gang." />
      ) : (
        <DataTable<DraftDisplay>
          data={displayData}
          columns={columns}
          exportFilename="kassekladde"
          rowSelection="multiple"
          onRowClick={(record) => handleAction('view', record)}
          rowClassName={(record) =>
            record.isVoided ? 'voided-row' : ''
          }
        />
      )}

      {/* Create/Edit Modal */}
      <Modal
        title={editingDraft ? 'Rediger bilag' : 'Nyt bilag'}
        open={isModalOpen}
        onCancel={() => {
          setIsModalOpen(false);
          form.resetFields();
          setLines([{ debit: 0, credit: 0 }, { debit: 0, credit: 0 }]);
        }}
        onOk={handleSubmit}
        okText="Gem"
        cancelText="Annuller"
        width={800}
      >
        <Form form={form} layout="vertical">
          <Space style={{ width: '100%' }} direction="vertical" size="middle">
            <Space style={{ width: '100%' }}>
              <Form.Item
                name="date"
                label="Dato"
                rules={[{ required: true, message: 'Vælg dato' }]}
                initialValue={dayjs()}
              >
                <DatePicker format="DD/MM/YYYY" style={{ width: 150 }} />
              </Form.Item>
              <Form.Item
                name="description"
                label="Beskrivelse"
                rules={[{ required: true, message: 'Indtast beskrivelse' }]}
                style={{ flex: 1 }}
              >
                <Input placeholder="F.eks. Faktura #1234 til kunde" />
              </Form.Item>
            </Space>

            {/* Transaction Lines */}
            <div>
              <Text strong style={{ display: 'block', marginBottom: 8 }}>
                Posteringslinjer
              </Text>
              <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                <thead>
                  <tr style={{ borderBottom: '1px solid #f0f0f0' }}>
                    <th style={{ textAlign: 'left', padding: 8, width: '40%' }}>Konto</th>
                    <th style={{ textAlign: 'right', padding: 8, width: '20%' }}>Debet</th>
                    <th style={{ textAlign: 'right', padding: 8, width: '20%' }}>Kredit</th>
                    <th style={{ textAlign: 'left', padding: 8, width: '15%' }}>Tekst</th>
                    <th style={{ width: '5%' }}></th>
                  </tr>
                </thead>
                <tbody>
                  {lines.map((line, index) => (
                    <tr key={index}>
                      <td style={{ padding: 4 }}>
                        <Select
                          style={{ width: '100%' }}
                          placeholder="Vælg konto"
                          showSearch
                          optionFilterProp="label"
                          value={line.accountId}
                          onChange={(value) => handleLineChange(index, 'accountId', value)}
                          options={accounts.map((acc) => ({
                            value: acc.id,
                            label: `${acc.accountNumber} - ${acc.name}`,
                          }))}
                        />
                      </td>
                      <td style={{ padding: 4 }}>
                        <InputNumber
                          style={{ width: '100%' }}
                          min={0}
                          precision={2}
                          value={line.debit}
                          onChange={(value) => handleLineChange(index, 'debit', value || 0)}
                          formatter={(value) =>
                            `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, '.')
                          }
                          parser={(value) =>
                            value?.replace(/\./g, '').replace(',', '.') as unknown as number
                          }
                        />
                      </td>
                      <td style={{ padding: 4 }}>
                        <InputNumber
                          style={{ width: '100%' }}
                          min={0}
                          precision={2}
                          value={line.credit}
                          onChange={(value) => handleLineChange(index, 'credit', value || 0)}
                          formatter={(value) =>
                            `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, '.')
                          }
                          parser={(value) =>
                            value?.replace(/\./g, '').replace(',', '.') as unknown as number
                          }
                        />
                      </td>
                      <td style={{ padding: 4 }}>
                        <Input
                          placeholder="Valgfri"
                          value={line.description}
                          onChange={(e) =>
                            handleLineChange(index, 'description', e.target.value)
                          }
                        />
                      </td>
                      <td style={{ padding: 4 }}>
                        {lines.length > 2 && (
                          <Button
                            type="text"
                            danger
                            size="small"
                            onClick={() => handleRemoveLine(index)}
                          >
                            x
                          </Button>
                        )}
                      </td>
                    </tr>
                  ))}
                </tbody>
                <tfoot>
                  <tr style={{ borderTop: '2px solid #f0f0f0' }}>
                    <td style={{ padding: 8 }}>
                      <Button type="dashed" size="small" onClick={handleAddLine}>
                        + Tilføj linje
                      </Button>
                    </td>
                    <td
                      style={{
                        padding: 8,
                        textAlign: 'right',
                        fontWeight: 'bold',
                      }}
                    >
                      {formatCurrency(balance.totalDebit)}
                    </td>
                    <td
                      style={{
                        padding: 8,
                        textAlign: 'right',
                        fontWeight: 'bold',
                      }}
                    >
                      {formatCurrency(balance.totalCredit)}
                    </td>
                    <td colSpan={2} style={{ padding: 8 }}>
                      {!balance.valid && (
                        <Tooltip title={`Difference: ${formatCurrency(balance.difference)}`}>
                          <Tag color="red">Ubalance!</Tag>
                        </Tooltip>
                      )}
                      {balance.valid && balance.totalDebit > 0 && (
                        <Tag color="green">Balancerer</Tag>
                      )}
                    </td>
                  </tr>
                </tfoot>
              </table>
            </div>
          </Space>
        </Form>
      </Modal>
    </div>
  );
}
