import { useState, useMemo, useEffect, useCallback } from 'react';
import { Table, Card, Button, Select, DatePicker, Modal, Descriptions, Alert, Typography, Breadcrumb, message, Tag } from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { request } from '../api/client';
import { useAppContext } from '../store/AppContext';
import { ROUTES } from '../router/routes.constant';

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

interface BookDetailResponse {
  id: string;
  title: string;
  isbn: string | null;
}

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

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

  const [currentLoans, setCurrentLoans] = useState<LoanResponse[]>([]);
  const [loanHistory, setLoanHistory] = useState<LoanResponse[]>([]);
  const [historyStatusFilter, setHistoryStatusFilter] = useState<string | null>(null);
  const [historyDateRange, setHistoryDateRange] = useState<[string, string] | null>(null);
  const [historyPagination, setHistoryPagination] = useState<PaginationState>({
    current: 1,
    pageSize: 10,
    total: 0,
  });
  const [loading, setLoading] = useState<boolean>(false);
  const [renewModalVisible, setRenewModalVisible] = useState<boolean>(false);
  const [selectedLoanForRenewal, setSelectedLoanForRenewal] = useState<LoanResponse | null>(null);
  const [renewalResult, setRenewalResult] = useState<{ error_message?: string } | null>(null);
  const [renewalLoading, setRenewalLoading] = useState<boolean>(false);
  const [bookDetailsCache, setBookDetailsCache] = useState<Record<string, BookDetailResponse>>({});

  const fetchCurrentLoans = useCallback(async () => {
    if (!currentUser?.memberId) return;
    setLoading(true);
    try {
      const result = await request<LoanResponse[]>({
        method: 'GET',
        path: '/circulation/loans',
        query: {
          member_id: currentUser.memberId,
          loan_status: 'ACTIVE',
          limit: 50,
        },
      });
      setCurrentLoans(result.data);
      
      const bookIds = result.data.map(loan => loan.book_id);
      const uniqueBookIds = Array.from(new Set(bookIds));
      
      for (const bookId of uniqueBookIds) {
        if (!bookDetailsCache[bookId]) {
          try {
            const bookResult = await request<BookDetailResponse>({
              method: 'GET',
              path: '/books/{book_id}/details',
              pathParams: { book_id: bookId },
            });
            setBookDetailsCache(prev => ({ ...prev, [bookId]: bookResult.data }));
          } catch (error) {
            console.error(`Failed to fetch book details for ${bookId}`);
          }
        }
      }
    } catch (error) {
      messageApi.error('Failed to load current loans');
    } finally {
      setLoading(false);
    }
  }, [currentUser?.memberId, messageApi, bookDetailsCache]);

  const fetchLoanHistory = useCallback(async () => {
    if (!currentUser?.memberId) return;
    setLoading(true);
    try {
      const offset = (historyPagination.current - 1) * historyPagination.pageSize;
      const queryParams: Record<string, string | number> = {
        member_id: currentUser.memberId,
        limit: historyPagination.pageSize,
        offset: offset,
      };
      
      if (historyStatusFilter) {
        queryParams.loan_status = historyStatusFilter;
      }

      const result = await request<LoanResponse[]>({
        method: 'GET',
        path: '/circulation/loans',
        query: queryParams,
      });
      setLoanHistory(result.data);
      setHistoryPagination(prev => ({ ...prev, total: result.data.length }));

      const bookIds = result.data.map(loan => loan.book_id);
      const uniqueBookIds = Array.from(new Set(bookIds));
      
      for (const bookId of uniqueBookIds) {
        if (!bookDetailsCache[bookId]) {
          try {
            const bookResult = await request<BookDetailResponse>({
              method: 'GET',
              path: '/books/{book_id}/details',
              pathParams: { book_id: bookId },
            });
            setBookDetailsCache(prev => ({ ...prev, [bookId]: bookResult.data }));
          } catch (error) {
            console.error(`Failed to fetch book details for ${bookId}`);
          }
        }
      }
    } catch (error) {
      messageApi.error('Failed to load loan history');
    } finally {
      setLoading(false);
    }
  }, [currentUser?.memberId, historyPagination.current, historyPagination.pageSize, historyStatusFilter, messageApi, bookDetailsCache]);

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

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

  const onHistoryStatusChange = (value: string | null) => {
    setHistoryStatusFilter(value);
    setHistoryPagination(prev => ({ ...prev, current: 1 }));
  };

  const onHistoryDateRangeChange = (dates: [string, string] | null) => {
    setHistoryDateRange(dates);
    setHistoryPagination(prev => ({ ...prev, current: 1 }));
  };

  const onHistoryPageChange = (page: number, pageSize: number) => {
    setHistoryPagination(prev => ({ ...prev, current: page, pageSize }));
  };

  const onRenewClick = (record: LoanResponse) => {
    setSelectedLoanForRenewal(record);
    setRenewModalVisible(true);
    setRenewalResult(null);
  };

  const onRenewModalClose = () => {
    setRenewModalVisible(false);
    setSelectedLoanForRenewal(null);
    setRenewalResult(null);
  };

  const confirmRenewLoan = async () => {
    if (!selectedLoanForRenewal) return;
    setRenewalLoading(true);
    try {
      const result = await request<LoanResponse>({
        method: 'POST',
        path: '/circulation/loans/{loan_id}/renew',
        pathParams: { loan_id: selectedLoanForRenewal.id },
      });
      setRenewalResult(result.data);
      messageApi.success('Loan renewed successfully!');
      await fetchCurrentLoans();
      onRenewModalClose();
    } catch (error) {
      messageApi.error('Unable to renew loan. Please check the reason below.');
      setRenewalResult({ error_message: 'Renewal failed. Please contact the library.' });
    } finally {
      setRenewalLoading(false);
    }
  };

  const navigateToDashboard = () => {
    navigate(ROUTES.MEMBER_DASHBOARD || '/member/dashboard');
  };

  const getStatusColor = (status: string): string => {
    switch (status) {
      case 'ACTIVE':
        return 'blue';
      case 'RETURNED':
        return 'green';
      case 'OVERDUE':
        return 'red';
      case 'LOST':
        return 'volcano';
      default:
        return 'default';
    }
  };

  const formatDate = (dateString: string | null): string => {
    if (!dateString) return '-';
    return new Date(dateString).toLocaleDateString();
  };

  const calculateNewDueDate = (currentDueDate: string): string => {
    const date = new Date(currentDueDate);
    date.setDate(date.getDate() + 14);
    return date.toLocaleDateString();
  };

  const currentLoansColumns = useMemo(() => [
    {
      title: 'Book',
      dataIndex: 'book_id',
      key: 'book_id',
      render: (bookId: string) => {
        const book = bookDetailsCache[bookId];
        return book ? book.title : bookId;
      },
    },
    {
      title: 'Checkout Date',
      dataIndex: 'checkout_date',
      key: 'checkout_date',
      render: (date: string) => formatDate(date),
    },
    {
      title: 'Due Date',
      dataIndex: 'due_date',
      key: 'due_date',
      render: (date: string) => formatDate(date),
    },
    {
      title: 'Renewals',
      dataIndex: 'renewal_count',
      key: 'renewal_count',
      render: (count: number) => `${count} / 3`,
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      render: (status: string) => (
        <Tag color={getStatusColor(status)}>{status}</Tag>
      ),
    },
    {
      title: 'Action',
      key: 'action',
      render: (_: unknown, record: LoanResponse) => (
        <Button
          type="link"
          onClick={() => onRenewClick(record)}
          disabled={record.renewal_count >= 3 || record.status !== 'ACTIVE'}
        >
          Renew
        </Button>
      ),
    },
  ], [bookDetailsCache]);

  const loanHistoryColumns = useMemo(() => [
    {
      title: 'Book',
      dataIndex: 'book_id',
      key: 'book_id',
      render: (bookId: string) => {
        const book = bookDetailsCache[bookId];
        return book ? (
          <Button type="link" onClick={() => navigate(`/catalog/${bookId}`)}>
            {book.title}
          </Button>
        ) : bookId;
      },
    },
    {
      title: 'Checkout Date',
      dataIndex: 'checkout_date',
      key: 'checkout_date',
      render: (date: string) => formatDate(date),
    },
    {
      title: 'Due Date',
      dataIndex: 'due_date',
      key: 'due_date',
      render: (date: string) => formatDate(date),
    },
    {
      title: 'Return Date',
      dataIndex: 'return_date',
      key: 'return_date',
      render: (date: string | null) => formatDate(date),
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      render: (status: string) => (
        <Tag color={getStatusColor(status)}>{status}</Tag>
      ),
    },
    {
      title: 'Fines',
      key: 'fines',
      render: () => '$0.00',
    },
  ], [bookDetailsCache, navigate]);

  const filteredHistoryCount = useMemo(() => historyPagination.total, [historyPagination.total]);

  return (
    <div style={{ minHeight: '100vh', height: '100%', width: '100%', display: 'flex', flexDirection: 'column', padding: '24px', background: '#f5f5f5' }}>
      {contextHolder}
      
      <div style={{ marginBottom: '24px' }}>
        <Breadcrumb
          style={{ marginBottom: '16px' }}
          items={[
            { title: 'Home', href: '/member/dashboard' },
            { title: 'My Loans' },
          ]}
        />
        <Button
          type="link"
          icon={<ArrowLeftOutlined />}
          onClick={navigateToDashboard}
        >
          Back to Dashboard
        </Button>
        <Typography.Title level={2} style={{ marginBottom: '0' }}>
          My Loans
        </Typography.Title>
      </div>

      <Card title="Current Loans" style={{ marginBottom: '24px' }}>
        <Table
          columns={currentLoansColumns}
          dataSource={currentLoans}
          rowKey="id"
          loading={loading}
          pagination={false}
        />
      </Card>

      <Card title="Loan History">
        <div style={{ marginBottom: '16px', display: 'flex', flexDirection: 'row', gap: '16px', flexWrap: 'wrap' }}>
          <Select
            placeholder="Filter by status"
            allowClear
            value={historyStatusFilter}
            onChange={onHistoryStatusChange}
            style={{ width: 180 }}
            options={[
              { label: 'Active', value: 'ACTIVE' },
              { label: 'Returned', value: 'RETURNED' },
              { label: 'Overdue', value: 'OVERDUE' },
              { label: 'Lost', value: 'LOST' },
            ]}
          />
          <DatePicker.RangePicker
            placeholder={['Start Date', 'End Date']}
            onChange={(dates) => onHistoryDateRangeChange(dates as [string, string] | null)}
          />
        </div>
        <Table
          columns={loanHistoryColumns}
          dataSource={loanHistory}
          rowKey="id"
          loading={loading}
          pagination={{
            current: historyPagination.current,
            pageSize: historyPagination.pageSize,
            total: historyPagination.total,
            showSizeChanger: true,
            showTotal: (total) => `Total ${total} items`,
            onChange: onHistoryPageChange,
          }}
        />
      </Card>

      <Modal
        title="Confirm Loan Renewal"
        open={renewModalVisible}
        onCancel={onRenewModalClose}
        footer={null}
      >
        <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
          {selectedLoanForRenewal && (
            <Descriptions column={1} bordered style={{ marginBottom: '16px' }}>
              <Descriptions.Item label="Book">
                {bookDetailsCache[selectedLoanForRenewal.book_id]?.title || selectedLoanForRenewal.book_id}
              </Descriptions.Item>
              <Descriptions.Item label="Current Due Date">
                {formatDate(selectedLoanForRenewal.due_date)}
              </Descriptions.Item>
              <Descriptions.Item label="New Due Date">
                {calculateNewDueDate(selectedLoanForRenewal.due_date)}
              </Descriptions.Item>
              <Descriptions.Item label="Renewals Used">
                {selectedLoanForRenewal.renewal_count}
              </Descriptions.Item>
            </Descriptions>
          )}
          
          {renewalResult?.error_message && (
            <Alert
              type="error"
              showIcon
              message="Renewal Denied"
              description={renewalResult.error_message}
              style={{ marginBottom: '16px' }}
            />
          )}

          <div style={{ display: 'flex', justifyContent: 'flex-end', gap: '8px' }}>
            <Button onClick={onRenewModalClose}>
              Cancel
            </Button>
            <Button
              type="primary"
              loading={renewalLoading}
              onClick={confirmRenewLoan}
            >
              Confirm Renewal
            </Button>
          </div>
        </div>
      </Modal>
    </div>
  );
}