import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import { Card, Input, Select, Table, Button, Drawer, Modal, Form, Descriptions, Statistic, Typography, Tag, Space, message } from 'antd';
import { ArrowLeftOutlined, EyeOutlined, EditOutlined, CheckOutlined, StopOutlined, PlayCircleOutlined } from '@ant-design/icons';
import { request } from '../api/client';
import { useNavigate } from 'react-router-dom';
import { ROUTES } from '../router/routes.constant';

type MembershipStatus = 'ACTIVE' | 'SUSPENDED' | 'EXPIRED' | 'CANCELLED';
type LoanStatus = 'ACTIVE' | 'RETURNED' | 'OVERDUE' | 'LOST';
type ReservationStatus = 'PENDING' | 'READY' | 'FULFILLED' | 'CANCELLED' | 'EXPIRED';
type PaymentStatus = 'UNPAID' | 'PARTIALLY_PAID' | 'PAID' | 'WAIVED';

interface UserResponse {
  id: string;
  email: string;
  first_name: string;
  last_name: string;
  phone?: string | null;
}

interface MemberResponse {
  id: string;
  membership_number: string;
  user: UserResponse;
  membership_status?: MembershipStatus;
  join_date?: string;
  date_of_birth?: string | null;
  address?: string | null;
  library_branch_id?: string | null;
}

interface MemberDetailResponse {
  id: string;
  membership_number: string;
  user: UserResponse;
  library_branch?: { id: string; name: string; address: string } | null;
  membership_status?: MembershipStatus;
  join_date?: string;
  date_of_birth?: string | null;
  address?: string | null;
}

interface LibraryBranchResponse {
  id: string;
  name: string;
  address: string;
}

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: LoanStatus;
}

interface ReservationResponse {
  id: string;
  member_id: string;
  book_id: string;
  reservation_date: string;
  expiration_date: string;
  status: ReservationStatus;
  priority_order?: number | null;
}

interface FineResponse {
  id: string;
  member_id: string;
  loan_id?: string | null;
  amount: number;
  reason: string;
  issue_date: string;
  payment_status: PaymentStatus;
  amount_paid?: number;
}

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

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

  const [members, setMembers] = useState<MemberResponse[]>([]);
  const [membersLoading, setMembersLoading] = useState<boolean>(false);
  const [searchText, setSearchText] = useState<string>('');
  const [statusFilter, setStatusFilter] = useState<string>('');
  const [branchFilter, setBranchFilter] = useState<string>('');
  const [branches, setBranches] = useState<LibraryBranchResponse[]>([]);
  const [selectedMemberId, setSelectedMemberId] = useState<string>('');
  const [selectedMemberDetail, setSelectedMemberDetail] = useState<MemberDetailResponse | null>(null);
  const [detailDrawerVisible, setDetailDrawerVisible] = useState<boolean>(false);
  const [editModalVisible, setEditModalVisible] = useState<boolean>(false);
  const [editingMember, setEditingMember] = useState<MemberResponse | null>(null);
  const [memberLoans, setMemberLoans] = useState<LoanResponse[]>([]);
  const [memberReservations, setMemberReservations] = useState<ReservationResponse[]>([]);
  const [memberFines, setMemberFines] = useState<FineResponse[]>([]);
  const [pagination, setPagination] = useState<PaginationState>({
    current: 1,
    pageSize: 20,
    total: 0,
  });

  const [form] = Form.useForm();

  const fetchMembers = useCallback(async () => {
    setMembersLoading(true);
    try {
      const query: Record<string, string | number> = {
        limit: pagination.pageSize,
        offset: (pagination.current - 1) * pagination.pageSize,
      };
      if (statusFilter) {
        query.membership_status = statusFilter;
      }
      if (branchFilter) {
        query.library_branch_id = branchFilter;
      }
      const result = await request<MemberResponse[]>({
        method: 'GET',
        path: '/auth/members',
        query,
      });
      setMembers(result.data);
      setPagination((prev) => ({ ...prev, total: result.data.length }));
    } catch (error) {
      messageApi.error('Failed to load members');
    } finally {
      setMembersLoading(false);
    }
  }, [pagination.current, pagination.pageSize, statusFilter, branchFilter, messageApi]);

  const fetchBranches = useCallback(async () => {
    try {
      const result = await request<LibraryBranchResponse[]>({
        method: 'GET',
        path: '/library-branches/',
        query: { limit: 100, offset: 0 },
      });
      setBranches(result.data);
    } catch (error) {
      messageApi.error('Failed to load branches');
    }
  }, [messageApi]);

  const fetchMemberDetails = useCallback(async (memberId: string) => {
    try {
      const result = await request<MemberDetailResponse>({
        method: 'GET',
        path: '/auth/members/{member_id}/details',
        pathParams: { member_id: memberId },
      });
      setSelectedMemberDetail(result.data);
    } catch (error) {
      messageApi.error('Failed to load member details');
    }
  }, [messageApi]);

  const fetchMemberLoans = useCallback(async (memberId: string) => {
    try {
      const result = await request<LoanResponse[]>({
        method: 'GET',
        path: '/loans/',
        query: { member_id: memberId, limit: 50, offset: 0 },
      });
      setMemberLoans(result.data);
    } catch (error) {
      messageApi.error('Failed to load member loans');
    }
  }, [messageApi]);

  const fetchMemberReservations = useCallback(async (memberId: string) => {
    try {
      const result = await request<ReservationResponse[]>({
        method: 'GET',
        path: '/reservations/',
        query: { member_id: memberId, limit: 50, offset: 0 },
      });
      setMemberReservations(result.data);
    } catch (error) {
      messageApi.error('Failed to load member reservations');
    }
  }, [messageApi]);

  const fetchMemberFines = useCallback(async (memberId: string) => {
    try {
      const result = await request<FineResponse[]>({
        method: 'GET',
        path: '/fines/',
        query: { member_id: memberId, limit: 50, offset: 0 },
      });
      setMemberFines(result.data);
    } catch (error) {
      messageApi.error('Failed to load member fines');
    }
  }, [messageApi]);

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

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

  useEffect(() => {
    if (selectedMemberId && detailDrawerVisible) {
      fetchMemberDetails(selectedMemberId);
      fetchMemberLoans(selectedMemberId);
      fetchMemberReservations(selectedMemberId);
      fetchMemberFines(selectedMemberId);
    }
  }, [selectedMemberId, detailDrawerVisible, fetchMemberDetails, fetchMemberLoans, fetchMemberReservations, fetchMemberFines]);

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

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

  const handleBranchFilterChange = (value: string) => {
    setBranchFilter(value);
    setPagination((prev) => ({ ...prev, current: 1 }));
  };

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

  const handleViewDetails = (record: MemberResponse) => {
    setSelectedMemberId(record.id);
    setDetailDrawerVisible(true);
  };

  const handleDrawerClose = () => {
    setDetailDrawerVisible(false);
    setSelectedMemberId('');
    setSelectedMemberDetail(null);
  };

  const handleEditMember = (record: MemberResponse) => {
    setEditingMember(record);
    setEditModalVisible(true);
    form.setFieldsValue({
      membership_number: record.membership_number,
      membership_status: record.membership_status,
      date_of_birth: record.date_of_birth,
      address: record.address,
      library_branch_id: record.library_branch_id,
      join_date: record.join_date,
    });
  };

  const handleEditModalClose = () => {
    setEditModalVisible(false);
    setEditingMember(null);
    form.resetFields();
  };

  const handleEditSubmit = async () => {
    try {
      const values = await form.validateFields();
      if (!editingMember) return;

      await request<MemberResponse>({
        method: 'PUT',
        path: '/auth/members/{member_id}',
        pathParams: { member_id: editingMember.id },
        body: values,
      });

      messageApi.success('Member updated successfully');
      setEditModalVisible(false);
      setEditingMember(null);
      form.resetFields();
      fetchMembers();
    } catch (error) {
      messageApi.error('Failed to update member');
    }
  };

  const handleApproveMember = async (memberId: string) => {
    Modal.confirm({
      title: 'Approve Member',
      content: 'Are you sure you want to approve this member?',
      onOk: async () => {
        try {
          await request<MemberResponse>({
            method: 'PUT',
            path: '/auth/members/{member_id}',
            pathParams: { member_id: memberId },
            body: { membership_status: 'ACTIVE' },
          });
          messageApi.success('Member approved successfully');
          fetchMembers();
        } catch (error) {
          messageApi.error('Failed to approve member');
        }
      },
    });
  };

  const handleSuspendMember = async (memberId: string) => {
    Modal.confirm({
      title: 'Suspend Member',
      content: 'Are you sure you want to suspend this member?',
      onOk: async () => {
        try {
          await request<MemberResponse>({
            method: 'PUT',
            path: '/auth/members/{member_id}',
            pathParams: { member_id: memberId },
            body: { membership_status: 'SUSPENDED' },
          });
          messageApi.warning('Member suspended');
          fetchMembers();
        } catch (error) {
          messageApi.error('Failed to suspend member');
        }
      },
    });
  };

  const handleActivateMember = async (memberId: string) => {
    Modal.confirm({
      title: 'Activate Member',
      content: 'Are you sure you want to activate this member?',
      onOk: async () => {
        try {
          await request<MemberResponse>({
            method: 'PUT',
            path: '/auth/members/{member_id}',
            pathParams: { member_id: memberId },
            body: { membership_status: 'ACTIVE' },
          });
          messageApi.success('Member activated successfully');
          fetchMembers();
        } catch (error) {
          messageApi.error('Failed to activate member');
        }
      },
    });
  };

  const handleNavigateBack = () => {
    navigate(ROUTES.STAFF_DASHBOARD || '/staff/dashboard');
  };

  const getStatusColor = (status: string): string => {
    const colorMap: Record<string, string> = {
      ACTIVE: 'green',
      SUSPENDED: 'orange',
      EXPIRED: 'red',
      CANCELLED: 'default',
      RETURNED: 'default',
      OVERDUE: 'red',
      LOST: 'red',
      PENDING: 'blue',
      READY: 'green',
      FULFILLED: 'default',
      UNPAID: 'red',
      PAID: 'green',
      PARTIALLY_PAID: 'orange',
      WAIVED: 'default',
    };
    return colorMap[status] || 'default';
  };

  const columns = useMemo(() => [
    {
      title: 'Membership #',
      dataIndex: 'membership_number',
      key: 'membership_number',
      width: 140,
    },
    {
      title: 'Full Name',
      key: 'full_name',
      render: (_: unknown, record: MemberResponse) => `${record.user.first_name} ${record.user.last_name}`,
    },
    {
      title: 'Email',
      dataIndex: ['user', 'email'],
      key: 'email',
    },
    {
      title: 'Phone',
      dataIndex: ['user', 'phone'],
      key: 'phone',
      render: (phone: string | null | undefined) => phone || '-',
    },
    {
      title: 'Join Date',
      dataIndex: 'join_date',
      key: 'join_date',
      render: (date: string | undefined) => date || '-',
    },
    {
      title: 'Status',
      dataIndex: 'membership_status',
      key: 'membership_status',
      render: (status: MembershipStatus | undefined) => status ? <Tag color={getStatusColor(status)}>{status}</Tag> : '-',
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, record: MemberResponse) => (
        <Space size="small">
          <Button size="small" icon={<EyeOutlined />} onClick={() => handleViewDetails(record)}>
            View
          </Button>
          <Button size="small" icon={<EditOutlined />} onClick={() => handleEditMember(record)}>
            Edit
          </Button>
          {record.membership_status === 'ACTIVE' && (
            <Button size="small" icon={<StopOutlined />} onClick={() => handleSuspendMember(record.id)}>
              Suspend
            </Button>
          )}
          {record.membership_status === 'SUSPENDED' && (
            <Button size="small" icon={<PlayCircleOutlined />} onClick={() => handleActivateMember(record.id)}>
              Activate
            </Button>
          )}
        </Space>
      ),
    },
  ], []);

  const loanColumns = useMemo(() => [
    {
      title: 'Book Copy',
      dataIndex: 'book_copy_id',
      key: 'book_copy_id',
    },
    {
      title: 'Checkout Date',
      dataIndex: 'checkout_date',
      key: 'checkout_date',
    },
    {
      title: 'Due Date',
      dataIndex: 'due_date',
      key: 'due_date',
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      render: (status: LoanStatus) => <Tag color={getStatusColor(status)}>{status}</Tag>,
    },
  ], []);

  const reservationColumns = useMemo(() => [
    {
      title: 'Book',
      dataIndex: 'book_id',
      key: 'book_id',
    },
    {
      title: 'Reserved Date',
      dataIndex: 'reservation_date',
      key: 'reservation_date',
    },
    {
      title: 'Expiration',
      dataIndex: 'expiration_date',
      key: 'expiration_date',
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      render: (status: ReservationStatus) => <Tag color={getStatusColor(status)}>{status}</Tag>,
    },
    {
      title: 'Queue Position',
      dataIndex: 'priority_order',
      key: 'priority_order',
      render: (order: number | null | undefined) => order || '-',
    },
  ], []);

  const fineColumns = useMemo(() => [
    {
      title: 'Amount',
      dataIndex: 'amount',
      key: 'amount',
      render: (amount: number) => `$${amount.toFixed(2)}`,
    },
    {
      title: 'Reason',
      dataIndex: 'reason',
      key: 'reason',
    },
    {
      title: 'Issue Date',
      dataIndex: 'issue_date',
      key: 'issue_date',
    },
    {
      title: 'Payment Status',
      dataIndex: 'payment_status',
      key: 'payment_status',
      render: (status: PaymentStatus) => <Tag color={getStatusColor(status)}>{status}</Tag>,
    },
    {
      title: 'Amount Paid',
      dataIndex: 'amount_paid',
      key: 'amount_paid',
      render: (amount: number | undefined) => amount ? `$${amount.toFixed(2)}` : '$0.00',
    },
  ], []);

  const activeLoansCount = useMemo(() => memberLoans.filter((l) => l.status === 'ACTIVE').length, [memberLoans]);
  const totalLoansCount = useMemo(() => memberLoans.length, [memberLoans]);
  const activeReservationsCount = useMemo(
    () => memberReservations.filter((r) => r.status === 'PENDING' || r.status === 'READY').length,
    [memberReservations]
  );
  const outstandingFinesAmount = useMemo(
    () => memberFines.filter((f) => f.payment_status === 'UNPAID').reduce((sum, f) => sum + f.amount, 0),
    [memberFines]
  );

  const branchOptions = useMemo(() => branches.map((b) => ({ label: b.name, value: b.id })), [branches]);

  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',
  };

  const headerLeftStyle: CSSProperties = {
    display: 'flex',
    alignItems: 'center',
    gap: '12px',
  };

  const filtersRowStyle: CSSProperties = {
    display: 'flex',
    gap: '16px',
    flexWrap: 'wrap',
    alignItems: 'center',
  };

  const drawerContentStyle: CSSProperties = {
    display: 'flex',
    flexDirection: 'column',
    gap: '24px',
  };

  const statsRowStyle: CSSProperties = {
    display: 'flex',
    gap: '24px',
    flexWrap: 'wrap',
  };

  return (
    <div style={rootStyle}>
      {contextHolder}
      <div style={pageHeaderStyle}>
        <div style={headerLeftStyle}>
          <Button type="text" icon={<ArrowLeftOutlined />} onClick={handleNavigateBack}>
            Back
          </Button>
          <Typography.Title level={3} style={{ margin: 0 }}>
            Member Management
          </Typography.Title>
        </div>
      </div>

      <Card bordered={false} style={{ marginBottom: '16px' }}>
        <div style={filtersRowStyle}>
          <Input.Search
            placeholder="Search by name, email, phone, or membership #"
            allowClear
            style={{ width: 360 }}
            value={searchText}
            onChange={handleSearchChange}
          />
          <Select
            placeholder="Filter by Status"
            allowClear
            style={{ width: 180 }}
            value={statusFilter || undefined}
            onChange={handleStatusFilterChange}
            options={[
              { label: 'Active', value: 'ACTIVE' },
              { label: 'Suspended', value: 'SUSPENDED' },
              { label: 'Expired', value: 'EXPIRED' },
              { label: 'Cancelled', value: 'CANCELLED' },
            ]}
          />
          <Select
            placeholder="Filter by Branch"
            allowClear
            style={{ width: 200 }}
            value={branchFilter || undefined}
            onChange={handleBranchFilterChange}
            options={branchOptions}
          />
        </div>
      </Card>

      <Card bordered={false}>
        <Table
          rowKey="id"
          dataSource={members}
          columns={columns}
          loading={membersLoading}
          pagination={{
            current: pagination.current,
            pageSize: pagination.pageSize,
            total: pagination.total,
            showSizeChanger: true,
            showTotal: (total) => `Total ${total} members`,
            onChange: handlePaginationChange,
          }}
        />
      </Card>

      <Drawer
        title="Member Details"
        width={720}
        placement="right"
        open={detailDrawerVisible}
        onClose={handleDrawerClose}
      >
        {selectedMemberDetail && (
          <div style={drawerContentStyle}>
            <Descriptions title="Profile Information" bordered column={2}>
              <Descriptions.Item label="Membership #">{selectedMemberDetail.membership_number}</Descriptions.Item>
              <Descriptions.Item label="Status">
                {selectedMemberDetail.membership_status ? (
                  <Tag color={getStatusColor(selectedMemberDetail.membership_status)}>
                    {selectedMemberDetail.membership_status}
                  </Tag>
                ) : (
                  '-'
                )}
              </Descriptions.Item>
              <Descriptions.Item label="Full Name">
                {selectedMemberDetail.user.first_name} {selectedMemberDetail.user.last_name}
              </Descriptions.Item>
              <Descriptions.Item label="Email">{selectedMemberDetail.user.email}</Descriptions.Item>
              <Descriptions.Item label="Phone">{selectedMemberDetail.user.phone || '-'}</Descriptions.Item>
              <Descriptions.Item label="Date of Birth">{selectedMemberDetail.date_of_birth || '-'}</Descriptions.Item>
              <Descriptions.Item label="Address" span={2}>
                {selectedMemberDetail.address || '-'}
              </Descriptions.Item>
              <Descriptions.Item label="Branch">
                {selectedMemberDetail.library_branch?.name || '-'}
              </Descriptions.Item>
              <Descriptions.Item label="Join Date">{selectedMemberDetail.join_date || '-'}</Descriptions.Item>
            </Descriptions>

            <Card title="Borrowing Statistics" size="small">
              <div style={statsRowStyle}>
                <Statistic title="Active Loans" value={activeLoansCount} />
                <Statistic title="Total Loans" value={totalLoansCount} />
                <Statistic title="Active Reservations" value={activeReservationsCount} />
                <Statistic title="Outstanding Fines" value={outstandingFinesAmount} prefix="$" precision={2} />
              </div>
            </Card>

            <Table
              title={() => 'Current Loans'}
              rowKey="id"
              dataSource={memberLoans}
              columns={loanColumns}
              size="small"
              pagination={{ pageSize: 5 }}
            />

            <Table
              title={() => 'Reservations'}
              rowKey="id"
              dataSource={memberReservations}
              columns={reservationColumns}
              size="small"
              pagination={{ pageSize: 5 }}
            />

            <Table
              title={() => 'Fine History'}
              rowKey="id"
              dataSource={memberFines}
              columns={fineColumns}
              size="small"
              pagination={{ pageSize: 5 }}
            />
          </div>
        )}
      </Drawer>

      <Modal
        title="Edit Member"
        open={editModalVisible}
        onCancel={handleEditModalClose}
        onOk={handleEditSubmit}
        width={640}
        okText="Save Changes"
        cancelText="Cancel"
      >
        <Form form={form} layout="vertical">
          <Form.Item
            name="membership_number"
            label="Membership Number"
            rules={[{ required: true, message: 'Membership number is required' }]}
          >
            <Input />
          </Form.Item>
          <Form.Item name="membership_status" label="Status">
            <Select
              options={[
                { label: 'Active', value: 'ACTIVE' },
                { label: 'Suspended', value: 'SUSPENDED' },
                { label: 'Expired', value: 'EXPIRED' },
                { label: 'Cancelled', value: 'CANCELLED' },
              ]}
            />
          </Form.Item>
          <Form.Item name="date_of_birth" label="Date of Birth">
            <Input type="date" />
          </Form.Item>
          <Form.Item name="address" label="Address">
            <Input.TextArea />
          </Form.Item>
          <Form.Item name="library_branch_id" label="Library Branch">
            <Select options={branchOptions} />
          </Form.Item>
          <Form.Item name="join_date" label="Join Date">
            <Input type="date" />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}