import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import {
  Card,
  Form,
  InputNumber,
  Select,
  Button,
  Row,
  Col,
  Typography,
  Statistic,
  Table,
  Space,
  message,
  Grid,
  Alert
} from 'antd';
import {
  CalculatorOutlined,
  ClearOutlined,
  DownloadOutlined,
  PrinterOutlined
} from '@ant-design/icons';
import { useApi } from '@/hooks/useApi';
import { LoanCalculationsService } from '@/services/loanCalculations';
import { parseError } from '@/utils/errorHandler';
import { useAppContext } from '@/store/AppStore';

const { Title, Text } = Typography;
const { useBreakpoint } = Grid;

interface LoanCalculation {
  id: string;
  principal_amount: number;
  annual_interest_rate: number;
  loan_term_months: number;
  monthly_payment: number;
  total_amount_paid: number;
  total_interest_paid: number;
  created_at?: string;
  updated_at?: string;
}

interface AmortizationScheduleEntry {
  paymentNumber: number;
  paymentAmount: number;
  principalPortion: number;
  interestPortion: number;
  remainingBalance: number;
}

interface LoanCalculationWithSchedule extends LoanCalculation {
  amortization_schedule_entries?: Array<{
    payment_number?: number;
    payment_amount?: number;
    principal_portion?: number;
    interest_portion?: number;
    remaining_balance?: number;
  }>;
}

const formatCurrency = (value: number): string => {
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  }).format(value);
};

const LoanCalculatorPage = () => {
  const [messageApi, contextHolder] = message.useMessage();
  const [form] = Form.useForm();
  const screens = useBreakpoint();

  const { loanCalculation, setLoanCalculation } = useAppContext();

  const [termUnit, setTermUnit] = useState<'years' | 'months'>('years');
  const [calculationPerformed, setCalculationPerformed] = useState(false);
  const [isCalculating, setIsCalculating] = useState(false);
  const [scheduleCurrentPage, setScheduleCurrentPage] = useState(1);
  const [scheduleData, setScheduleData] = useState<AmortizationScheduleEntry[]>([]);

  const { execute: createCalculation } = useApi<LoanCalculation>(LoanCalculationsService.create);
  const { execute: fetchDetails } = useApi<LoanCalculationWithSchedule>(LoanCalculationsService.getDetails);

  const interestPercentOfPrincipal = useMemo(() => {
    if (loanCalculation && loanCalculation.total_interest_paid && loanCalculation.principal_amount) {
      const percent = ((loanCalculation.total_interest_paid / loanCalculation.principal_amount) * 100).toFixed(1);
      return `${percent}% of loan amount`;
    }
    return '';
  }, [loanCalculation]);

  const hasResults = useMemo(() => {
    return calculationPerformed && loanCalculation !== null;
  }, [calculationPerformed, loanCalculation]);

  const onTermUnitChange = useCallback((value: 'years' | 'months') => {
    setTermUnit(value);
  }, []);

  const onSchedulePageChange = useCallback((page: number) => {
    setScheduleCurrentPage(page);
  }, []);

  const calculateLoan = async () => {
    try {
      const values = await form.validateFields();
      setIsCalculating(true);

      const loanTermMonths = termUnit === 'years' ? values.loan_term * 12 : values.loan_term;

      const response = await createCalculation({
        principal_amount: values.principal_amount,
        annual_interest_rate: values.annual_interest_rate,
        loan_term_months: loanTermMonths
      });

      if (response?.data) {
        setLoanCalculation(response.data);
        setCalculationPerformed(true);
        messageApi.success('Loan calculation complete!');

        if (response.data.id) {
          const detailsResponse = await fetchDetails(response.data.id);
          if (detailsResponse?.data?.amortization_schedule_entries) {
            const entries: AmortizationScheduleEntry[] = detailsResponse.data.amortization_schedule_entries.map((entry) => ({
              paymentNumber: entry.payment_number ?? 0,
              paymentAmount: entry.payment_amount ?? 0,
              principalPortion: entry.principal_portion ?? 0,
              interestPortion: entry.interest_portion ?? 0,
              remainingBalance: entry.remaining_balance ?? 0
            }));
            setScheduleData(entries);
          }
        }
      }
    } catch (e) {
      const { message: errorMsg } = parseError(e);
      messageApi.error(errorMsg || 'Failed to calculate loan. Please check your inputs and try again.');
    } finally {
      setIsCalculating(false);
    }
  };

  const resetCalculator = useCallback(() => {
    setCalculationPerformed(false);
    setIsCalculating(false);
    setScheduleCurrentPage(1);
    setTermUnit('years');
    setScheduleData([]);
    setLoanCalculation(null);
    form.resetFields();
    messageApi.success('Calculator reset.');
  }, [form, messageApi, setLoanCalculation]);

  const exportCSV = useCallback(() => {
    try {
      if (!scheduleData || scheduleData.length === 0) {
        messageApi.error('No schedule data to export.');
        return;
      }

      const headers = ['Payment #', 'Payment Amount', 'Principal', 'Interest', 'Remaining Balance'];
      const rows = scheduleData.map((entry) => [
        entry.paymentNumber,
        entry.paymentAmount.toFixed(2),
        entry.principalPortion.toFixed(2),
        entry.interestPortion.toFixed(2),
        entry.remainingBalance.toFixed(2)
      ]);

      const csvContent = [
        headers.join(','),
        ...rows.map((row) => row.join(','))
      ].join('\n');

      const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
      const link = document.createElement('a');
      const url = URL.createObjectURL(blob);
      link.setAttribute('href', url);
      link.setAttribute('download', 'amortization_schedule.csv');
      link.style.visibility = 'hidden';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);

      messageApi.success('CSV exported successfully!');
    } catch (e) {
      const { message: errorMsg } = parseError(e);
      messageApi.error(errorMsg || 'Failed to export CSV.');
    }
  }, [scheduleData, messageApi]);

  const printSchedule = useCallback(() => {
    window.print();
  }, []);

  const columns = useMemo(() => [
    {
      title: 'Payment #',
      dataIndex: 'paymentNumber',
      key: 'paymentNumber',
      width: 100,
      align: 'center' as const
    },
    {
      title: 'Payment Amount',
      dataIndex: 'paymentAmount',
      key: 'paymentAmount',
      align: 'right' as const,
      render: (value: number) => formatCurrency(value)
    },
    {
      title: 'Principal',
      dataIndex: 'principalPortion',
      key: 'principalPortion',
      align: 'right' as const,
      render: (value: number) => formatCurrency(value)
    },
    {
      title: 'Interest',
      dataIndex: 'interestPortion',
      key: 'interestPortion',
      align: 'right' as const,
      render: (value: number) => formatCurrency(value)
    },
    {
      title: 'Remaining Balance',
      dataIndex: 'remainingBalance',
      key: 'remainingBalance',
      align: 'right' as const,
      render: (value: number) => formatCurrency(value)
    }
  ], []);

  const containerPadding = screens.xs ? 12 : 24;
  const titleFontSize = screens.xs ? 18 : 24;

  return (
    <div style={{ minHeight: '100vh', width: '100%', backgroundColor: '#f5f7fa', padding: containerPadding }}>
      {contextHolder}
      <div style={{ maxWidth: '960px', margin: '0 auto', width: '100%' }}>
        <Title level={2} style={{ textAlign: 'center', marginBottom: '8px', color: '#1a1a1a', fontSize: titleFontSize }}>
          Loan Calculator
        </Title>
        <Text type="secondary" style={{ textAlign: 'center', display: 'block', marginBottom: '32px', fontSize: '16px' }}>
          Calculate your monthly payments, total cost, and view a detailed amortization schedule.
        </Text>

        <Card
          title="Loan Details"
          bordered
          style={{ marginBottom: '24px', borderRadius: '8px', boxShadow: '0 2px 8px rgba(0,0,0,0.06)' }}
        >
          <Form form={form} layout="vertical" requiredMark onFinish={calculateLoan}>
            <Row gutter={[24, 16]}>
              <Col xs={24} sm={24} md={8}>
                <Form.Item
                  name="principal_amount"
                  label="Principal Amount"
                  rules={[
                    { required: true, message: 'Principal amount is required' },
                    { type: 'number', min: 1, max: 100000000, message: 'Principal must be between $1 and $100,000,000' }
                  ]}
                  tooltip="The total amount of money you are borrowing from the lender."
                >
                  <InputNumber
                    prefix="$"
                    placeholder="250,000"
                    min={1}
                    max={100000000}
                    formatter={(value) => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
                    parser={(value) => (value ?? '').replace(/\$\s?|(,*)/g, '')}
                    inputMode="decimal"
                    aria-label="Principal Amount"
                    style={{ width: '100%' }}
                  />
                </Form.Item>
              </Col>

              <Col xs={24} sm={24} md={8}>
                <Form.Item
                  name="annual_interest_rate"
                  label="Annual Interest Rate"
                  rules={[
                    { required: true, message: 'Annual interest rate is required' },
                    { type: 'number', min: 0.01, max: 99.99, message: 'Rate must be between 0.01% and 99.99%' }
                  ]}
                  tooltip="The annual percentage rate (APR) charged by the lender on your loan balance."
                >
                  <InputNumber
                    suffix="%"
                    placeholder="6.5"
                    min={0.01}
                    max={99.99}
                    step={0.01}
                    precision={2}
                    inputMode="decimal"
                    aria-label="Annual Interest Rate"
                    style={{ width: '100%' }}
                  />
                </Form.Item>
              </Col>

              <Col xs={24} sm={24} md={8}>
                <Form.Item
                  name="loan_term"
                  label="Loan Term"
                  rules={[
                    { required: true, message: 'Loan term is required' },
                    { type: 'number', min: 1, message: 'Loan term must be at least 1' }
                  ]}
                  tooltip="The length of time over which you will repay the loan. Toggle between years and months."
                >
                  <Space.Compact block style={{ width: '100%' }}>
                    <InputNumber
                      placeholder="30"
                      min={1}
                      max={termUnit === 'years' ? 50 : 600}
                      step={1}
                      precision={0}
                      inputMode="numeric"
                      aria-label="Loan Term"
                      style={{ width: '70%' }}
                    />
                    <Select
                      defaultValue="years"
                      value={termUnit}
                      options={[
                        { label: 'Years', value: 'years' },
                        { label: 'Months', value: 'months' }
                      ]}
                      onChange={onTermUnitChange}
                      aria-label="Term Unit"
                      style={{ width: '30%' }}
                    />
                  </Space.Compact>
                </Form.Item>
              </Col>
            </Row>

            <Row gutter={16} justify="end" style={{ marginTop: '24px' }}>
              <Col>
                <Button
                  htmlType="button"
                  icon={<ClearOutlined />}
                  size="large"
                  onClick={resetCalculator}
                  style={{ minWidth: '120px' }}
                >
                  Reset
                </Button>
              </Col>
              <Col>
                <Button
                  type="primary"
                  htmlType="submit"
                  icon={<CalculatorOutlined />}
                  size="large"
                  loading={isCalculating}
                  style={{ minWidth: '160px', fontWeight: 600 }}
                >
                  Calculate
                </Button>
              </Col>
            </Row>
          </Form>
        </Card>

        {hasResults && (
          <div style={{ marginBottom: '24px' }}>
            <Title level={4} style={{ marginBottom: '16px' }}>
              Calculation Results
            </Title>
            <Row gutter={[24, 16]}>
              <Col xs={24} sm={24} md={8}>
                <Card
                  bordered
                  style={{
                    borderRadius: '8px',
                    textAlign: 'center',
                    borderTop: '3px solid #1677ff',
                    boxShadow: '0 2px 8px rgba(0,0,0,0.06)'
                  }}
                >
                  <Text type="secondary" style={{ display: 'block', fontSize: '14px', marginBottom: '8px' }}>
                    Monthly Payment
                  </Text>
                  <Statistic
                    value={loanCalculation?.monthly_payment ?? 0}
                    prefix="$"
                    precision={2}
                    valueStyle={{ fontSize: '32px', fontWeight: 700, color: '#1677ff' }}
                  />
                </Card>
              </Col>

              <Col xs={24} sm={12} md={8}>
                <Card
                  bordered
                  style={{
                    borderRadius: '8px',
                    textAlign: 'center',
                    boxShadow: '0 2px 8px rgba(0,0,0,0.06)'
                  }}
                >
                  <Text type="secondary" style={{ display: 'block', fontSize: '14px', marginBottom: '8px' }}>
                    Total Amount Paid
                  </Text>
                  <Statistic
                    value={loanCalculation?.total_amount_paid ?? 0}
                    prefix="$"
                    precision={2}
                    valueStyle={{ fontSize: '24px', fontWeight: 600, color: '#1a1a1a' }}
                  />
                </Card>
              </Col>

              <Col xs={24} sm={12} md={8}>
                <Card
                  bordered
                  style={{
                    borderRadius: '8px',
                    textAlign: 'center',
                    boxShadow: '0 2px 8px rgba(0,0,0,0.06)'
                  }}
                >
                  <Text type="secondary" style={{ display: 'block', fontSize: '14px', marginBottom: '4px' }}>
                    Total Interest Paid
                  </Text>
                  <Statistic
                    value={loanCalculation?.total_interest_paid ?? 0}
                    prefix="$"
                    precision={2}
                    valueStyle={{ fontSize: '24px', fontWeight: 600, color: '#cf1322' }}
                  />
                  <Text
                    type="secondary"
                    style={{ display: 'block', fontSize: '12px', marginTop: '4px', color: '#8c8c8c' }}
                  >
                    {interestPercentOfPrincipal}
                  </Text>
                </Card>
              </Col>
            </Row>
          </div>
        )}

        {hasResults && (
          <div style={{ marginBottom: '24px' }}>
            <Card bordered style={{ borderRadius: '8px', boxShadow: '0 2px 8px rgba(0,0,0,0.06)' }}>
              <div
                style={{
                  display: 'flex',
                  justifyContent: 'space-between',
                  alignItems: 'center',
                  marginBottom: '16px',
                  flexWrap: 'wrap',
                  gap: '12px'
                }}
              >
                <Title level={4} style={{ margin: 0 }}>
                  Amortization Schedule
                </Title>
                <Space size="middle">
                  <Button
                    icon={<DownloadOutlined />}
                    size="middle"
                    onClick={exportCSV}
                    aria-label="Export amortization schedule as CSV"
                  >
                    Export CSV
                  </Button>
                  <Button
                    icon={<PrinterOutlined />}
                    size="middle"
                    onClick={printSchedule}
                    aria-label="Print amortization schedule"
                  >
                    Print
                  </Button>
                </Space>
              </div>
              <Table
                columns={columns}
                dataSource={scheduleData}
                rowKey="paymentNumber"
                pagination={{
                  pageSize: 12,
                  current: scheduleCurrentPage,
                  onChange: onSchedulePageChange,
                  showSizeChanger: false,
                  showTotal: (total, range) => `${range[0]}-${range[1]} of ${total} payments`
                }}
                size={screens.xs ? 'small' : 'middle'}
                bordered={false}
                scroll={{ x: 'max-content' }}
                aria-label="Amortization Schedule Table"
              />
            </Card>
          </div>
        )}

        <Text
          type="secondary"
          style={{
            display: 'block',
            textAlign: 'center',
            marginTop: '32px',
            fontSize: '12px',
            color: '#8c8c8c'
          }}
        >
          This calculator provides estimates for informational purposes only. Actual loan terms may vary.
        </Text>
      </div>
    </div>
  );
};

export default LoanCalculatorPage;