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

type FineStatus = 'UNPAID' | 'PARTIAL' | 'PAID' | 'WAIVED';
type FineReason = 'OVERDUE' | 'DAMAGED' | 'LOST' | 'OTHER';

interface FineResponse {
  id: string;
  member_id: string;
  loan_id: string | null;
  amount: number;
  amount_paid: number;
  reason: FineReason;
  description: string | null;
  status: FineStatus;
  assessed_date: string;
  due_date: string | null;
  waived_by: string | null;
  waived_date: string | null;
  waived_reason: string | null;
  created_at: string;
  updated_at: string;
}

interface MemberDetailResponse {
  id: string;
  user_id: string;
  membership_number: string;
  account_standing: string;
}

interface LoanDetailResponse {
  id: string;
  book_id: string;
  book: {
    id: string;
    title: string;
    isbn: string | null;
  };
}

interface UserDetailResponse {
  id: string;
  email: string;
  first_name: string;
  last_name: string;
}

interface PaymentDetailInFineResponse {
  id: string;
  payment_date: string;
  amount: number;
  payment_method: string;
  notes: string | null;
}

interface FineDetailResponse {
  id: string;
  member_id: string;
  loan_id: string | null;
  amount: number;
  amount_paid: number;
  reason: FineReason;
  description: string | null;
  status: FineStatus;
  assessed_date: string;
  due_date: string | null;
  waived_by: string | null;
  waived_date: string | null;
  waived_reason: string | null;
  created_at: string;
  updated_at: string;
  member: MemberDetailResponse;
  loan: LoanDetailResponse | null;
  waived_by_user: UserDetailResponse | null;
  payments: PaymentDetailInFineResponse[];
}

interface MemberResponse {
  id: string;
  user_id: string;
  membership_number: string;
  membership_date: string;
  membership_expiry: string | null;
  borrowing_limit: number;
  account_standing: string;
  created_at: string;
  updated_at: string;
}

interface PaginationState {
  current: number;
  pageSize: number;
  total: number;
}

interface SummaryStats {
  totalOutstanding: number;
  collectedThisMonth: number;
  waivedThisMonth: number;
}

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

  const [fines, setFines] = useState<FineResponse[]>([]);
  const [loading, setLoading] = useState<boolean>(false);
  const [filterStatus, setFilterStatus] = useState<FineStatus | null>(null);
  const [filterReason, setFilterReason] = useState<FineReason | null>(null);
  const [searchMember, setSearchMember] = useState<string>('');
  const [dateRange, setDateRange] = useState<[string, string] | null>(null);
  const [pagination, setPagination] = useState<PaginationState>({
    current: 1,
    pageSize: 20,
    total: 0,
  });
  const [selectedFine, setSelectedFine] = useState<FineResponse | null>(null);
  const [detailModalVisible, setDetailModalVisible] = useState<boolean>(false);
  const [paymentModalVisible, setPaymentModalVisible] = useState<boolean>(false);
  const [waiveModalVisible, setWaiveModalVisible] = useState<boolean>(false);
  const [addFineModalVisible, setAddFineModalVisible] = useState<boolean>(false);
  const [fineDetails, setFineDetails] = useState<FineDetailResponse | null>(null);
  const [members, setMembers] = useState<MemberResponse[]>([]);
  const [summaryStats, setSummaryStats] = useState<SummaryStats>({
    totalOutstanding: 0,
    collectedThisMonth: 0,
    waivedThisMonth: 0,
  });

  const [paymentForm] = Form.useForm();
  const [waiveForm] = Form.useForm();
  const [addFineForm] = Form.useForm();

  const fineBalance = useMemo(() => {
    return selectedFine ? selectedFine.amount - selectedFine.amount_paid : 0;
  }, [selectedFine]);

  const fetchFines = useCallback(async () => {
    setLoading(true);
    try {
      const result = await request<FineResponse[]>({
        method: 'GET',
        path: '/fines/',
        query: {
          limit: pagination.pageSize,
          offset: (pagination.current - 1) * pagination.pageSize,
          ...(filterStatus && { status: filterStatus }),
          ...(searchMember && { member_id: searchMember }),
        },
      });
      setFines(result.data);
      setPagination((prev) => ({ ...prev, total: result.data.length }));
    } catch (error) {
      messageApi.error('Failed to load fines');
    } finally {
      setLoading(false);
    }
  }, [pagination.current, pagination.pageSize, filterStatus, searchMember, messageApi]);

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

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

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

  const handleViewDetails = async (record: FineResponse) => {
    setSelectedFine(record);
    setDetailModalVisible(true);
    try {
      const result = await request<FineDetailResponse>({
        method: 'GET',
        path: '/fines/{fine_id}/details',
        pathParams: { fine_id: record.id },
      });
      setFineDetails(result.data);
    } catch (error) {
      messageApi.error('Failed to load fine details');
    }
  };

  const handleOpenPaymentModal = (record: FineResponse) => {
    setSelectedFine(record);
    setPaymentModalVisible(true);
  };

  const handleProcessPayment = async () => {
    if (!selectedFine) return;
    
    try {
      const values = await paymentForm.validateFields();
      
      Modal.confirm({
        title: 'Confirm Payment',
        content: 'Are you sure you want to process this payment?',
        onOk: async () => {
          try {
            const newAmountPaid = selectedFine.amount_paid + values.amount;
            const newStatus: FineStatus = newAmountPaid >= selectedFine.amount ? 'PAID' : 'PARTIAL';
            
            await request<FineResponse>({
              method: 'PUT',
              path: '/fines/{fine_id}',
              pathParams: { fine_id: selectedFine.id },
              body: {
                amount_paid: newAmountPaid,
                status: newStatus,
              },
            });
            
            messageApi.success('Payment processed successfully');
            setPaymentModalVisible(false);
            paymentForm.resetFields();
            fetchFines();
          } catch (error) {
            messageApi.error('Failed to process payment');
          }
        },
      });
    } catch (error) {
      return;
    }
  };

  const handleOpenWaiveModal = (record: FineResponse) => {
    setSelectedFine(record);
    setWaiveModalVisible(true);
  };

  const handleWaiveFine = async () => {
    if (!selectedFine || !currentUser) return;
    
    try {
      const values = await waiveForm.validateFields();
      
      Modal.confirm({
        title: 'Confirm Waive Fine',
        content: 'Are you sure you want to waive this fine?',
        onOk: async () => {
          try {
            await request<FineResponse>({
              method: 'POST',
              path: '/fines/{fine_id}/waive',
              pathParams: { fine_id: selectedFine.id },
              query: {
                waived_by: currentUser.id,
                waived_reason: values.waived_reason,
              },
            });
            
            messageApi.success('Fine waived successfully');
            setWaiveModalVisible(false);
            waiveForm.resetFields();
            fetchFines();
          } catch (error) {
            messageApi.error('Failed to waive fine');
          }
        },
      });
    } catch (error) {
      return;
    }
  };

  const handleOpenAddFineModal = () => {
    setAddFineModalVisible(true);
  };

  const handleAddFine = async () => {
    try {
      const values = await addFineForm.validateFields();
      
      await request<FineResponse>({
        method: 'POST',
        path: '/fines/',
        body: {
          member_id: values.member_id,
          loan_id: values.loan_id || null,
          amount: values.amount,
          amount_paid: 0,
          reason: values.reason,
          description: values.description || null,
          status: 'UNPAID',
          assessed_date: new Date().toISOString(),
          due_date: values.due_date || null,
        },
      });
      
      messageApi.success('Fine added successfully');
      setAddFineModalVisible(false);
      addFineForm.resetFields();
      fetchFines();
    } catch (error) {
      messageApi.error('Failed to add fine');
    }
  };

  const handleCloseDetailModal = () => {
    setDetailModalVisible(false);
    setFineDetails(null);
  };

  const handleClosePaymentModal = () => {
    setPaymentModalVisible(false);
    paymentForm.resetFields();
  };

  const handleCloseWaiveModal = () => {
    setWaiveModalVisible(false);
    waiveForm.resetFields();
  };

  const handleCloseAddFineModal = () => {
    setAddFineModalVisible(false);
    addFineForm.resetFields();
  };

  const handleExport = () => {
    messageApi.info('Export functionality not implemented');
  };

  const handleNavigateToMember = (memberId: string) => {
    navigate(`/admin/members/${memberId}`);
  };

  const getStatusColor = (status: FineStatus): string => {
    switch (status) {
      case 'UNPAID':
        return 'red';
      case 'PARTIAL':
        return 'orange';
      case 'PAID':
        return 'green';
      case 'WAIVED':
        return 'blue';
      default:
        return 'default';
    }
  };

  const getReasonColor = (reason: FineReason): string => {
    switch (reason) {
      case 'OVERDUE':
        return 'orange';
      case 'DAMAGED':
        return 'red';
      case 'LOST':
        return 'volcano';
      case 'OTHER':
        return 'default';
      default:
        return 'default';
    }
  };

  const columns = useMemo(() => [
    {
      title: 'Fine ID',
      dataIndex: 'id',
      key: 'id',
      width: 100,
      ellipsis: true,
    },
    {
      title: 'Member',
      dataIndex: 'member_id',
      key: 'member_id',
      render: (memberId: string) => (
        <Button type="link" onClick={() => handleNavigateToMember(memberId)}>
          {memberId}
        </Button>
      ),
    },
    {
      title: 'Type',
      dataIndex: 'reason',
      key: 'reason',
      render: (reason: FineReason) => (
        <Tag color={getReasonColor(reason)}>{reason}</Tag>
      ),
    },
    {
      title: 'Amount',
      dataIndex: 'amount',
      key: 'amount',
      render: (amount: number) => `$${amount.toFixed(2)}`,
    },
    {
      title: 'Paid',
      dataIndex: 'amount_paid',
      key: 'amount_paid',
      render: (amountPaid: number) => `$${amountPaid.toFixed(2)}`,
    },
    {
      title: 'Balance',
      key: 'balance',
      render: (_: unknown, record: FineResponse) => {
        const balance = record.amount - record.amount_paid;
        return `$${balance.toFixed(2)}`;
      },
    },
    {
      title: 'Loan',
      dataIndex: 'loan_id',
      key: 'loan_id',
      ellipsis: true,
      render: (loanId: string | null) => loanId || '-',
    },
    {
      title: 'Date Assessed',
      dataIndex: 'assessed_date',
      key: 'assessed_date',
      render: (date: string) => new Date(date).toLocaleDateString(),
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      render: (status: FineStatus) => (
        <Tag color={getStatusColor(status)}>{status}</Tag>
      ),
    },
    {
      title: 'Actions',
      key: 'actions',
      fixed: 'right' as const,
      width: 200,
      render: (_: unknown, record: FineResponse) => (
        <Space size="small">
          <Button
            type="link"
            size="small"
            icon={<EyeOutlined />}
            onClick={() => handleViewDetails(record)}
          >
            View
          </Button>
          {record.status !== 'PAID' && record.status !== 'WAIVED' && (
            <Button
              type="link"
              size="small"
              icon={<DollarOutlined />}
              onClick={() => handleOpenPaymentModal(record)}
            >
              Pay
            </Button>
          )}
          {record.status !== 'WAIVED' && (
            <Button
              type="link"
              size="small"
              danger
              icon={<CloseCircleOutlined />}
              onClick={() => handleOpenWaiveModal(record)}
            >
              Waive
            </Button>
          )}
        </Space>
      ),
    },
  ], []);

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

  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' }}>
        <Typography.Title level={2} style={{ margin: 0 }}>
          Fines Management
        </Typography.Title>
        <Space>
          <Button type="primary" icon={<PlusOutlined />} onClick={handleOpenAddFineModal}>
            Add Manual Fine
          </Button>
          <Button icon={<DownloadOutlined />} onClick={handleExport}>
            Export
          </Button>
        </Space>
      </div>

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

      <Card size="small" style={{ marginBottom: '16px' }}>
        <Row gutter={[16, 16]}>
          <Col xs={24} sm={12} md={6}>
            <Select
              placeholder="All Statuses"
              allowClear
              value={filterStatus}
              onChange={(value) => {
                setFilterStatus(value);
                setPagination((prev) => ({ ...prev, current: 1 }));
              }}
              style={{ width: '100%' }}
              options={[
                { label: 'Unpaid', value: 'UNPAID' },
                { label: 'Partially Paid', value: 'PARTIAL' },
                { label: 'Paid', value: 'PAID' },
                { label: 'Waived', value: 'WAIVED' },
              ]}
            />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <Select
              placeholder="All Types"
              allowClear
              value={filterReason}
              onChange={(value) => {
                setFilterReason(value);
                setPagination((prev) => ({ ...prev, current: 1 }));
              }}
              style={{ width: '100%' }}
              options={[
                { label: 'Overdue', value: 'OVERDUE' },
                { label: 'Damaged', value: 'DAMAGED' },
                { label: 'Lost', value: 'LOST' },
                { label: 'Other', value: 'OTHER' },
              ]}
            />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <DatePicker.RangePicker
              value={dateRange as never}
              onChange={(dates) => {
                setDateRange(dates as never);
                setPagination((prev) => ({ ...prev, current: 1 }));
              }}
              style={{ width: '100%' }}
            />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <Input.Search
              placeholder="Search by member ID..."
              allowClear
              value={searchMember}
              onChange={(e) => {
                setSearchMember(e.target.value);
                setPagination((prev) => ({ ...prev, current: 1 }));
              }}
            />
          </Col>
        </Row>
      </Card>

      <Card bodyStyle={{ padding: 0 }}>
        <Table
          rowKey="id"
          dataSource={fines}
          columns={columns}
          loading={loading}
          pagination={{
            current: pagination.current,
            pageSize: pagination.pageSize,
            total: pagination.total,
            showSizeChanger: true,
            showTotal: (total) => `Total ${total} items`,
            onChange: (page, pageSize) => {
              setPagination((prev) => ({ ...prev, current: page, pageSize: pageSize || 20 }));
            },
          }}
        />
      </Card>

      <Modal
        title="Fine Details"
        open={detailModalVisible}
        onCancel={handleCloseDetailModal}
        footer={null}
        width={720}
      >
        {fineDetails && (
          <>
            <Descriptions bordered column={2}>
              <Descriptions.Item label="Fine ID">{fineDetails.id}</Descriptions.Item>
              <Descriptions.Item label="Status">
                <Tag color={getStatusColor(fineDetails.status)}>{fineDetails.status}</Tag>
              </Descriptions.Item>
              <Descriptions.Item label="Member ID">{fineDetails.member_id}</Descriptions.Item>
              <Descriptions.Item label="Loan ID">{fineDetails.loan_id || '-'}</Descriptions.Item>
              <Descriptions.Item label="Type">
                <Tag color={getReasonColor(fineDetails.reason)}>{fineDetails.reason}</Tag>
              </Descriptions.Item>
              <Descriptions.Item label="Amount">${fineDetails.amount.toFixed(2)}</Descriptions.Item>
              <Descriptions.Item label="Amount Paid">${fineDetails.amount_paid.toFixed(2)}</Descriptions.Item>
              <Descriptions.Item label="Balance">${(fineDetails.amount - fineDetails.amount_paid).toFixed(2)}</Descriptions.Item>
              <Descriptions.Item label="Assessed Date">
                {new Date(fineDetails.assessed_date).toLocaleDateString()}
              </Descriptions.Item>
              <Descriptions.Item label="Due Date">
                {fineDetails.due_date ? new Date(fineDetails.due_date).toLocaleDateString() : '-'}
              </Descriptions.Item>
              <Descriptions.Item label="Description" span={2}>
                {fineDetails.description || '-'}
              </Descriptions.Item>
              {fineDetails.waived_by && (
                <>
                  <Descriptions.Item label="Waived By">{fineDetails.waived_by}</Descriptions.Item>
                  <Descriptions.Item label="Waived Date">
                    {fineDetails.waived_date ? new Date(fineDetails.waived_date).toLocaleDateString() : '-'}
                  </Descriptions.Item>
                  <Descriptions.Item label="Waived Reason" span={2}>
                    {fineDetails.waived_reason || '-'}
                  </Descriptions.Item>
                </>
              )}
            </Descriptions>
            
            {fineDetails.payments && fineDetails.payments.length > 0 && (
              <Table
                rowKey="id"
                dataSource={fineDetails.payments}
                size="small"
                pagination={false}
                style={{ marginTop: '16px' }}
                columns={[
                  {
                    title: 'Date',
                    dataIndex: 'payment_date',
                    key: 'payment_date',
                    render: (date: string) => new Date(date).toLocaleDateString(),
                  },
                  {
                    title: 'Amount',
                    dataIndex: 'amount',
                    key: 'amount',
                    render: (amount: number) => `$${amount.toFixed(2)}`,
                  },
                  {
                    title: 'Method',
                    dataIndex: 'payment_method',
                    key: 'payment_method',
                  },
                  {
                    title: 'Notes',
                    dataIndex: 'notes',
                    key: 'notes',
                    render: (notes: string | null) => notes || '-',
                  },
                ]}
              />
            )}
          </>
        )}
      </Modal>

      <Modal
        title="Process Payment"
        open={paymentModalVisible}
        onCancel={handleClosePaymentModal}
        onOk={handleProcessPayment}
        okText="Process Payment"
        width={480}
      >
        <Form form={paymentForm} layout="vertical">
          <Form.Item
            label="Payment Amount"
            name="amount"
            rules={[{ required: true, message: 'Payment amount is required' }]}
          >
            <InputNumber
              min={0.01}
              precision={2}
              prefix="$"
              style={{ width: '100%' }}
              placeholder="Enter 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: 'Check', value: 'CHECK' },
              ]}
            />
          </Form.Item>
          <Form.Item label="Notes" name="notes">
            <Input.TextArea rows={3} placeholder="Optional notes..." />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="Waive Fine"
        open={waiveModalVisible}
        onCancel={handleCloseWaiveModal}
        onOk={handleWaiveFine}
        okText="Waive Fine"
        okButtonProps={{ danger: true }}
        width={480}
      >
        <Form form={waiveForm} layout="vertical">
          <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="Add Manual Fine"
        open={addFineModalVisible}
        onCancel={handleCloseAddFineModal}
        onOk={handleAddFine}
        okText="Add Fine"
        width={560}
      >
        <Form form={addFineForm} layout="vertical">
          <Form.Item
            label="Member"
            name="member_id"
            rules={[{ required: true, message: 'Member is required' }]}
          >
            <Select
              placeholder="Select member"
              showSearch
              optionFilterProp="label"
              style={{ width: '100%' }}
              options={memberOptions}
            />
          </Form.Item>
          <Form.Item
            label="Fine Type"
            name="reason"
            rules={[{ required: true, message: 'Fine type is required' }]}
          >
            <Select
              placeholder="Select type"
              options={[
                { label: 'Overdue', value: 'OVERDUE' },
                { label: 'Damaged', value: 'DAMAGED' },
                { label: 'Lost', value: 'LOST' },
                { 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="Reason/Description" name="description">
            <Input.TextArea rows={3} placeholder="Describe the reason for this fine..." />
          </Form.Item>
          <Form.Item label="Associated Loan (Optional)" name="loan_id">
            <Input placeholder="Enter loan ID (optional)" />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}