import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import { Card, Row, Col, Table, Button, Modal, Form, Select, InputNumber, Space, Typography, Statistic, Tag, message } from 'antd';
import { SearchOutlined, HistoryOutlined, UserOutlined, DollarOutlined, SyncOutlined } from '@ant-design/icons';
import { request } from '../api/client';
import { useNavigate } from 'react-router-dom';
import { useAppContext } from '../store/AppContext';

const { Title, Text } = Typography;

interface LoanResponse {
  id: string;
  member_id: string;
  book_copy_id: string;
  checkout_date: string;
  due_date: string;
  return_date?: string | null;
  renewal_count: number;
  status: 'ACTIVE' | 'RETURNED' | 'OVERDUE' | 'LOST';
  checked_out_by_librarian_id?: string | null;
  checked_in_by_librarian_id?: string | null;
  notes?: string | null;
  created_at: string;
  updated_at: string;
}

interface ReservationResponse {
  id: string;
  member_id: string;
  book_id: string;
  reservation_date: string;
  expiration_date: string;
  status: 'PENDING' | 'READY' | 'FULFILLED' | 'CANCELLED' | 'EXPIRED';
  priority_order?: number | null;
  notified_date?: string | null;
  created_at: string;
  updated_at: string;
}

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

interface BookResponse {
  id: string;
  title: string;
  book_authors: Array<{ author: { name: string } }>;
}

interface PaymentFormValues {
  paymentMethod: 'CASH' | 'CREDIT_CARD' | 'DEBIT_CARD' | 'ONLINE' | 'CHECK';
  paymentAmount: number;
}

export default function MemberDashboardPage() {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();
  const { currentUser } = useAppContext();
  const [form] = Form.useForm<PaymentFormValues>();

  const [activeLoans, setActiveLoans] = useState<LoanResponse[]>([]);
  const [activeReservations, setActiveReservations] = useState<ReservationResponse[]>([]);
  const [outstandingFines, setOutstandingFines] = useState<FineResponse[]>([]);
  const [recommendedBooks, setRecommendedBooks] = useState<BookResponse[]>([]);
  const [booksReadCount, setBooksReadCount] = useState<number>(0);
  const [paymentModalVisible, setPaymentModalVisible] = useState<boolean>(false);
  const [selectedFinesForPayment, setSelectedFinesForPayment] = useState<string[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [renewingLoanId, setRenewingLoanId] = useState<string | null>(null);
  const [cancellingReservationId, setCancellingReservationId] = useState<string | null>(null);

  const totalFinesAmount = useMemo(() => {
    return outstandingFines.reduce((sum, f) => sum + (f.amount - f.amount_paid), 0);
  }, [outstandingFines]);

  const activeLoansCount = useMemo(() => activeLoans.length, [activeLoans]);
  const activeReservationsCount = useMemo(() => activeReservations.length, [activeReservations]);

  const fetchActiveLoans = useCallback(async () => {
    try {
      const result = await request<LoanResponse[]>({
        method: 'GET',
        path: '/loans/',
        query: {
          member_id: currentUser?.memberId,
          status: 'ACTIVE',
          limit: 50
        }
      });
      setActiveLoans(result.data);
    } catch (error) {
      messageApi.error('Failed to load active loans');
    }
  }, [currentUser?.memberId, messageApi]);

  const fetchActiveReservations = useCallback(async () => {
    try {
      const result = await request<ReservationResponse[]>({
        method: 'GET',
        path: '/reservations/',
        query: {
          member_id: currentUser?.memberId,
          status: 'PENDING',
          limit: 50
        }
      });
      setActiveReservations(result.data);
    } catch (error) {
      messageApi.error('Failed to load active reservations');
    }
  }, [currentUser?.memberId, messageApi]);

  const fetchOutstandingFines = useCallback(async () => {
    try {
      const result = await request<FineResponse[]>({
        method: 'GET',
        path: '/fines/',
        query: {
          member_id: currentUser?.memberId,
          payment_status: 'UNPAID',
          limit: 50
        }
      });
      setOutstandingFines(result.data);
    } catch (error) {
      messageApi.error('Failed to load outstanding fines');
    }
  }, [currentUser?.memberId, messageApi]);

  const fetchBooksReadCount = useCallback(async () => {
    try {
      const result = await request<LoanResponse[]>({
        method: 'GET',
        path: '/loans/',
        query: {
          member_id: currentUser?.memberId,
          status: 'RETURNED',
          limit: 1,
          offset: 0
        }
      });
      setBooksReadCount(result.data.length);
    } catch (error) {
      messageApi.error('Failed to load books read count');
    }
  }, [currentUser?.memberId, messageApi]);

  const fetchRecommendedBooks = useCallback(async () => {
    try {
      const result = await request<BookResponse[]>({
        method: 'GET',
        path: '/catalog/books',
        query: {
          limit: 10,
          offset: 0
        }
      });
      setRecommendedBooks(result.data);
    } catch (error) {
      messageApi.error('Failed to load recommended books');
    }
  }, [messageApi]);

  useEffect(() => {
    const fetchData = async () => {
      setLoading(true);
      await Promise.all([
        fetchActiveLoans(),
        fetchActiveReservations(),
        fetchOutstandingFines(),
        fetchBooksReadCount(),
        fetchRecommendedBooks()
      ]);
      setLoading(false);
    };
    fetchData();
  }, [fetchActiveLoans, fetchActiveReservations, fetchOutstandingFines, fetchBooksReadCount, fetchRecommendedBooks]);

  const handleRenewLoan = useCallback((loanId: string) => {
    Modal.confirm({
      title: 'Renew Book',
      content: 'Are you sure you want to renew this book?',
      onOk: async () => {
        setRenewingLoanId(loanId);
        try {
          await request<LoanResponse>({
            method: 'POST',
            path: '/loans/{loan_id}/renew',
            pathParams: { loan_id: loanId },
            body: { notes: null }
          });
          messageApi.success('Book renewed successfully!');
          await fetchActiveLoans();
        } catch (error) {
          messageApi.error('Unable to renew this book. It may be reserved by another member or has reached the renewal limit.');
        } finally {
          setRenewingLoanId(null);
        }
      }
    });
  }, [fetchActiveLoans, messageApi]);

  const handleCancelReservation = useCallback((reservationId: string) => {
    Modal.confirm({
      title: 'Cancel Reservation',
      content: 'Are you sure you want to cancel this reservation?',
      onOk: async () => {
        setCancellingReservationId(reservationId);
        try {
          await request<ReservationResponse>({
            method: 'POST',
            path: '/reservations/{reservation_id}/cancel',
            pathParams: { reservation_id: reservationId }
          });
          messageApi.success('Reservation cancelled successfully');
          await fetchActiveReservations();
        } catch (error) {
          messageApi.error('Unable to cancel reservation. Please try again.');
        } finally {
          setCancellingReservationId(null);
        }
      }
    });
  }, [fetchActiveReservations, messageApi]);

  const handlePaymentSubmit = useCallback(async () => {
    try {
      const values = await form.validateFields();
      if (selectedFinesForPayment.length === 0) {
        messageApi.error('Please select at least one fine to pay');
        return;
      }
      await request({
        method: 'POST',
        path: '/fines/payments',
        body: {
          member_id: currentUser?.memberId,
          fine_id: selectedFinesForPayment[0],
          amount: values.paymentAmount,
          payment_method: values.paymentMethod,
          transaction_date: new Date().toISOString(),
          reference_number: null,
          processed_by_librarian_id: null,
          notes: null
        }
      });
      messageApi.success('Payment processed successfully!');
      setPaymentModalVisible(false);
      setSelectedFinesForPayment([]);
      form.resetFields();
      await fetchOutstandingFines();
    } catch (error) {
      messageApi.error('Payment failed. Please try again or contact the library.');
    }
  }, [form, selectedFinesForPayment, currentUser?.memberId, fetchOutstandingFines, messageApi]);

  const getDueDateColor = useCallback((dueDate: string): string => {
    const today = new Date();
    const due = new Date(dueDate);
    const diffDays = Math.ceil((due.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));
    if (diffDays < 0) return 'red';
    if (diffDays <= 3) return 'orange';
    return 'green';
  }, []);

  const loansColumns = useMemo(() => [
    {
      title: 'Book Copy ID',
      dataIndex: 'book_copy_id',
      key: 'book_copy_id'
    },
    {
      title: 'Checkout Date',
      dataIndex: 'checkout_date',
      key: 'checkout_date',
      render: (date: string) => new Date(date).toLocaleDateString()
    },
    {
      title: 'Due Date',
      dataIndex: 'due_date',
      key: 'due_date',
      render: (date: string) => (
        <Tag color={getDueDateColor(date)}>
          {new Date(date).toLocaleDateString()}
        </Tag>
      )
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      render: (status: string) => <Tag>{status}</Tag>
    },
    {
      title: 'Renewals',
      dataIndex: 'renewal_count',
      key: 'renewal_count'
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, record: LoanResponse) => (
        <Button
          type="link"
          icon={<SyncOutlined />}
          onClick={() => handleRenewLoan(record.id)}
          loading={renewingLoanId === record.id}
        >
          Renew
        </Button>
      )
    }
  ], [getDueDateColor, handleRenewLoan, renewingLoanId]);

  const reservationsColumns = useMemo(() => [
    {
      title: 'Book ID',
      dataIndex: 'book_id',
      key: 'book_id'
    },
    {
      title: 'Reservation Date',
      dataIndex: 'reservation_date',
      key: 'reservation_date',
      render: (date: string) => new Date(date).toLocaleDateString()
    },
    {
      title: 'Queue Position',
      dataIndex: 'priority_order',
      key: 'priority_order'
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      render: (status: string) => <Tag>{status}</Tag>
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, record: ReservationResponse) => (
        <Button
          type="link"
          danger
          onClick={() => handleCancelReservation(record.id)}
          loading={cancellingReservationId === record.id}
        >
          Cancel
        </Button>
      )
    }
  ], [handleCancelReservation, cancellingReservationId]);

  const finesColumns = useMemo(() => [
    {
      title: 'Reason',
      dataIndex: 'reason',
      key: 'reason'
    },
    {
      title: 'Amount',
      dataIndex: 'amount',
      key: 'amount',
      render: (amount: number) => `$${amount.toFixed(2)}`
    },
    {
      title: 'Paid',
      dataIndex: 'amount_paid',
      key: 'amount_paid',
      render: (amount: number) => `$${amount.toFixed(2)}`
    },
    {
      title: 'Remaining',
      key: 'remaining',
      render: (_: unknown, record: FineResponse) => `$${(record.amount - record.amount_paid).toFixed(2)}`
    }
  ], []);

  const rootStyle: CSSProperties = {
    minHeight: '100vh',
    height: '100%',
    width: '100%',
    display: 'flex',
    flexDirection: 'column',
    padding: '24px',
    background: '#f5f5f5'
  };

  return (
    <div style={rootStyle}>
      {contextHolder}
      <Title level={2} style={{ marginBottom: '8px' }}>
        My Dashboard
      </Title>
      <Text type="secondary" style={{ marginBottom: '24px', display: 'block' }}>
        Welcome, {currentUser?.fullName || 'Member'}
      </Text>

      <Row gutter={[16, 16]} style={{ marginBottom: '24px' }}>
        <Col xs={24} sm={12} md={6}>
          <Card bordered size="small">
            <Statistic title="Active Loans" value={activeLoansCount} />
          </Card>
        </Col>
        <Col xs={24} sm={12} md={6}>
          <Card bordered size="small">
            <Statistic title="Active Reservations" value={activeReservationsCount} />
          </Card>
        </Col>
        <Col xs={24} sm={12} md={6}>
          <Card bordered size="small">
            <Statistic
              title="Outstanding Fines"
              value={totalFinesAmount}
              prefix="$"
              precision={2}
              valueStyle={{ color: '#cf1322' }}
            />
          </Card>
        </Col>
        <Col xs={24} sm={12} md={6}>
          <Card bordered size="small">
            <Statistic title="Books Read" value={booksReadCount} />
          </Card>
        </Col>
      </Row>

      <Card title="Current Loans" bordered style={{ marginBottom: '24px' }}>
        <Table
          dataSource={activeLoans}
          columns={loansColumns}
          rowKey="id"
          pagination={false}
          size="middle"
          loading={loading}
        />
      </Card>

      <Card title="Active Reservations" bordered style={{ marginBottom: '24px' }}>
        <Table
          dataSource={activeReservations}
          columns={reservationsColumns}
          rowKey="id"
          pagination={false}
          size="middle"
          loading={loading}
        />
      </Card>

      <Card title="Outstanding Fines" bordered style={{ marginBottom: '24px' }}>
        <Statistic
          title="Total Balance"
          value={totalFinesAmount}
          prefix="$"
          precision={2}
          valueStyle={{ color: '#cf1322' }}
          style={{ marginBottom: '16px' }}
        />
        <Button
          type="primary"
          danger
          icon={<DollarOutlined />}
          onClick={() => setPaymentModalVisible(true)}
          disabled={outstandingFines.length === 0}
        >
          Pay Now
        </Button>
      </Card>

      <Space size="middle" wrap style={{ marginBottom: '24px' }}>
        <Button
          type="primary"
          icon={<SearchOutlined />}
          size="large"
          onClick={() => navigate('/')}
        >
          Search Catalog
        </Button>
        <Button
          type="default"
          icon={<HistoryOutlined />}
          size="large"
          onClick={() => navigate('/dashboard/history')}
        >
          View History
        </Button>
        <Button
          type="default"
          icon={<UserOutlined />}
          size="large"
          onClick={() => navigate('/dashboard/profile')}
        >
          My Profile
        </Button>
      </Space>

      <Modal
        title="Make Payment"
        open={paymentModalVisible}
        onCancel={() => {
          setPaymentModalVisible(false);
          setSelectedFinesForPayment([]);
          form.resetFields();
        }}
        onOk={handlePaymentSubmit}
        width={520}
        destroyOnClose
        okText="Submit Payment"
        cancelText="Cancel"
      >
        <Form form={form} layout="vertical">
          <Table
            dataSource={outstandingFines}
            columns={finesColumns}
            rowKey="id"
            rowSelection={{
              type: 'checkbox',
              selectedRowKeys: selectedFinesForPayment,
              onChange: (selectedRowKeys) => setSelectedFinesForPayment(selectedRowKeys as string[])
            }}
            pagination={false}
            size="small"
            style={{ marginBottom: '16px' }}
          />
          <Form.Item
            name="paymentMethod"
            label="Payment Method"
            rules={[{ required: true, message: 'Please select a payment method' }]}
          >
            <Select
              placeholder="Select payment method"
              style={{ width: '100%' }}
              options={[
                { label: 'Cash', value: 'CASH' },
                { label: 'Credit Card', value: 'CREDIT_CARD' },
                { label: 'Debit Card', value: 'DEBIT_CARD' },
                { label: 'Online', value: 'ONLINE' }
              ]}
            />
          </Form.Item>
          <Form.Item
            name="paymentAmount"
            label="Amount"
            rules={[{ required: true, message: 'Please enter payment amount' }]}
          >
            <InputNumber
              min={0.01}
              step={0.01}
              prefix="$"
              placeholder="Enter amount"
              precision={2}
              style={{ width: '100%' }}
            />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}