import { useState, useMemo, useEffect, useCallback } from 'react';
import { Layout, Typography, Space, Button, Row, Col, Card, Statistic, Select, DatePicker, Input, Table, Modal, Descriptions, message, Tag, Badge } from 'antd';
import { PlusOutlined, DownloadOutlined, BookOutlined, WarningOutlined, ClockCircleOutlined, EyeOutlined, ReloadOutlined, RollbackOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { request } from '../api/client';
import { ROUTES } from '../router/routes.constant';

type LoanStatus = 'ACTIVE' | 'RETURNED' | 'OVERDUE' | 'LOST';

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: LoanStatus;
  notes: string | null;
  created_at: string;
  updated_at: string;
}

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

interface LoanDetailResponse {
  id: string;
  book_id: string;
  book: BookDetailResponse;
  member_id: string;
  librarian_id: string | null;
  checkout_date: string;
  due_date: string;
  return_date: string | null;
  renewal_count: number;
  status: LoanStatus;
  notes: string | null;
}

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

export default function LoansListPage() {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();

  const [loans, setLoans] = useState<LoanResponse[]>([]);
  const [loansLoading, setLoansLoading] = useState<boolean>(false);
  const [filterStatus, setFilterStatus] = useState<string>('');
  const [filterDateRange, setFilterDateRange] = useState<[any, any] | null>(null);
  const [searchMember, setSearchMember] = useState<string>('');
  const [searchBook, setSearchBook] = useState<string>('');
  const [pagination, setPagination] = useState<PaginationState>({
    current: 1,
    pageSize: 20,
    total: 0,
  });
  const [detailModalVisible, setDetailModalVisible] = useState<boolean>(false);
  const [selectedLoan, setSelectedLoan] = useState<LoanDetailResponse | null>(null);
  const [totalActiveLoans, setTotalActiveLoans] = useState<number>(0);
  const [overdueCount, setOverdueCount] = useState<number>(0);
  const [dueTodayCount, setDueTodayCount] = useState<number>(0);

  const filteredLoansCount = useMemo(() => pagination.total, [pagination.total]);

  const fetchLoans = useCallback(async () => {
    setLoansLoading(true);
    try {
      const queryParams: Record<string, any> = {
        limit: pagination.pageSize,
        offset: (pagination.current - 1) * pagination.pageSize,
      };
      if (filterStatus) {
        queryParams.loan_status = filterStatus;
      }
      if (searchMember) {
        queryParams.member_id = searchMember;
      }
      if (searchBook) {
        queryParams.book_id = searchBook;
      }

      const result = await request<LoanResponse[]>({
        method: 'GET',
        path: '/circulation/loans',
        query: queryParams,
      });

      setLoans(result.data);
      setPagination(prev => ({ ...prev, total: result.data.length }));
    } catch (error) {
      messageApi.error('Failed to load loans');
    } finally {
      setLoansLoading(false);
    }
  }, [pagination.pageSize, pagination.current, filterStatus, searchMember, searchBook, messageApi]);

  const fetchActiveLoansCount = useCallback(async () => {
    try {
      const result = await request<LoanResponse[]>({
        method: 'GET',
        path: '/circulation/loans',
        query: {
          loan_status: 'ACTIVE',
          limit: 1,
          offset: 0,
        },
      });
      setTotalActiveLoans(result.data.length);
    } catch (error) {
      messageApi.error('Failed to load active loans count');
    }
  }, [messageApi]);

  const fetchOverdueCount = useCallback(async () => {
    try {
      const result = await request<LoanResponse[]>({
        method: 'GET',
        path: '/circulation/loans',
        query: {
          loan_status: 'OVERDUE',
          limit: 1,
          offset: 0,
        },
      });
      setOverdueCount(result.data.length);
    } catch (error) {
      messageApi.error('Failed to load overdue count');
    }
  }, [messageApi]);

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

  useEffect(() => {
    fetchActiveLoansCount();
    fetchOverdueCount();
  }, [fetchActiveLoansCount, fetchOverdueCount]);

  const handleStatusFilterChange = (value: string) => {
    setFilterStatus(value || '');
    setPagination(prev => ({ ...prev, current: 1 }));
  };

  const handleDateRangeChange = (dates: [any, any] | null) => {
    setFilterDateRange(dates);
    setPagination(prev => ({ ...prev, current: 1 }));
  };

  const handleMemberSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchMember(e.target.value);
    setPagination(prev => ({ ...prev, current: 1 }));
  };

  const handleBookSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchBook(e.target.value);
    setPagination(prev => ({ ...prev, current: 1 }));
  };

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

  const handleViewDetails = async (record: LoanResponse) => {
    try {
      const result = await request<LoanDetailResponse>({
        method: 'GET',
        path: '/circulation/loans/{loan_id}/details',
        pathParams: { loan_id: record.id },
      });
      setSelectedLoan(result.data);
      setDetailModalVisible(true);
    } catch (error) {
      messageApi.error('Failed to load loan details');
    }
  };

  const handleRenewLoan = async (record: LoanResponse) => {
    Modal.confirm({
      title: 'Confirm Renewal',
      content: 'Are you sure you want to renew this loan?',
      onOk: async () => {
        try {
          await request<LoanResponse>({
            method: 'POST',
            path: '/circulation/loans/{loan_id}/renew',
            pathParams: { loan_id: record.id },
          });
          messageApi.success('Loan renewed successfully!');
          fetchLoans();
        } catch (error) {
          messageApi.error('Failed to renew loan. The book may be reserved or renewal limit reached.');
        }
      },
    });
  };

  const handleProcessReturn = (record: LoanResponse) => {
    navigate(ROUTES.CIRCULATION_RETURN || '/circulation/return');
  };

  const handleNewCheckout = () => {
    navigate(ROUTES.CIRCULATION_CHECKOUT || '/circulation/checkout');
  };

  const handleExportCsv = () => {
    try {
      const csvContent = [
        ['Loan ID', 'Book ID', 'Member ID', 'Checkout Date', 'Due Date', 'Return Date', 'Renewal Count', 'Status'],
        ...loans.map(loan => [
          loan.id,
          loan.book_id,
          loan.member_id,
          loan.checkout_date,
          loan.due_date,
          loan.return_date || '',
          loan.renewal_count.toString(),
          loan.status,
        ]),
      ]
        .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', 'loans_export.csv');
      link.style.visibility = 'hidden';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      messageApi.success('Export completed');
    } catch (error) {
      messageApi.error('Failed to export data');
    }
  };

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

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

  const columns = useMemo(
    () => [
      {
        title: 'Loan ID',
        dataIndex: 'id',
        key: 'id',
        width: 100,
        ellipsis: true,
      },
      {
        title: 'Book Title',
        dataIndex: 'book_id',
        key: 'book_id',
      },
      {
        title: 'Member',
        dataIndex: 'member_id',
        key: 'member_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) => new Date(date).toLocaleDateString(),
      },
      {
        title: 'Return Date',
        dataIndex: 'return_date',
        key: 'return_date',
        render: (date: string | null) => (date ? new Date(date).toLocaleDateString() : '-'),
      },
      {
        title: 'Renewals',
        dataIndex: 'renewal_count',
        key: 'renewal_count',
        render: (count: number) => <Badge count={count} showZero />,
      },
      {
        title: 'Status',
        dataIndex: 'status',
        key: 'status',
        render: (status: LoanStatus) => <Tag color={getStatusColor(status)}>{status}</Tag>,
      },
      {
        title: 'Actions',
        key: 'actions',
        fixed: 'right' as const,
        width: 200,
        render: (_: any, record: LoanResponse) => (
          <Space size="small">
            <Button
              type="link"
              size="small"
              icon={<EyeOutlined />}
              onClick={() => handleViewDetails(record)}
            >
              View
            </Button>
            <Button
              type="link"
              size="small"
              icon={<ReloadOutlined />}
              onClick={() => handleRenewLoan(record)}
              disabled={record.status !== 'ACTIVE'}
            >
              Renew
            </Button>
            <Button
              type="link"
              size="small"
              icon={<RollbackOutlined />}
              onClick={() => handleProcessReturn(record)}
              disabled={record.status === 'RETURNED'}
            >
              Return
            </Button>
          </Space>
        ),
      },
    ],
    []
  );

  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 }}>
          Loans Management
        </Typography.Title>
        <Space>
          <Button type="primary" icon={<PlusOutlined />} onClick={handleNewCheckout}>
            New Checkout
          </Button>
          <Button icon={<DownloadOutlined />} onClick={handleExportCsv}>
            Export CSV
          </Button>
        </Space>
      </div>

      <Row gutter={[16, 16]} style={{ marginBottom: '24px' }}>
        <Col xs={24} sm={8}>
          <Card>
            <Statistic
              title="Total Active Loans"
              value={totalActiveLoans}
              valueStyle={{ color: '#1677ff' }}
              prefix={<BookOutlined />}
            />
          </Card>
        </Col>
        <Col xs={24} sm={8}>
          <Card>
            <Statistic
              title="Overdue"
              value={overdueCount}
              valueStyle={{ color: '#ff4d4f' }}
              prefix={<WarningOutlined />}
            />
          </Card>
        </Col>
        <Col xs={24} sm={8}>
          <Card>
            <Statistic
              title="Due Today"
              value={dueTodayCount}
              valueStyle={{ color: '#faad14' }}
              prefix={<ClockCircleOutlined />}
            />
          </Card>
        </Col>
      </Row>

      <Card size="small" style={{ marginBottom: '16px' }}>
        <Row gutter={[16, 16]} align="middle">
          <Col xs={24} sm={12} md={6}>
            <Select
              placeholder="All Statuses"
              allowClear
              value={filterStatus || undefined}
              onChange={handleStatusFilterChange}
              style={{ width: '100%' }}
              options={[
                { label: 'Active', value: 'ACTIVE' },
                { label: 'Returned', value: 'RETURNED' },
                { label: 'Overdue', value: 'OVERDUE' },
                { label: 'Lost', value: 'LOST' },
              ]}
            />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <DatePicker.RangePicker
              value={filterDateRange}
              onChange={handleDateRangeChange}
              style={{ width: '100%' }}
              placeholder={['Start Date', 'End Date']}
            />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <Input.Search
              placeholder="Search by member ID..."
              allowClear
              value={searchMember}
              onChange={handleMemberSearchChange}
            />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <Input.Search
              placeholder="Search by book ID..."
              allowClear
              value={searchBook}
              onChange={handleBookSearchChange}
            />
          </Col>
        </Row>
      </Card>

      <Card bodyStyle={{ padding: 0 }}>
        <Table
          rowKey="id"
          dataSource={loans}
          columns={columns}
          loading={loansLoading}
          pagination={{
            current: pagination.current,
            pageSize: pagination.pageSize,
            total: pagination.total,
            showSizeChanger: true,
            showTotal: (total) => `Total ${total} items`,
            onChange: handlePaginationChange,
          }}
          scroll={{ x: 1200 }}
        />
      </Card>

      <Modal
        title="Loan Details"
        open={detailModalVisible}
        onCancel={handleCloseDetailModal}
        footer={null}
        width={700}
      >
        {selectedLoan && (
          <Descriptions bordered column={2}>
            <Descriptions.Item label="Loan ID" span={2}>
              {selectedLoan.id}
            </Descriptions.Item>
            <Descriptions.Item label="Status">
              <Tag color={getStatusColor(selectedLoan.status)}>{selectedLoan.status}</Tag>
            </Descriptions.Item>
            <Descriptions.Item label="Book ID">{selectedLoan.book_id}</Descriptions.Item>
            <Descriptions.Item label="Member ID">{selectedLoan.member_id}</Descriptions.Item>
            <Descriptions.Item label="Librarian ID">{selectedLoan.librarian_id || '-'}</Descriptions.Item>
            <Descriptions.Item label="Checkout Date">
              {new Date(selectedLoan.checkout_date).toLocaleDateString()}
            </Descriptions.Item>
            <Descriptions.Item label="Due Date">
              {new Date(selectedLoan.due_date).toLocaleDateString()}
            </Descriptions.Item>
            <Descriptions.Item label="Return Date">
              {selectedLoan.return_date ? new Date(selectedLoan.return_date).toLocaleDateString() : '-'}
            </Descriptions.Item>
            <Descriptions.Item label="Renewal Count">{selectedLoan.renewal_count}</Descriptions.Item>
            <Descriptions.Item label="Notes" span={2}>
              {selectedLoan.notes || '-'}
            </Descriptions.Item>
          </Descriptions>
        )}
      </Modal>
    </div>
  );
}