import { useState, useMemo, useEffect, useCallback } from 'react';
import { Layout, Typography, Breadcrumb, Space, Button, Card, Input, Row, Col, Descriptions, Alert, Select, Statistic, Result, List, Modal, message } from 'antd';
import { ArrowLeftOutlined, CheckCircleOutlined, ReloadOutlined } 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: string;
  notes: string | null;
  created_at: string;
  updated_at: string;
}

interface BookResponse {
  id: string;
  isbn: string | null;
  title: string;
  subtitle: string | null;
  publisher_id: string | null;
  publication_date: string | null;
  edition: string | null;
  language: string;
  pages: number | null;
  description: string | null;
  book_format: string;
  total_copies: number;
  available_copies: number;
  location: string | null;
  status: string;
  created_at: string;
  updated_at: string;
}

interface MemberDetailResponse {
  id: string;
  user_id: string;
  membership_number: string;
  user: {
    id: string;
    email: string;
    first_name: string;
    last_name: string;
  };
}

interface ReservationResponse {
  id: string;
  book_id: string;
  member_id: string;
  reservation_date: string;
  expiry_date: string | null;
  queue_position: number;
  status: string;
  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: string;
  description: string | null;
  status: string;
  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;
}

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

  const [searchQuery, setSearchQuery] = useState<string>('');
  const [selectedLoan, setSelectedLoan] = useState<LoanResponse | null>(null);
  const [bookInfo, setBookInfo] = useState<BookResponse | null>(null);
  const [memberInfo, setMemberInfo] = useState<MemberDetailResponse | null>(null);
  const [damageLevel, setDamageLevel] = useState<string>('');
  const [loading, setLoading] = useState<boolean>(false);
  const [returnProcessing, setReturnProcessing] = useState<boolean>(false);
  const [returnResult, setReturnResult] = useState<LoanResponse | null>(null);
  const [pendingReservations, setPendingReservations] = useState<ReservationResponse[]>([]);
  const [overdueFineCreated, setOverdueFineCreated] = useState<FineResponse | null>(null);
  const [damageFineCreated, setDamageFineCreated] = useState<FineResponse | null>(null);

  const isOverdue = useMemo(() => {
    return selectedLoan ? new Date() > new Date(selectedLoan.due_date) : false;
  }, [selectedLoan]);

  const overdueDays = useMemo(() => {
    if (selectedLoan && new Date() > new Date(selectedLoan.due_date)) {
      return Math.ceil((new Date().getTime() - new Date(selectedLoan.due_date).getTime()) / (1000 * 60 * 60 * 24));
    }
    return 0;
  }, [selectedLoan]);

  const overdueFineAmount = useMemo(() => {
    const dailyRate = librarySettings?.dailyFineRate || 0.5;
    const maxCap = librarySettings?.maxFineCap || 25;
    return Math.min(overdueDays * dailyRate, maxCap);
  }, [overdueDays, librarySettings]);

  const damageFineAmount = useMemo(() => {
    if (damageLevel === 'minor') return 5;
    if (damageLevel === 'moderate') return 15;
    if (damageLevel === 'severe') return 50;
    return 0;
  }, [damageLevel]);

  const totalFineAmount = useMemo(() => {
    return overdueFineAmount + damageFineAmount;
  }, [overdueFineAmount, damageFineAmount]);

  const loanFound = useMemo(() => {
    return selectedLoan !== null;
  }, [selectedLoan]);

  const returnCompleted = useMemo(() => {
    return returnResult !== null;
  }, [returnResult]);

  const finesList = useMemo(() => {
    const fines: Array<{ reason: string; amount: number }> = [];
    if (overdueFineAmount > 0) {
      fines.push({ reason: `Overdue (${overdueDays} days)`, amount: overdueFineAmount });
    }
    if (damageFineAmount > 0) {
      fines.push({ reason: `Damage (${damageLevel})`, amount: damageFineAmount });
    }
    return fines;
  }, [overdueFineAmount, damageFineAmount, overdueDays, damageLevel]);

  const handleSearchLoan = async () => {
    if (!searchQuery || searchQuery.trim() === '') {
      messageApi.error('Please enter a Book ID or ISBN');
      return;
    }

    setLoading(true);
    try {
      const { data } = await request<LoanResponse[]>({
        method: 'GET',
        path: '/circulation/loans',
        query: {
          book_id: searchQuery,
          loan_status: 'ACTIVE',
          limit: 1
        }
      });

      if (data && data.length > 0) {
        const loan = data[0];
        setSelectedLoan(loan);
        messageApi.success('Loan record found');

        await Promise.all([
          fetchBookInfo(loan.book_id),
          fetchMemberInfo(loan.member_id),
          fetchPendingReservations(loan.book_id)
        ]);
      } else {
        messageApi.error('No active loan found for this book');
        setSelectedLoan(null);
        setBookInfo(null);
        setMemberInfo(null);
      }
    } catch (error) {
      messageApi.error('No active loan found for this book');
      setSelectedLoan(null);
      setBookInfo(null);
      setMemberInfo(null);
    } finally {
      setLoading(false);
    }
  };

  const fetchBookInfo = async (bookId: string) => {
    try {
      const { data } = await request<BookResponse>({
        method: 'GET',
        path: '/books/{book_id}',
        pathParams: { book_id: bookId }
      });
      setBookInfo(data);
    } catch (error) {
      messageApi.error('Failed to fetch book information');
    }
  };

  const fetchMemberInfo = async (memberId: string) => {
    try {
      const { data } = await request<MemberDetailResponse>({
        method: 'GET',
        path: '/users/members/{member_id}/details',
        pathParams: { member_id: memberId }
      });
      setMemberInfo(data);
    } catch (error) {
      messageApi.error('Failed to fetch member information');
    }
  };

  const fetchPendingReservations = async (bookId: string) => {
    try {
      const { data } = await request<ReservationResponse[]>({
        method: 'GET',
        path: '/circulation/reservations',
        query: {
          book_id: bookId,
          reservation_status: 'PENDING',
          limit: 5
        }
      });
      setPendingReservations(data || []);
    } catch (error) {
      setPendingReservations([]);
    }
  };

  const createOverdueFine = async () => {
    if (!selectedLoan || overdueFineAmount <= 0) return;

    try {
      const { data } = await request<FineResponse>({
        method: 'POST',
        path: '/fines/',
        body: {
          member_id: selectedLoan.member_id,
          loan_id: selectedLoan.id,
          amount: overdueFineAmount,
          amount_paid: 0,
          reason: 'OVERDUE',
          description: `Overdue fine for ${overdueDays} days`,
          status: 'UNPAID',
          assessed_date: new Date().toISOString(),
          due_date: null,
          waived_by: null,
          waived_date: null,
          waived_reason: null
        }
      });
      setOverdueFineCreated(data);
    } catch (error) {
      messageApi.error('Failed to create overdue fine');
    }
  };

  const createDamageFine = async () => {
    if (!selectedLoan || damageFineAmount <= 0) return;

    try {
      const { data } = await request<FineResponse>({
        method: 'POST',
        path: '/fines/',
        body: {
          member_id: selectedLoan.member_id,
          loan_id: selectedLoan.id,
          amount: damageFineAmount,
          amount_paid: 0,
          reason: 'DAMAGED',
          description: `Damage fine - ${damageLevel} damage`,
          status: 'UNPAID',
          assessed_date: new Date().toISOString(),
          due_date: null,
          waived_by: null,
          waived_date: null,
          waived_reason: null
        }
      });
      setDamageFineCreated(data);
    } catch (error) {
      messageApi.error('Failed to create damage fine');
    }
  };

  const handleProcessReturn = async () => {
    if (!selectedLoan) return;

    Modal.confirm({
      title: 'Confirm Return',
      content: 'Are you sure you want to process this book return?',
      onOk: async () => {
        setReturnProcessing(true);
        try {
          await Promise.all([
            createOverdueFine(),
            createDamageFine()
          ]);

          const { data } = await request<LoanResponse>({
            method: 'POST',
            path: '/circulation/loans/{loan_id}/return',
            pathParams: { loan_id: selectedLoan.id }
          });

          setReturnResult(data);
          messageApi.success('Book return processed successfully!');
        } catch (error) {
          messageApi.error('Failed to process return. Please try again.');
        } finally {
          setReturnProcessing(false);
        }
      }
    });
  };

  const handleProcessAnotherReturn = () => {
    setSearchQuery('');
    setSelectedLoan(null);
    setBookInfo(null);
    setMemberInfo(null);
    setDamageLevel('');
    setReturnResult(null);
    setPendingReservations([]);
    setReturnProcessing(false);
    setOverdueFineCreated(null);
    setDamageFineCreated(null);
  };

  const handleNavigateToDashboard = () => {
    navigate(ROUTES.LIBRARIAN_DASHBOARD || '/librarian/dashboard');
  };

  const handleNavigateToLoans = () => {
    navigate(ROUTES.CIRCULATION_LOANS || '/circulation/loans');
  };

  return (
    <div style={{ minHeight: '100vh', height: '100%', width: '100%', display: 'flex', flexDirection: 'column', background: '#f5f5f5', padding: '24px' }}>
      {contextHolder}
      
      <div style={{ marginBottom: '24px' }}>
        <Typography.Title level={2} style={{ marginBottom: '4px' }}>
          Book Return
        </Typography.Title>
        <Breadcrumb
          items={[
            { title: 'Circulation' },
            { title: 'Book Return' }
          ]}
        />
      </div>

      <Space size="middle" style={{ marginBottom: '16px' }}>
        <Button icon={<ArrowLeftOutlined />} onClick={handleNavigateToDashboard}>
          Back to Dashboard
        </Button>
        <Button onClick={handleNavigateToLoans}>
          View All Loans
        </Button>
      </Space>

      <Card title="Scan / Enter Book" style={{ marginBottom: '24px' }}>
        <Input.Search
          placeholder="Enter Book ID or ISBN and press Enter"
          enterButton="Search"
          size="large"
          loading={loading}
          allowClear
          value={searchQuery}
          onChange={(e) => setSearchQuery(e.target.value)}
          onSearch={handleSearchLoan}
          style={{ maxWidth: '600px' }}
        />
      </Card>

      {loanFound && !returnCompleted && (
        <div style={{ marginBottom: '24px' }}>
          <Row gutter={[16, 16]}>
            <Col xs={24} md={12}>
              <Card title="Book Information" size="small">
                {bookInfo && (
                  <Descriptions column={1} size="small">
                    <Descriptions.Item label="Title">{bookInfo.title}</Descriptions.Item>
                    <Descriptions.Item label="ISBN">{bookInfo.isbn || 'N/A'}</Descriptions.Item>
                    <Descriptions.Item label="Location">{bookInfo.location || 'N/A'}</Descriptions.Item>
                  </Descriptions>
                )}
              </Card>
            </Col>
            <Col xs={24} md={12}>
              <Card title="Loan Information" size="small">
                {selectedLoan && (
                  <Descriptions column={1} size="small">
                    <Descriptions.Item label="Member">{memberInfo?.membership_number || selectedLoan.member_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="Renewals">{selectedLoan.renewal_count}</Descriptions.Item>
                  </Descriptions>
                )}
              </Card>
            </Col>
          </Row>

          <Card title="Return Status" size="small" style={{ marginTop: '16px', marginBottom: '16px' }}>
            {!isOverdue && (
              <Alert
                type="success"
                message="On Time"
                description="This book is being returned on time. No overdue fine."
                showIcon
              />
            )}
            {isOverdue && (
              <Alert
                type="error"
                message="Overdue"
                description={`This book is overdue by ${overdueDays} day(s). Fine: $${overdueFineAmount.toFixed(2)}`}
                showIcon
              />
            )}
          </Card>

          <Card title="Damage Assessment (Optional)" size="small" style={{ marginBottom: '16px' }}>
            <Select
              placeholder="Select damage level if applicable"
              allowClear
              value={damageLevel || undefined}
              onChange={(value) => setDamageLevel(value || '')}
              style={{ width: '300px' }}
              options={[
                { value: 'minor', label: 'Minor ($5)' },
                { value: 'moderate', label: 'Moderate ($15)' },
                { value: 'severe', label: 'Severe ($50)' }
              ]}
            />
            {damageLevel && (
              <Typography.Text type="warning" style={{ marginTop: '8px', display: 'block' }}>
                Damage fine: ${damageFineAmount.toFixed(2)}
              </Typography.Text>
            )}
          </Card>

          {totalFineAmount > 0 && (
            <Card size="small" style={{ marginBottom: '16px', background: '#fff2e8', borderColor: '#ffbb96' }}>
              <Statistic
                title="Total Fine Amount"
                value={totalFineAmount}
                prefix="$"
                precision={2}
                valueStyle={{ color: '#cf1322' }}
              />
            </Card>
          )}

          <Button
            type="primary"
            size="large"
            icon={<CheckCircleOutlined />}
            loading={returnProcessing}
            onClick={handleProcessReturn}
            style={{ marginTop: '8px' }}
          >
            Process Return
          </Button>
        </div>
      )}

      {returnCompleted && (
        <div>
          <Result
            status="success"
            title="Book Return Processed Successfully"
            subTitle="The book has been returned and the loan record has been updated."
          />

          <Card title="Return Receipt" size="small" style={{ marginBottom: '16px' }}>
            {returnResult && (
              <Descriptions column={2} size="small">
                <Descriptions.Item label="Loan ID">{returnResult.id}</Descriptions.Item>
                <Descriptions.Item label="Book ID">{returnResult.book_id}</Descriptions.Item>
                <Descriptions.Item label="Return Date">
                  {returnResult.return_date ? new Date(returnResult.return_date).toLocaleString() : 'N/A'}
                </Descriptions.Item>
                <Descriptions.Item label="Status">{returnResult.status}</Descriptions.Item>
              </Descriptions>
            )}
          </Card>

          {totalFineAmount > 0 && (
            <Card title="Fines Generated" size="small" style={{ marginBottom: '16px' }}>
              <List
                size="small"
                dataSource={finesList}
                renderItem={(item) => (
                  <List.Item>
                    <List.Item.Meta
                      title={item.reason}
                      description={`Amount: $${item.amount.toFixed(2)}`}
                    />
                  </List.Item>
                )}
              />
            </Card>
          )}

          {pendingReservations.length > 0 && (
            <Alert
              type="info"
              message="Pending Reservations"
              description="This book has pending reservations. The next member in queue has been notified."
              showIcon
              style={{ marginBottom: '16px' }}
            />
          )}

          <Space size="middle" style={{ marginTop: '16px' }}>
            <Button
              type="primary"
              size="large"
              icon={<ReloadOutlined />}
              onClick={handleProcessAnotherReturn}
            >
              Process Another Return
            </Button>
            <Button size="large" onClick={handleNavigateToDashboard}>
              Back to Dashboard
            </Button>
          </Space>
        </div>
      )}
    </div>
  );
}