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

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 LoanWithComputed extends LoanResponse {
  book_title?: string;
  barcode?: string;
  member_name?: string;
  member_email?: string;
  days_overdue?: number;
  fine_amount?: string;
  condition_status?: string;
}

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

  const [activeLoans, setActiveLoans] = useState<LoanWithComputed[]>([]);
  const [overdueLoans, setOverdueLoans] = useState<LoanWithComputed[]>([]);
  const [returnedTodayLoans, setReturnedTodayLoans] = useState<LoanWithComputed[]>([]);
  const [activeTab, setActiveTab] = useState<string>('active');
  const [searchText, setSearchText] = useState<string>('');
  const [dateRange, setDateRange] = useState<[any, any] | null>(null);
  const [loading, setLoading] = useState<boolean>(false);
  const [selectedOverdueIds, setSelectedOverdueIds] = useState<string[]>([]);
  const [returnModalVisible, setReturnModalVisible] = useState<boolean>(false);
  const [renewModalVisible, setRenewModalVisible] = useState<boolean>(false);
  const [selectedLoanId, setSelectedLoanId] = useState<string | null>(null);

  const filteredActiveLoans = useMemo(() => {
    return activeLoans.filter(l => 
      !searchText || 
      l.book_title?.toLowerCase().includes(searchText.toLowerCase()) || 
      l.member_name?.toLowerCase().includes(searchText.toLowerCase())
    );
  }, [activeLoans, searchText]);

  const filteredOverdueLoans = useMemo(() => {
    return overdueLoans.filter(l => 
      !searchText || 
      l.book_title?.toLowerCase().includes(searchText.toLowerCase()) || 
      l.member_name?.toLowerCase().includes(searchText.toLowerCase())
    );
  }, [overdueLoans, searchText]);

  const selectedOverdueCount = useMemo(() => {
    return selectedOverdueIds.length;
  }, [selectedOverdueIds]);

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

  const fetchOverdueLoans = useCallback(async () => {
    try {
      setLoading(true);
      const result = await request<LoanResponse[]>({
        method: 'GET',
        path: '/loans/',
        query: { status: 'OVERDUE', limit: 50 }
      });
      setOverdueLoans(result.data);
    } catch (error) {
      messageApi.error('Failed to load overdue loans');
    } finally {
      setLoading(false);
    }
  }, [messageApi]);

  const fetchReturnedLoans = useCallback(async () => {
    try {
      setLoading(true);
      const result = await request<LoanResponse[]>({
        method: 'GET',
        path: '/loans/',
        query: { status: 'RETURNED', limit: 50 }
      });
      setReturnedTodayLoans(result.data);
    } catch (error) {
      messageApi.error('Failed to load returned loans');
    } finally {
      setLoading(false);
    }
  }, [messageApi]);

  useEffect(() => {
    fetchActiveLoans();
    fetchOverdueLoans();
    fetchReturnedLoans();
  }, [fetchActiveLoans, fetchOverdueLoans, fetchReturnedLoans]);

  const returnBook = useCallback(async () => {
    if (!selectedLoanId) {
      messageApi.error('Please select a loan to return');
      return;
    }

    try {
      setLoading(true);
      await request<LoanResponse>({
        method: 'POST',
        path: '/loans/{loan_id}/return',
        pathParams: { loan_id: selectedLoanId },
        body: {
          checked_in_by_librarian_id: currentUser?.id || null,
          notes: null
        }
      });
      messageApi.success('Book returned successfully');
      setReturnModalVisible(false);
      setSelectedLoanId(null);
      await Promise.all([fetchActiveLoans(), fetchReturnedLoans(), fetchOverdueLoans()]);
    } catch (error) {
      messageApi.error('Failed to return book. Please try again.');
    } finally {
      setLoading(false);
    }
  }, [selectedLoanId, currentUser, messageApi, fetchActiveLoans, fetchReturnedLoans, fetchOverdueLoans]);

  const renewBook = useCallback(async () => {
    if (!selectedLoanId) {
      messageApi.error('Please select a loan to renew');
      return;
    }

    try {
      setLoading(true);
      await request<LoanResponse>({
        method: 'POST',
        path: '/loans/{loan_id}/renew',
        pathParams: { loan_id: selectedLoanId },
        body: { notes: null }
      });
      messageApi.success('Book renewed successfully. New due date has been set.');
      setRenewModalVisible(false);
      setSelectedLoanId(null);
      await fetchActiveLoans();
    } catch (error) {
      messageApi.error('Failed to renew book. It may be reserved or at max renewals.');
    } finally {
      setLoading(false);
    }
  }, [selectedLoanId, messageApi, fetchActiveLoans]);

  const openReturnModal = useCallback((record: LoanWithComputed) => {
    setSelectedLoanId(record.id);
    setReturnModalVisible(true);
  }, []);

  const openRenewModal = useCallback((record: LoanWithComputed) => {
    setSelectedLoanId(record.id);
    setRenewModalVisible(true);
  }, []);

  const closeReturnModal = useCallback(() => {
    setReturnModalVisible(false);
    setSelectedLoanId(null);
  }, []);

  const closeRenewModal = useCallback(() => {
    setRenewModalVisible(false);
    setSelectedLoanId(null);
  }, []);

  const sendOverdueNotifications = useCallback(async () => {
    if (selectedOverdueIds.length === 0) {
      messageApi.error('Please select at least one overdue loan');
      return;
    }

    Modal.confirm({
      title: 'Send Overdue Notifications',
      content: `Are you sure you want to send overdue notifications to ${selectedOverdueIds.length} member(s)?`,
      onOk: async () => {
        try {
          setLoading(true);
          messageApi.success('Overdue notifications sent to selected members');
          setSelectedOverdueIds([]);
        } catch (error) {
          messageApi.error('Failed to send some notifications. Please try again.');
        } finally {
          setLoading(false);
        }
      }
    });
  }, [selectedOverdueIds, messageApi]);

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

  const activeLoansColumns = useMemo(() => [
    {
      title: 'Loan ID',
      dataIndex: 'id',
      key: 'id',
      width: 100,
      ellipsis: true
    },
    {
      title: 'Book Title',
      dataIndex: 'book_title',
      key: 'book_title'
    },
    {
      title: 'Barcode',
      dataIndex: 'barcode',
      key: 'barcode',
      width: 120
    },
    {
      title: 'Member Name',
      dataIndex: 'member_name',
      key: 'member_name'
    },
    {
      title: 'Checkout Date',
      dataIndex: 'checkout_date',
      key: 'checkout_date',
      width: 130
    },
    {
      title: 'Due Date',
      dataIndex: 'due_date',
      key: 'due_date',
      width: 130
    },
    {
      title: 'Renewals',
      dataIndex: 'renewal_count',
      key: 'renewal_count',
      width: 100
    },
    {
      title: 'Actions',
      key: 'actions',
      width: 180,
      render: (_: unknown, record: LoanWithComputed) => (
        <div style={{ display: 'flex', gap: '8px' }}>
          <Button size="small" onClick={() => openReturnModal(record)}>Return</Button>
          <Button size="small" onClick={() => openRenewModal(record)}>Renew</Button>
        </div>
      )
    }
  ], [openReturnModal, openRenewModal]);

  const overdueColumns = useMemo(() => [
    {
      title: 'Loan ID',
      dataIndex: 'id',
      key: 'id',
      width: 100,
      ellipsis: true
    },
    {
      title: 'Book Title',
      dataIndex: 'book_title',
      key: 'book_title'
    },
    {
      title: 'Member Name',
      dataIndex: 'member_name',
      key: 'member_name'
    },
    {
      title: 'Member Email',
      dataIndex: 'member_email',
      key: 'member_email'
    },
    {
      title: 'Due Date',
      dataIndex: 'due_date',
      key: 'due_date',
      width: 130
    },
    {
      title: 'Days Overdue',
      dataIndex: 'days_overdue',
      key: 'days_overdue',
      width: 120
    },
    {
      title: 'Fine Amount',
      dataIndex: 'fine_amount',
      key: 'fine_amount',
      width: 120
    },
    {
      title: 'Actions',
      key: 'actions',
      width: 200,
      render: (_: unknown, record: LoanWithComputed) => (
        <div style={{ display: 'flex', gap: '8px' }}>
          <Button size="small" onClick={() => openReturnModal(record)}>Return</Button>
          <Button size="small" onClick={() => openRenewModal(record)}>Renew</Button>
        </div>
      )
    }
  ], [openReturnModal, openRenewModal]);

  const returnedColumns = useMemo(() => [
    {
      title: 'Loan ID',
      dataIndex: 'id',
      key: 'id',
      width: 100,
      ellipsis: true
    },
    {
      title: 'Book Title',
      dataIndex: 'book_title',
      key: 'book_title'
    },
    {
      title: 'Member Name',
      dataIndex: 'member_name',
      key: 'member_name'
    },
    {
      title: 'Return Date',
      dataIndex: 'return_date',
      key: 'return_date',
      width: 130
    },
    {
      title: 'Condition',
      dataIndex: 'condition_status',
      key: 'condition_status',
      width: 120
    },
    {
      title: 'Fine Applied',
      dataIndex: 'fine_amount',
      key: 'fine_amount',
      width: 120
    }
  ], []);

  const tabItems = useMemo(() => [
    {
      key: 'active',
      label: 'Active Loans',
      children: (
        <div>
          <Table
            columns={activeLoansColumns}
            dataSource={filteredActiveLoans}
            rowKey="id"
            pagination={{ pageSize: 20 }}
            loading={loading}
          />
        </div>
      )
    },
    {
      key: 'overdue',
      label: 'Overdue',
      children: (
        <div>
          {selectedOverdueCount > 0 && (
            <div style={{
              display: 'flex',
              justifyContent: 'space-between',
              alignItems: 'center',
              marginBottom: '16px',
              padding: '12px 16px',
              background: '#fff7e6',
              borderRadius: '6px',
              border: '1px solid #ffd591'
            }}>
              <Typography.Text type="warning">
                {selectedOverdueCount} item(s) selected
              </Typography.Text>
              <Button
                type="primary"
                danger
                icon={<MailOutlined />}
                onClick={sendOverdueNotifications}
                disabled={selectedOverdueIds.length === 0}
              >
                Send Overdue Notifications
              </Button>
            </div>
          )}
          <Table
            columns={overdueColumns}
            dataSource={filteredOverdueLoans}
            rowKey="id"
            rowSelection={{
              type: 'checkbox',
              selectedRowKeys: selectedOverdueIds,
              onChange: (selectedKeys: React.Key[]) => setSelectedOverdueIds(selectedKeys as string[])
            }}
            pagination={{ pageSize: 20 }}
            loading={loading}
          />
        </div>
      )
    },
    {
      key: 'returned',
      label: 'Returned Today',
      children: (
        <div>
          <Table
            columns={returnedColumns}
            dataSource={returnedTodayLoans}
            rowKey="id"
            pagination={{ pageSize: 20 }}
            loading={loading}
          />
        </div>
      )
    }
  ], [activeLoansColumns, filteredActiveLoans, loading, selectedOverdueCount, overdueColumns, filteredOverdueLoans, selectedOverdueIds, sendOverdueNotifications, returnedColumns, returnedTodayLoans]);

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

  return (
    <div style={rootStyle}>
      {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 }}>
            Circulation Management
          </Typography.Title>
        </div>
      </div>

      <Card bordered={false} style={{ marginBottom: '16px' }}>
        <div style={{
          display: 'flex',
          gap: '16px',
          flexWrap: 'wrap',
          alignItems: 'center'
        }}>
          <Input.Search
            placeholder="Search by member name or book title..."
            allowClear
            style={{ width: 320 }}
            value={searchText}
            onChange={(e) => setSearchText(e.target.value)}
          />
          <DatePicker.RangePicker
            placeholder={['Start Date', 'End Date']}
            value={dateRange}
            onChange={(dates) => setDateRange(dates)}
          />
        </div>
      </Card>

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

      <Modal
        title="Confirm Book Return"
        open={returnModalVisible}
        onOk={returnBook}
        onCancel={closeReturnModal}
        okText="Confirm Return"
        cancelText="Cancel"
      >
        <Typography.Text>
          Are you sure you want to process this book return? Any applicable overdue fines will be calculated automatically.
        </Typography.Text>
      </Modal>

      <Modal
        title="Confirm Book Renewal"
        open={renewModalVisible}
        onOk={renewBook}
        onCancel={closeRenewModal}
        okText="Confirm Renewal"
        cancelText="Cancel"
      >
        <Typography.Text>
          Are you sure you want to renew this loan? The due date will be extended by the standard loan period.
        </Typography.Text>
      </Modal>
    </div>
  );
}