// BalanceImpactPanel - Shows the balance impact of journal entry draft lines

import { useMemo } from 'react';
import { Collapse, Table, Typography, Badge, Spin, Alert, Space } from 'antd';
import { FundViewOutlined, CheckCircleOutlined, WarningOutlined } from '@ant-design/icons';
import type { ColumnsType } from 'antd/es/table';
import { useAccountBalances } from '@/api/queries/accountQueries';
import { AmountText } from '@/components/shared/AmountText';
import { spacing } from '@/styles/designTokens';
import type { Account } from '@/types/accounting';

const { Text } = Typography;

// Matches the EditableLine interface from Kassekladde.tsx
interface EditableLine {
  lineNumber: number;
  accountId?: string;
  debitAmount: number;
  creditAmount: number;
  description?: string;
  vatCode?: string;
}

interface AccountImpact {
  accountId: string;
  accountNumber: string;
  accountName: string;
  currentBalance: number;
  debitChange: number;
  creditChange: number;
  netChange: number;
  newBalance: number;
}

interface BalanceImpactPanelProps {
  lines: EditableLine[];
  accounts: Account[];
  companyId: string;
  defaultOpen?: boolean;
}

/**
 * Panel that displays the balance impact on accounts affected by journal entry lines.
 * Shows current balance, change, and projected new balance for each affected account.
 */
export function BalanceImpactPanel({
  lines,
  accounts,
  companyId,
  defaultOpen = true,
}: BalanceImpactPanelProps) {
  // Fetch current account balances (no date filter = all time accumulated)
  const { data: accountBalances, isLoading, error } = useAccountBalances(companyId);

  // Calculate impacts for each affected account
  const { impacts, totals, isBalanced } = useMemo(() => {
    // Find all unique account IDs from lines
    const affectedAccountIds = new Set(
      lines.filter((l) => l.accountId).map((l) => l.accountId!)
    );

    if (affectedAccountIds.size === 0) {
      return { impacts: [], totals: { debit: 0, credit: 0 }, isBalanced: true };
    }

    const calculatedImpacts: AccountImpact[] = [];
    let totalDebit = 0;
    let totalCredit = 0;

    for (const accountId of affectedAccountIds) {
      const account = accounts.find((a) => a.id === accountId);
      if (!account) continue;

      // Get current balance from the balances query
      const balanceData = accountBalances?.find((b) => b.id === accountId);
      const currentBalance = balanceData?.netChange ?? 0;

      // Sum up all changes for this account from the draft lines
      const linesForAccount = lines.filter((l) => l.accountId === accountId);
      const debitChange = linesForAccount.reduce((sum, l) => sum + (l.debitAmount || 0), 0);
      const creditChange = linesForAccount.reduce((sum, l) => sum + (l.creditAmount || 0), 0);
      const netChange = debitChange - creditChange;

      totalDebit += debitChange;
      totalCredit += creditChange;

      calculatedImpacts.push({
        accountId,
        accountNumber: account.accountNumber,
        accountName: account.name,
        currentBalance,
        debitChange,
        creditChange,
        netChange,
        newBalance: currentBalance + netChange,
      });
    }

    // Sort by account number
    calculatedImpacts.sort((a, b) => a.accountNumber.localeCompare(b.accountNumber));

    return {
      impacts: calculatedImpacts,
      totals: { debit: totalDebit, credit: totalCredit },
      isBalanced: Math.abs(totalDebit - totalCredit) < 0.01,
    };
  }, [lines, accounts, accountBalances]);

  // Don't render if no lines with accounts
  if (lines.length === 0 || !lines.some((l) => l.accountId)) {
    return null;
  }

  const columns: ColumnsType<AccountImpact> = [
    {
      title: 'Konto',
      key: 'account',
      render: (_, record) => (
        <span>
          <Text strong>{record.accountNumber}</Text>
          <Text style={{ marginLeft: spacing.sm }}>{record.accountName}</Text>
        </span>
      ),
    },
    {
      title: 'Aktuel saldo',
      dataIndex: 'currentBalance',
      key: 'currentBalance',
      align: 'right',
      width: 140,
      render: (value: number) => (
        <AmountText amount={value} type="neutral" showCurrency={false} />
      ),
    },
    {
      title: 'Ændring',
      key: 'change',
      align: 'right',
      width: 140,
      render: (_, record) => (
        <AmountText
          amount={record.netChange}
          type="auto"
          showSign
          showCurrency={false}
        />
      ),
    },
    {
      title: 'Ny saldo',
      dataIndex: 'newBalance',
      key: 'newBalance',
      align: 'right',
      width: 140,
      render: (value: number) => (
        <AmountText amount={value} type="auto" showCurrency={false} style={{ fontWeight: 600 }} />
      ),
    },
  ];

  const panelHeader = (
    <Space>
      <FundViewOutlined />
      <span>Konsekvens på konti</span>
      <Badge
        count={impacts.length}
        style={{ backgroundColor: '#1677ff' }}
        title={`${impacts.length} konti påvirket`}
      />
      {isBalanced ? (
        <CheckCircleOutlined style={{ color: '#52c41a', marginLeft: spacing.sm }} />
      ) : (
        <WarningOutlined style={{ color: '#faad14', marginLeft: spacing.sm }} />
      )}
    </Space>
  );

  return (
    <Collapse
      defaultActiveKey={defaultOpen ? ['impact'] : []}
      style={{ marginTop: spacing.md }}
      items={[
        {
          key: 'impact',
          label: panelHeader,
          children: (
            <>
              {error && (
                <Alert
                  type="warning"
                  message="Kunne ikke hente aktuelle saldi"
                  description="Ændringer vises stadig, men aktuelle saldi er ikke tilgængelige."
                  style={{ marginBottom: spacing.md }}
                />
              )}

              <Spin spinning={isLoading}>
                <Table
                  dataSource={impacts}
                  columns={columns}
                  rowKey="accountId"
                  pagination={false}
                  size="small"
                  bordered
                  summary={() => (
                    <Table.Summary fixed>
                      <Table.Summary.Row>
                        <Table.Summary.Cell index={0}>
                          <Text strong>Total ændring</Text>
                        </Table.Summary.Cell>
                        <Table.Summary.Cell index={1} align="right">
                          {/* Empty - no total for current balance */}
                        </Table.Summary.Cell>
                        <Table.Summary.Cell index={2} align="right">
                          <Space size={4}>
                            <Text type="secondary">D:</Text>
                            <AmountText
                              amount={totals.debit}
                              type="debit"
                              showCurrency={false}
                              style={{ fontWeight: 600 }}
                            />
                            <Text type="secondary" style={{ marginLeft: spacing.xs }}>/</Text>
                            <Text type="secondary">K:</Text>
                            <AmountText
                              amount={totals.credit}
                              type="credit"
                              showCurrency={false}
                              style={{ fontWeight: 600 }}
                            />
                          </Space>
                        </Table.Summary.Cell>
                        <Table.Summary.Cell index={3} align="right">
                          {isBalanced ? (
                            <Text style={{ color: '#52c41a' }}>
                              <CheckCircleOutlined style={{ marginRight: 4 }} />
                              Balancerer
                            </Text>
                          ) : (
                            <Text style={{ color: '#faad14' }}>
                              <WarningOutlined style={{ marginRight: 4 }} />
                              Difference: {(totals.debit - totals.credit).toFixed(2)}
                            </Text>
                          )}
                        </Table.Summary.Cell>
                      </Table.Summary.Row>
                    </Table.Summary>
                  )}
                />
              </Spin>
            </>
          ),
        },
      ]}
    />
  );
}

export default BalanceImpactPanel;
