import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import { Layout, Typography, Space, Button, Row, Col, Card, Statistic, Table, List, message, Modal, Tag } from 'antd';
import { SearchOutlined, UserOutlined, BookOutlined, ClockCircleOutlined, DollarOutlined } 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;
  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 ReservationResponse {
  id: string;
  book_id: string;
  member_id: string;
  reservation_date: string;
  expiry_date: string | null;
  queue_position: number;
  status: 'PENDING' | 'READY' | 'FULFILLED' | 'CANCELLED' | 'EXPIRED';
  notified_date: string | null;
  created_at: string;
  updated_at: string;
}

interface FineResponse {
  id: string;
  member_id: string;
  loan_id: string | null;
  amount: number;
  amount_paid: number;
  reason: 'OVERDUE' | 'DAMAGED' | 'LOST' | 'OTHER';
  description: string | null;
  status: 'UNPAID' | 'PARTIAL' | 'PAID' | 'WAIVED';
  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 NotificationResponse {
  id: string;
  member_id: string;
  notification_type: 'DUE_DATE' | 'OVERDUE' | 'RESERVATION_READY' | 'FINE_ASSESSED' | 'GENERAL' | 'ANNOUNCEMENT';
  title: string;
  message: string;
  status: 'UNREAD' | 'READ' | 'ARCHIVED';
  sent_date: string;
  read_date: string | null;
  created_at: string;
  updated_at: string;
}

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

  const [loans, setLoans] = useState<LoanResponse[]>([]);
  const [reservations, setReservations] = useState<ReservationResponse[]>([]);
  const [fines, setFines] = useState<FineResponse[]>([]);
  const [notifications, setNotifications] = useState<NotificationResponse[]>([]);
  const [loansLoading, setLoansLoading] = useState<boolean>(true);
  const [reservationsLoading, setReservationsLoading] = useState<boolean>(true);
  const [finesLoading, setFinesLoading] = useState<boolean>(true);
  const [notificationsLoading, setNotificationsLoading] = useState<boolean>(true);

  const activeLoansCount = useMemo(() => {
    return loans.filter(l => l.status === 'ACTIVE' || l.status === 'OVERDUE').length;
  }, [loans]);

  const activeReservationsCount = useMemo(() => {
    return reservations.filter(r => r.status === 'PENDING' || r.status === 'READY').length;
  }, [reservations]);

  const outstandingFinesTotal = useMemo(() => {
    return fines
      .filter(f => f.status === 'UNPAID' || f.status === 'PARTIAL')
      .reduce((sum, f) => sum + (f.amount - f.amount_paid), 0);
  }, [fines]);

  const fetchMemberLoans = useCallback(async () => {
    if (!currentUser?.memberId) return;
    try {
      setLoansLoading(true);
      const result = await request<LoanResponse[]>({
        method: 'GET',
        path: '/circulation/loans',
        query: {
          member_id: currentUser.memberId,
          limit: 20
        }
      });
      setLoans(result.data);
    } catch (error) {
      messageApi.error('Failed to load loans');
    } finally {
      setLoansLoading(false);
    }
  }, [currentUser?.memberId, messageApi]);

  const fetchMemberReservations = useCallback(async () => {
    if (!currentUser?.memberId) return;
    try {
      setReservationsLoading(true);
      const result = await request<ReservationResponse[]>({
        method: 'GET',
        path: '/circulation/reservations',
        query: {
          member_id: currentUser.memberId,
          limit: 20
        }
      });
      setReservations(result.data);
    } catch (error) {
      messageApi.error('Failed to load reservations');
    } finally {
      setReservationsLoading(false);
    }
  }, [currentUser?.memberId, messageApi]);

  const fetchMemberFines = useCallback(async () => {
    if (!currentUser?.memberId) return;
    try {
      setFinesLoading(true);
      const result = await request<FineResponse[]>({
        method: 'GET',
        path: '/fines/',
        query: {
          member_id: currentUser.memberId,
          limit: 20
        }
      });
      setFines(result.data);
    } catch (error) {
      messageApi.error('Failed to load fines');
    } finally {
      setFinesLoading(false);
    }
  }, [currentUser?.memberId, messageApi]);

  const fetchMemberNotifications = useCallback(async () => {
    if (!currentUser?.memberId) return;
    try {
      setNotificationsLoading(true);
      const result = await request<NotificationResponse[]>({
        method: 'GET',
        path: '/engagement/notifications',
        query: {
          member_id: currentUser.memberId,
          limit: 10
        }
      });
      setNotifications(result.data);
    } catch (error) {
      messageApi.error('Failed to load notifications');
    } finally {
      setNotificationsLoading(false);
    }
  }, [currentUser?.memberId, messageApi]);

  useEffect(() => {
    fetchMemberLoans();
    fetchMemberReservations();
    fetchMemberFines();
    fetchMemberNotifications();
  }, [fetchMemberLoans, fetchMemberReservations, fetchMemberFines, fetchMemberNotifications]);

  const handleRenewLoan = useCallback(async (loanId: string) => {
    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: loanId }
          });
          messageApi.success('Loan renewed successfully!');
          fetchMemberLoans();
        } catch (error) {
          messageApi.error('Unable to renew loan. It may be reserved or at max renewals.');
        }
      }
    });
  }, [messageApi, fetchMemberLoans]);

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

  const navigateToCatalog = useCallback(() => {
    navigate(ROUTES.CATALOG);
  }, [navigate]);

  const navigateToProfile = useCallback(() => {
    navigate(ROUTES.MEMBER_PROFILE);
  }, [navigate]);

  const navigateToLoans = useCallback(() => {
    navigate(ROUTES.MEMBER_LOANS);
  }, [navigate]);

  const navigateToReservations = useCallback(() => {
    navigate(ROUTES.MEMBER_RESERVATIONS);
  }, [navigate]);

  const navigateToFines = useCallback(() => {
    navigate(ROUTES.MEMBER_FINES);
  }, [navigate]);

  const navigateToNotifications = useCallback(() => {
    navigate(ROUTES.MEMBER_NOTIFICATIONS);
  }, [navigate]);

  const loansColumns = useMemo(() => [
    {
      title: 'Book',
      dataIndex: 'book_id',
      key: 'book_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: 'Renewals',
      dataIndex: 'renewal_count',
      key: 'renewal_count',
      render: (count: number) => `${count} / 2`
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      render: (status: string) => {
        const colorMap: Record<string, string> = {
          ACTIVE: 'green',
          OVERDUE: 'red',
          RETURNED: 'default'
        };
        return <Tag color={colorMap[status] || 'default'}>{status}</Tag>;
      }
    },
    {
      title: 'Action',
      key: 'action',
      render: (_: unknown, record: LoanResponse) => (
        <Button
          type="link"
          size="small"
          onClick={() => handleRenewLoan(record.id)}
          disabled={record.status !== 'ACTIVE' && record.status !== 'OVERDUE'}
        >
          Renew
        </Button>
      )
    }
  ], [handleRenewLoan]);

  const filteredFines = useMemo(() => {
    return fines.filter(f => f.status === 'UNPAID' || f.status === 'PARTIAL');
  }, [fines]);

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

  const pageHeaderStyle: CSSProperties = {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: '24px'
  };

  return (
    <div style={rootStyle}>
      {contextHolder}
      <div style={pageHeaderStyle}>
        <Typography.Title level={2} style={{ margin: 0 }}>
          My Dashboard
        </Typography.Title>
        <Space>
          <Button type="primary" icon={<SearchOutlined />} onClick={navigateToCatalog}>
            Browse Catalog
          </Button>
          <Button icon={<UserOutlined />} onClick={navigateToProfile}>
            My Profile
          </Button>
        </Space>
      </div>

      <Row gutter={[16, 16]} style={{ marginBottom: '24px' }}>
        <Col xs={24} sm={8}>
          <Card hoverable>
            <Statistic
              title="Current Loans"
              value={activeLoansCount}
              suffix="/ 5"
              prefix={<BookOutlined />}
              valueStyle={{ color: '#1677ff' }}
            />
          </Card>
        </Col>
        <Col xs={24} sm={8}>
          <Card hoverable>
            <Statistic
              title="Active Reservations"
              value={activeReservationsCount}
              prefix={<ClockCircleOutlined />}
              valueStyle={{ color: '#722ed1' }}
            />
          </Card>
        </Col>
        <Col xs={24} sm={8}>
          <Card hoverable>
            <Statistic
              title="Outstanding Fines"
              value={outstandingFinesTotal}
              prefix={<DollarOutlined />}
              precision={2}
              valueStyle={{ color: '#fa541c' }}
            />
          </Card>
        </Col>
      </Row>

      <Row gutter={[16, 16]}>
        <Col xs={24} lg={16}>
          <Card
            title="Current Loans"
            extra={
              <Button type="link" size="small" onClick={navigateToLoans}>
                View All
              </Button>
            }
            style={{ marginBottom: '16px' }}
          >
            <Table
              dataSource={loans}
              columns={loansColumns}
              size="small"
              pagination={false}
              loading={loansLoading}
              rowKey="id"
            />
          </Card>

          <Card
            title="Active Reservations"
            extra={
              <Button type="link" size="small" onClick={navigateToReservations}>
                View All
              </Button>
            }
            style={{ marginBottom: '16px' }}
          >
            <List
              dataSource={reservations}
              loading={reservationsLoading}
              renderItem={(item) => (
                <List.Item
                  actions={[
                    <Button
                      key="cancel"
                      type="link"
                      size="small"
                      onClick={() => handleCancelReservation(item.id)}
                      disabled={item.status !== 'PENDING' && item.status !== 'READY'}
                    >
                      Cancel
                    </Button>
                  ]}
                >
                  <List.Item.Meta
                    title={item.book_id}
                    description={`Reservation Date: ${new Date(item.reservation_date).toLocaleDateString()} | Queue Position: ${item.queue_position} | Estimated Availability: ${item.expiry_date ? new Date(item.expiry_date).toLocaleDateString() : 'N/A'}`}
                  />
                  <Tag>{item.status}</Tag>
                </List.Item>
              )}
            />
          </Card>
        </Col>

        <Col xs={24} lg={8}>
          <Card
            title="Outstanding Fines"
            extra={
              <Button type="link" size="small" onClick={navigateToFines}>
                View All Fines
              </Button>
            }
            style={{ marginBottom: '16px' }}
          >
            <List
              dataSource={filteredFines}
              loading={finesLoading}
              size="small"
              renderItem={(item) => (
                <List.Item>
                  <List.Item.Meta
                    title={item.reason}
                    description={`Amount: $${item.amount.toFixed(2)} | Paid: $${item.amount_paid.toFixed(2)} | Status: ${item.status}`}
                  />
                </List.Item>
              )}
            />
          </Card>

          <Card
            title="Recent Notifications"
            extra={
              <Button type="link" size="small" onClick={navigateToNotifications}>
                View All
              </Button>
            }
            style={{ marginBottom: '16px' }}
          >
            <List
              dataSource={notifications}
              loading={notificationsLoading}
              size="small"
              renderItem={(item) => (
                <List.Item>
                  <List.Item.Meta
                    title={item.title}
                    description={
                      <>
                        <div>{item.message}</div>
                        <div style={{ fontSize: '12px', color: '#999', marginTop: '4px' }}>
                          {new Date(item.sent_date).toLocaleString()}
                        </div>
                      </>
                    }
                  />
                  <Tag>{item.status}</Tag>
                </List.Item>
              )}
            />
          </Card>
        </Col>
      </Row>
    </div>
  );
}