import { useState, useMemo, useEffect, useCallback } from 'react';
import { Layout, Typography, Button, Row, Col, Card, Statistic, Tabs, Table, Modal, Form, InputNumber, Select, Input, Alert, message } from 'antd';
import { ArrowLeftOutlined, PlusOutlined, DollarOutlined } from '@ant-design/icons';
import { request } from '../api/client';
import { useNavigate } from 'react-router-dom';
import { useAppContext } from '../store/AppContext';

interface FineResponse {
  id: string;
  member_id: string;
  loan_id: string | null;
  amount: string;
  reason: string;
  issue_date: string;
  payment_status: 'UNPAID' | 'PARTIALLY_PAID' | 'PAID' | 'WAIVED';
  payment_date: string | null;
  amount_paid: string;
  waived_by_librarian_id: string | null;
  waived_reason: string | null;
  created_at: string;
  updated_at: string;
}

interface PaymentResponse {
  id: string;
  member_id: string;
  fine_id: string | null;
  amount: string;
  payment_method: 'CASH' | 'CREDIT_CARD' | 'DEBIT_CARD' | 'ONLINE' | 'CHECK';
  transaction_date: string;
  reference_number: string | null;
  processed_by_librarian_id: string | null;
  notes: string | null;
  created_at: string;
  updated_at: string;
}

interface MemberResponse {
  id: string;
  membership_number: string;
  user: {
    id: string;
    email: string;
    first_name: string;
    last_name: string;
  };
}

interface LoanResponse {
  id: string;
  member_id: string;
  book_copy_id: string;
  checkout_date: string;
  due_date: string;
  status: 'ACTIVE' | 'RETURNED' | 'OVERDUE' | 'LOST';
}

export default function FinesManagementPage() {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();
  const { currentUser } = useAppContext();

  const [fines, setFines] = useState<FineResponse[]>([]);
  const [payments, setPayments] = useState<PaymentResponse[]>([]);
  const [activeTab, setActiveTab] = useState<string>('outstanding');
  const [filterPaymentStatus, setFilterPaymentStatus] = useState<string>('UNPAID');
  const [selectedFineId, setSelectedFineId] = useState<string | null>(null);
  const [recordPaymentModalVisible, setRecordPaymentModalVisible] = useState<boolean>(false);
  const [waiveFineModalVisible, setWaiveFineModalVisible] = useState<boolean>(false);
  const [createFineModalVisible, setCreateFineModalVisible] = useState<boolean>(false);
  const [loading, setLoading] = useState<boolean>(false);
  const [members, setMembers] = useState<MemberResponse[]>([]);
  const [loans, setLoans] = useState<LoanResponse[]>([]);

  const [recordPaymentForm] = Form.useForm();
  const [waiveFineForm] = Form.useForm();
  const [createFineForm] = Form.useForm();

  const outstandingFines = useMemo(() => {
    return fines.filter(f => f.payment_status === 'UNPAID' || f.payment_status === 'PARTIALLY_PAID');
  }, [fines]);

  const totalOutstanding = useMemo(() => {
    return fines
      .filter(f => f.payment_status === 'UNPAID' || f.payment_status === 'PARTIALLY_PAID')
      .reduce((sum, f) => sum + (Number(f.amount) - Number(f.amount_paid || 0)), 0);
  }, [fines]);

  const collectedToday = useMemo(() => {
    return payments
      .filter(p => new Date(p.transaction_date).toDateString() === new Date().toDateString())
      .reduce((sum, p) => sum + Number(p.amount), 0);
  }, [payments]);

  const collectedThisMonth = useMemo(() => {
    return payments
      .filter(p => {
        const d = new Date(p.transaction_date);
        const now = new Date();
        return d.getMonth() === now.getMonth() && d.getFullYear() === now.getFullYear();
      })
      .reduce((sum, p) => sum + Number(p.amount), 0);
  }, [payments]);

  const fetchFines = useCallback(async () => {
    try {
      const result = await request<FineResponse[]>({
        method: 'GET',
        path: '/fines/',
        query: { limit: 100 }
      });
      setFines(result.data);
    } catch (error) {
      messageApi.error('Failed to load fines');
    }
  }, [messageApi]);

  const fetchPayments = useCallback(async () => {
    try {
      const result = await request<PaymentResponse[]>({
        method: 'GET',
        path: '/fines/payments',
        query: { limit: 100 }
      });
      setPayments(result.data);
    } catch (error) {
      messageApi.error('Failed to load payments');
    }
  }, [messageApi]);

  const fetchMembers = useCallback(async () => {
    try {
      const result = await request<MemberResponse[]>({
        method: 'GET',
        path: '/auth/members',
        query: { limit: 100 }
      });
      setMembers(result.data);
    } catch (error) {
      messageApi.error('Failed to load members');
    }
  }, [messageApi]);

  const fetchLoans = useCallback(async () => {
    try {
      const result = await request<LoanResponse[]>({
        method: 'GET',
        path: '/loans/',
        query: { limit: 100 }
      });
      setLoans(result.data);
    } catch (error) {
      messageApi.error('Failed to load loans');
    }
  }, [messageApi]);

  useEffect(() => {
    fetchFines();
    fetchPayments();
    fetchMembers();
    fetchLoans();
  }, [fetchFines, fetchPayments, fetchMembers, fetchLoans]);

  const navigateToDashboard = useCallback(() => {
    navigate('/staff/dashboard');
  }, [navigate]);

  const openRecordPaymentModal = useCallback((fineId: string) => {
    setSelectedFineId(fineId);
    setRecordPaymentModalVisible(true);
  }, []);

  const closeRecordPaymentModal = useCallback(() => {
    setRecordPaymentModalVisible(false);
    setSelectedFineId(null);
    recordPaymentForm.resetFields();
  }, [recordPaymentForm]);

  const openWaiveFineModal = useCallback((fineId: string) => {
    setSelectedFineId(fineId);
    setWaiveFineModalVisible(true);
  }, []);

  const closeWaiveFineModal = useCallback(() => {
    setWaiveFineModalVisible(false);
    setSelectedFineId(null);
    waiveFineForm.resetFields();
  }, [waiveFineForm]);

  const openCreateFineModal = useCallback(() => {
    setCreateFineModalVisible(true);
  }, []);

  const closeCreateFineModal = useCallback(() => {
    setCreateFineModalVisible(false);
    createFineForm.resetFields();
  }, [createFineForm]);

  const handleRecordPayment = useCallback(async () => {
    try {
      const values = await recordPaymentForm.validateFields();
      
      if (!values.amount || values.amount <= 0) {
        messageApi.error('Amount must be greater than 0');
        return;
      }
      if (!values.payment_method) {
        messageApi.error('Payment method is required');
        return;
      }

      const selectedFine = fines.find(f => f.id === selectedFineId);
      if (!selectedFine) {
        messageApi.error('Fine not found');
        return;
      }

      setLoading(true);
      await request<PaymentResponse>({
        method: 'POST',
        path: '/fines/payments',
        body: {
          member_id: selectedFine.member_id,
          fine_id: selectedFineId,
          amount: values.amount,
          payment_method: values.payment_method,
          transaction_date: new Date().toISOString(),
          reference_number: values.reference_number || null,
          processed_by_librarian_id: currentUser?.id || null,
          notes: values.notes || null
        }
      });

      messageApi.success('Payment recorded successfully');
      setRecordPaymentModalVisible(false);
      setSelectedFineId(null);
      recordPaymentForm.resetFields();
      fetchFines();
      fetchPayments();
    } catch (error) {
      messageApi.error('Failed to record payment');
    } finally {
      setLoading(false);
    }
  }, [recordPaymentForm, selectedFineId, fines, currentUser, messageApi, fetchFines, fetchPayments]);

  const handleWaiveFine = useCallback(async () => {
    try {
      const values = await waiveFineForm.validateFields();
      
      if (!values.waived_reason) {
        messageApi.error('Reason for waiving is required');
        return;
      }

      Modal.confirm({
        title: 'Confirm Waive Fine',
        content: 'Are you sure you want to waive this fine? This action cannot be undone.',
        onOk: async () => {
          try {
            setLoading(true);
            await request<FineResponse>({
              method: 'POST',
              path: '/fines/{fine_id}/waive',
              pathParams: { fine_id: selectedFineId || '' },
              query: {
                librarian_id: currentUser?.id || '',
                reason: values.waived_reason
              }
            });

            messageApi.success('Fine waived successfully');
            setWaiveFineModalVisible(false);
            setSelectedFineId(null);
            waiveFineForm.resetFields();
            fetchFines();
          } catch (error) {
            messageApi.error('Failed to waive fine');
          } finally {
            setLoading(false);
          }
        }
      });
    } catch (error) {
      messageApi.error('Validation failed');
    }
  }, [waiveFineForm, selectedFineId, currentUser, messageApi, fetchFines]);

  const handleCreateFine = useCallback(async () => {
    try {
      const values = await createFineForm.validateFields();
      
      if (!values.member_id) {
        messageApi.error('Member is required');
        return;
      }
      if (!values.amount || values.amount <= 0) {
        messageApi.error('Amount must be greater than 0');
        return;
      }
      if (!values.reason) {
        messageApi.error('Reason is required');
        return;
      }

      setLoading(true);
      await request<FineResponse>({
        method: 'POST',
        path: '/fines/',
        body: {
          member_id: values.member_id,
          loan_id: values.loan_id || null,
          amount: values.amount,
          reason: values.reason,
          issue_date: new Date().toISOString().split('T')[0],
          payment_status: 'UNPAID',
          amount_paid: 0
        }
      });

      messageApi.success('Fine created successfully');
      setCreateFineModalVisible(false);
      createFineForm.resetFields();
      fetchFines();
    } catch (error) {
      messageApi.error('Failed to create fine');
    } finally {
      setLoading(false);
    }
  }, [createFineForm, messageApi, fetchFines]);

  const outstandingFinesColumns = useMemo(() => [
    {
      title: 'Fine ID',
      dataIndex: 'id',
      key: 'id',
      ellipsis: true,
      width: 120
    },
    {
      title: 'Member',
      dataIndex: 'member_id',
      key: 'member_id'
    },
    {
      title: 'Type',
      dataIndex: 'reason',
      key: 'reason'
    },
    {
      title: 'Amount',
      dataIndex: 'amount',
      key: 'amount',
      render: (amount: string) => `$${Number(amount).toFixed(2)}`
    },
    {
      title: 'Issue Date',
      dataIndex: 'issue_date',
      key: 'issue_date'
    },
    {
      title: 'Related Loan',
      dataIndex: 'loan_id',
      key: 'loan_id',
      render: (loan_id: string | null) => loan_id || '-'
    },
    {
      title: 'Status',
      dataIndex: 'payment_status',
      key: 'payment_status',
      render: (status: string) => status
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, record: FineResponse) => (
        <div style={{ display: 'flex', gap: '8px' }}>
          <Button size="small" onClick={() => openRecordPaymentModal(record.id)}>
            Record Payment
          </Button>
          <Button size="small" onClick={() => openWaiveFineModal(record.id)}>
            Waive
          </Button>
        </div>
      )
    }
  ], [openRecordPaymentModal, openWaiveFineModal]);

  const paymentsColumns = useMemo(() => [
    {
      title: 'Payment ID',
      dataIndex: 'id',
      key: 'id',
      ellipsis: true,
      width: 120
    },
    {
      title: 'Member',
      dataIndex: 'member_id',
      key: 'member_id'
    },
    {
      title: 'Amount',
      dataIndex: 'amount',
      key: 'amount',
      render: (amount: string) => `$${Number(amount).toFixed(2)}`
    },
    {
      title: 'Method',
      dataIndex: 'payment_method',
      key: 'payment_method'
    },
    {
      title: 'Date',
      dataIndex: 'transaction_date',
      key: 'transaction_date',
      render: (date: string) => new Date(date).toLocaleDateString()
    },
    {
      title: 'Transaction Reference',
      dataIndex: 'reference_number',
      key: 'reference_number',
      render: (ref: string | null) => ref || '-'
    },
    {
      title: 'Fine Covered',
      dataIndex: 'fine_id',
      key: 'fine_id',
      render: (fine_id: string | null) => fine_id || '-'
    }
  ], []);

  const allFinesColumns = useMemo(() => [
    {
      title: 'Fine ID',
      dataIndex: 'id',
      key: 'id',
      ellipsis: true,
      width: 120
    },
    {
      title: 'Member',
      dataIndex: 'member_id',
      key: 'member_id'
    },
    {
      title: 'Type',
      dataIndex: 'reason',
      key: 'reason'
    },
    {
      title: 'Amount',
      dataIndex: 'amount',
      key: 'amount',
      render: (amount: string) => `$${Number(amount).toFixed(2)}`
    },
    {
      title: 'Amount Paid',
      dataIndex: 'amount_paid',
      key: 'amount_paid',
      render: (amount: string) => `$${Number(amount || 0).toFixed(2)}`
    },
    {
      title: 'Issue Date',
      dataIndex: 'issue_date',
      key: 'issue_date'
    },
    {
      title: 'Status',
      dataIndex: 'payment_status',
      key: 'payment_status'
    },
    {
      title: 'Related Loan',
      dataIndex: 'loan_id',
      key: 'loan_id',
      render: (loan_id: string | null) => loan_id || '-'
    }
  ], []);

  const memberOptions = useMemo(() => {
    return members.map(m => ({
      label: `${m.user.first_name} ${m.user.last_name} (${m.membership_number})`,
      value: m.id
    }));
  }, [members]);

  const loanOptions = useMemo(() => {
    return loans.map(l => ({
      label: `Loan ${l.id} - Member ${l.member_id}`,
      value: l.id
    }));
  }, [loans]);

  const tabItems = [
    {
      key: 'outstanding',
      label: 'Outstanding Fines',
      children: (
        <Table
          columns={outstandingFinesColumns}
          dataSource={outstandingFines}
          rowKey="id"
          pagination={{ pageSize: 10 }}
          size="middle"
          loading={loading}
        />
      )
    },
    {
      key: 'payments',
      label: 'Payments',
      children: (
        <Table
          columns={paymentsColumns}
          dataSource={payments}
          rowKey="id"
          pagination={{ pageSize: 10 }}
          size="middle"
          loading={loading}
        />
      )
    },
    {
      key: 'all',
      label: 'All Fines',
      children: (
        <Table
          columns={allFinesColumns}
          dataSource={fines}
          rowKey="id"
          pagination={{ pageSize: 10 }}
          size="middle"
          loading={loading}
        />
      )
    }
  ];

  return (
    <div style={{ minHeight: '100vh', height: '100%', width: '100%', display: 'flex', flexDirection: 'column', padding: '24px', background: '#f5f5f5' }}>
      {contextHolder}
      
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '24px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
          <Button type="text" icon={<ArrowLeftOutlined />} onClick={navigateToDashboard}>
            Back to Dashboard
          </Button>
          <Typography.Title level={2} style={{ margin: 0 }}>
            Fines & Payments
          </Typography.Title>
        </div>
        <Button type="primary" icon={<PlusOutlined />} onClick={openCreateFineModal}>
          Create Fine
        </Button>
      </div>

      <Row gutter={[16, 16]} style={{ marginBottom: '24px' }}>
        <Col xs={24} sm={8}>
          <Card>
            <Statistic
              title="Total Outstanding"
              value={totalOutstanding}
              prefix="$"
              precision={2}
              valueStyle={{ color: '#cf1322' }}
            />
          </Card>
        </Col>
        <Col xs={24} sm={8}>
          <Card>
            <Statistic
              title="Collected Today"
              value={collectedToday}
              prefix="$"
              precision={2}
              valueStyle={{ color: '#3f8600' }}
            />
          </Card>
        </Col>
        <Col xs={24} sm={8}>
          <Card>
            <Statistic
              title="Collected This Month"
              value={collectedThisMonth}
              prefix="$"
              precision={2}
              valueStyle={{ color: '#1677ff' }}
            />
          </Card>
        </Col>
      </Row>

      <Tabs
        activeKey={activeTab}
        onChange={setActiveTab}
        items={tabItems}
      />

      <Modal
        title="Record Payment"
        open={recordPaymentModalVisible}
        onCancel={closeRecordPaymentModal}
        onOk={handleRecordPayment}
        width={520}
        destroyOnClose
        confirmLoading={loading}
      >
        <Form form={recordPaymentForm} layout="vertical">
          <Form.Item
            label="Amount"
            name="amount"
            rules={[{ required: true, message: 'Amount is required' }]}
          >
            <InputNumber
              min={0.01}
              precision={2}
              prefix="$"
              style={{ width: '100%' }}
              placeholder="Enter payment amount"
            />
          </Form.Item>
          <Form.Item
            label="Payment Method"
            name="payment_method"
            rules={[{ required: true, message: 'Payment method is required' }]}
          >
            <Select
              placeholder="Select payment method"
              options={[
                { label: 'Cash', value: 'CASH' },
                { label: 'Credit Card', value: 'CREDIT_CARD' },
                { label: 'Debit Card', value: 'DEBIT_CARD' },
                { label: 'Online', value: 'ONLINE' },
                { label: 'Check', value: 'CHECK' }
              ]}
            />
          </Form.Item>
          <Form.Item label="Reference Number" name="reference_number">
            <Input placeholder="Enter transaction reference number (optional)" />
          </Form.Item>
          <Form.Item label="Notes" name="notes">
            <Input.TextArea rows={3} placeholder="Additional notes (e.g., partial payment)" />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="Waive Fine"
        open={waiveFineModalVisible}
        onCancel={closeWaiveFineModal}
        onOk={handleWaiveFine}
        width={480}
        destroyOnClose
        confirmLoading={loading}
      >
        <Form form={waiveFineForm} layout="vertical">
          <Alert
            type="warning"
            message="This action cannot be undone. The fine will be permanently waived."
            showIcon
            style={{ marginBottom: '16px' }}
          />
          <Form.Item
            label="Reason for Waiving"
            name="waived_reason"
            rules={[{ required: true, message: 'Reason is required' }]}
          >
            <Input.TextArea rows={4} placeholder="Enter reason for waiving this fine" />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="Create Fine"
        open={createFineModalVisible}
        onCancel={closeCreateFineModal}
        onOk={handleCreateFine}
        width={560}
        destroyOnClose
        confirmLoading={loading}
      >
        <Form form={createFineForm} layout="vertical">
          <Form.Item
            label="Member"
            name="member_id"
            rules={[{ required: true, message: 'Member is required' }]}
          >
            <Select
              placeholder="Select member"
              showSearch
              optionFilterProp="label"
              options={memberOptions}
            />
          </Form.Item>
          <Form.Item
            label="Fine Type"
            name="reason"
            rules={[{ required: true, message: 'Fine type is required' }]}
          >
            <Select
              placeholder="Select fine type"
              options={[
                { label: 'Overdue', value: 'Overdue' },
                { label: 'Damage', value: 'Damage' },
                { label: 'Lost Book', value: 'Lost Book' },
                { label: 'Other', value: 'Other' }
              ]}
            />
          </Form.Item>
          <Form.Item
            label="Amount"
            name="amount"
            rules={[{ required: true, message: 'Amount is required' }]}
          >
            <InputNumber
              min={0.01}
              precision={2}
              prefix="$"
              style={{ width: '100%' }}
              placeholder="Enter fine amount"
            />
          </Form.Item>
          <Form.Item label="Related Loan (Optional)" name="loan_id">
            <Select
              placeholder="Select related loan (optional)"
              allowClear
              showSearch
              options={loanOptions}
            />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}