import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import { Card, Button, Typography, Descriptions, Tag, Statistic, Table, Image, Spin, Alert, Breadcrumb, Modal, message } from 'antd';
import { ArrowLeftOutlined, BookOutlined, ClockCircleOutlined } from '@ant-design/icons';
import { useNavigate, useParams } from 'react-router-dom';
import { request } from '../api/client';
import { useAppContext } from '../store/AppContext';

interface BookAuthorDetailResponse {
  author_id: string;
  author_order: number | null;
  author: {
    id: string;
    name: string;
  };
}

interface BookCategoryDetailResponse {
  category_id: string;
  category: {
    id: string;
    name: string;
    description: string | null;
  };
}

interface BookCopyDetailResponse {
  id: string;
  barcode: string;
  library_branch_id: string;
  condition_status: 'EXCELLENT' | 'GOOD' | 'FAIR' | 'POOR' | 'DAMAGED' | 'LOST';
  availability_status: 'AVAILABLE' | 'CHECKED_OUT' | 'RESERVED' | 'IN_TRANSIT' | 'MAINTENANCE' | 'LOST';
  acquisition_date: string | null;
  physical_location: string | null;
}

interface BookDetailsResponse {
  id: string;
  isbn: string | null;
  title: string;
  publisher: string | null;
  publication_date: string | null;
  edition: string | null;
  number_of_pages: number | null;
  language: string | null;
  description: string | null;
  cover_image_url: string | null;
  created_at: string;
  updated_at: string;
  book_authors: BookAuthorDetailResponse[];
  book_categories: BookCategoryDetailResponse[];
  book_copies: BookCopyDetailResponse[];
}

interface BookAvailabilityResponse {
  book_id: string;
  title: string;
  total_copies: number;
  available_copies: number;
  checked_out_copies: number;
  reserved_copies: number;
  copies_by_branch: Array<{
    branch_id: string;
    branch_name: string;
    available: number;
    total: number;
  }>;
}

interface ReservationResponse {
  id: string;
  member_id: string;
  book_id: string;
  reservation_date: string;
  expiration_date: string;
  status: 'PENDING' | 'READY' | 'FULFILLED' | 'CANCELLED' | 'EXPIRED';
  priority_order: number | null;
  notified_date: string | null;
  created_at: string;
  updated_at: string;
}

interface BookResponse {
  id: string;
  title: string;
  book_authors: Array<{
    author_id: string;
    author: {
      id: string;
      name: string;
    };
  }>;
}

export default function BookDetailPage() {
  const { bookId } = useParams<{ bookId: string }>();
  const navigate = useNavigate();
  const { currentUser } = useAppContext();
  const [messageApi, contextHolder] = message.useMessage();

  const [bookDetails, setBookDetails] = useState<BookDetailsResponse | null>(null);
  const [bookAvailability, setBookAvailability] = useState<BookAvailabilityResponse | null>(null);
  const [activeReservations, setActiveReservations] = useState<ReservationResponse[]>([]);
  const [recommendedBooks, setRecommendedBooks] = useState<BookResponse[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [reserving, setReserving] = useState<boolean>(false);
  const [reservationQueuePosition, setReservationQueuePosition] = useState<number | null>(null);

  const totalCopies = useMemo(() => bookAvailability?.total_copies || 0, [bookAvailability]);
  const availableCopies = useMemo(() => bookAvailability?.available_copies || 0, [bookAvailability]);
  const checkedOutCopies = useMemo(() => bookAvailability?.checked_out_copies || 0, [bookAvailability]);
  const reservedCopies = useMemo(() => bookAvailability?.reserved_copies || 0, [bookAvailability]);
  const activeReservationCount = useMemo(() => activeReservations.length, [activeReservations]);
  const canBorrow = useMemo(() => currentUser?.role === 'MEMBER' && (bookAvailability?.available_copies || 0) > 0, [currentUser, bookAvailability]);
  const canReserve = useMemo(() => currentUser?.role === 'MEMBER' && (bookAvailability?.available_copies || 0) === 0, [currentUser, bookAvailability]);
  const bookAuthors = useMemo(() => bookDetails?.book_authors || [], [bookDetails]);
  const bookCategories = useMemo(() => bookDetails?.book_categories || [], [bookDetails]);
  const bookCopies = useMemo(() => bookDetails?.book_copies || [], [bookDetails]);

  const copiesTableColumns = useMemo(() => [
    {
      title: 'Barcode',
      dataIndex: 'barcode',
      key: 'barcode',
    },
    {
      title: 'Branch',
      dataIndex: 'library_branch_id',
      key: 'branch',
    },
    {
      title: 'Condition',
      dataIndex: 'condition_status',
      key: 'condition',
      render: (status: string) => {
        const colorMap: Record<string, string> = {
          EXCELLENT: 'green',
          GOOD: 'blue',
          FAIR: 'orange',
          POOR: 'red',
          DAMAGED: 'red',
          LOST: 'red',
        };
        return <Tag color={colorMap[status] || 'default'}>{status}</Tag>;
      },
    },
    {
      title: 'Status',
      dataIndex: 'availability_status',
      key: 'status',
      render: (status: string) => {
        const colorMap: Record<string, string> = {
          AVAILABLE: 'green',
          CHECKED_OUT: 'orange',
          RESERVED: 'blue',
          IN_TRANSIT: 'purple',
          MAINTENANCE: 'gold',
          LOST: 'red',
        };
        return <Tag color={colorMap[status] || 'default'}>{status}</Tag>;
      },
    },
    {
      title: 'Location',
      dataIndex: 'physical_location',
      key: 'location',
      render: (location: string | null) => location || '-',
    },
  ], []);

  useEffect(() => {
    const fetchData = async () => {
      if (!bookId) return;

      setLoading(true);
      try {
        const [detailsRes, availabilityRes, reservationsRes, recommendedRes] = await Promise.all([
          request<BookDetailsResponse>({
            method: 'GET',
            path: '/catalog/books/{book_id}/details',
            pathParams: { book_id: bookId },
          }),
          request<BookAvailabilityResponse>({
            method: 'GET',
            path: '/catalog/books/{book_id}/availability',
            pathParams: { book_id: bookId },
          }),
          request<ReservationResponse[]>({
            method: 'GET',
            path: '/reservations/',
            query: { book_id: bookId, status: 'PENDING', limit: 50 },
          }),
          request<BookResponse[]>({
            method: 'GET',
            path: '/catalog/books',
            query: { limit: 6 },
          }),
        ]);

        setBookDetails(detailsRes.data);
        setBookAvailability(availabilityRes.data);
        setActiveReservations(reservationsRes.data);
        setRecommendedBooks(recommendedRes.data);
      } catch (error) {
        messageApi.error('Failed to load book details');
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [bookId, messageApi]);

  const navigateToCatalog = useCallback(() => {
    navigate('/');
  }, [navigate]);

  const navigateToAuthor = useCallback((authorId: string) => {
    navigate(`/authors/${authorId}`);
  }, [navigate]);

  const borrowBook = useCallback(() => {
    Modal.confirm({
      title: 'Borrow Book',
      content: 'Please visit the library to complete checkout or contact a librarian.',
      onOk: () => {
        messageApi.info('Please visit the library to complete checkout or contact a librarian.');
      },
    });
  }, [messageApi]);

  const reserveBook = useCallback(async () => {
    if (!bookId || !currentUser) return;

    Modal.confirm({
      title: 'Reserve Book',
      content: 'Are you sure you want to reserve this book?',
      onOk: async () => {
        setReserving(true);
        try {
          const memberId = (currentUser as { memberId?: string }).memberId;
          if (!memberId) {
            messageApi.error('Member ID not found');
            setReserving(false);
            return;
          }

          const reservationDate = new Date().toISOString();
          const expirationDate = new Date(Date.now() + 90 * 24 * 60 * 60 * 1000).toISOString();

          const response = await request<ReservationResponse>({
            method: 'POST',
            path: '/reservations/',
            body: {
              member_id: memberId,
              book_id: bookId,
              reservation_date: reservationDate,
              expiration_date: expirationDate,
              status: 'PENDING',
            },
          });

          setReservationQueuePosition(response.data.priority_order || activeReservations.length + 1);
          messageApi.success('Book reserved successfully!');

          const updatedReservations = await request<ReservationResponse[]>({
            method: 'GET',
            path: '/reservations/',
            query: { book_id: bookId, status: 'PENDING', limit: 50 },
          });
          setActiveReservations(updatedReservations.data);

          const updatedAvailability = await request<BookAvailabilityResponse>({
            method: 'GET',
            path: '/catalog/books/{book_id}/availability',
            pathParams: { book_id: bookId },
          });
          setBookAvailability(updatedAvailability.data);
        } catch (error) {
          messageApi.error('Unable to reserve book. Please try again.');
        } finally {
          setReserving(false);
        }
      },
    });
  }, [bookId, currentUser, activeReservations.length, messageApi]);

  const navigateToBookDetail = useCallback((selectedBookId: string) => {
    navigate(`/books/${selectedBookId}`);
  }, [navigate]);

  const mainContainerStyle: CSSProperties = {
    minHeight: '100vh',
    width: '100%',
    padding: '24px',
    maxWidth: '1200px',
    margin: '0 auto',
    display: 'flex',
    flexDirection: 'column',
  };

  const bookInfoSectionStyle: CSSProperties = {
    marginBottom: '32px',
    display: 'flex',
    flexDirection: 'row',
    gap: '32px',
  };

  const coverImageColStyle: CSSProperties = {
    flex: '0 0 300px',
    marginRight: '32px',
  };

  const bookDetailsColStyle: CSSProperties = {
    flex: '1',
    display: 'flex',
    flexDirection: 'column',
    gap: '12px',
  };

  const categoriesSectionStyle: CSSProperties = {
    marginBottom: '16px',
    display: 'flex',
    flexDirection: 'row',
    gap: '8px',
    flexWrap: 'wrap',
  };

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

  const availabilityStatsStyle: CSSProperties = {
    marginBottom: '16px',
    display: 'flex',
    flexDirection: 'row',
    gap: '32px',
    flexWrap: 'wrap',
  };

  const actionButtonsSectionStyle: CSSProperties = {
    marginBottom: '16px',
    display: 'flex',
    flexDirection: 'row',
    gap: '12px',
  };

  const recommendedBooksGridStyle: CSSProperties = {
    display: 'grid',
    gridTemplateColumns: 'repeat(3, 1fr)',
    gap: '16px',
  };

  if (loading) {
    return (
      <div style={mainContainerStyle}>
        {contextHolder}
        <div style={{ display: 'flex', justifyContent: 'center', padding: '100px 0' }}>
          <Spin size="large" tip="Loading book details..." />
        </div>
      </div>
    );
  }

  if (!bookDetails) {
    return (
      <div style={mainContainerStyle}>
        {contextHolder}
        <Alert type="error" message="Book not found" showIcon />
      </div>
    );
  }

  return (
    <div style={mainContainerStyle}>
      {contextHolder}
      
      <Breadcrumb
        style={{ marginBottom: '24px' }}
        items={[
          { title: 'Catalog', href: '/' },
          { title: 'Book Details' },
        ]}
      />

      <Button
        type="link"
        icon={<ArrowLeftOutlined />}
        onClick={navigateToCatalog}
        style={{ marginBottom: '16px', paddingLeft: '0' }}
      >
        Back to Catalog
      </Button>

      <div style={bookInfoSectionStyle}>
        <div style={coverImageColStyle}>
          <Image
            width={280}
            src={bookDetails.cover_image_url || undefined}
            fallback="https://via.placeholder.com/280x400?text=No+Cover"
            alt="Book cover"
            style={{ borderRadius: '8px', boxShadow: '0 4px 12px rgba(0,0,0,0.1)' }}
          />
        </div>

        <div style={bookDetailsColStyle}>
          <Typography.Title level={2} style={{ marginBottom: '8px' }}>
            {bookDetails.title}
          </Typography.Title>

          <div style={{ fontSize: '16px', marginBottom: '16px' }}>
            {bookAuthors.map((ba, idx) => (
              <span key={ba.author_id}>
                <Typography.Link onClick={() => navigateToAuthor(ba.author_id)}>
                  {ba.author.name}
                </Typography.Link>
                {idx < bookAuthors.length - 1 && ', '}
              </span>
            ))}
          </div>

          <Descriptions
            column={2}
            bordered
            size="middle"
            style={{ marginBottom: '16px' }}
            items={[
              { label: 'ISBN', children: bookDetails.isbn || '-' },
              { label: 'Publisher', children: bookDetails.publisher || '-' },
              { label: 'Publication Date', children: bookDetails.publication_date || '-' },
              { label: 'Edition', children: bookDetails.edition || '-' },
              { label: 'Pages', children: bookDetails.number_of_pages || '-' },
              { label: 'Language', children: bookDetails.language || '-' },
            ]}
          />

          <div style={categoriesSectionStyle}>
            <Typography.Text strong style={{ marginRight: '8px' }}>
              Categories:
            </Typography.Text>
            {bookCategories.map((bc) => (
              <Tag key={bc.category_id} color="blue">
                {bc.category.name}
              </Tag>
            ))}
          </div>
        </div>
      </div>

      <div style={descriptionSectionStyle}>
        <Typography.Title level={4} style={{ marginBottom: '8px' }}>
          Description
        </Typography.Title>
        <Typography.Paragraph ellipsis={{ rows: 5, expandable: true }}>
          {bookDetails.description || 'No description available.'}
        </Typography.Paragraph>
      </div>

      <Card title="Availability" bordered style={{ marginBottom: '24px' }}>
        <div style={availabilityStatsStyle}>
          <Statistic title="Total Copies" value={totalCopies} />
          <Statistic
            title="Available"
            value={availableCopies}
            valueStyle={{ color: '#52c41a' }}
          />
          <Statistic
            title="Checked Out"
            value={checkedOutCopies}
            valueStyle={{ color: '#faad14' }}
          />
          <Statistic
            title="Reserved"
            value={reservedCopies}
            valueStyle={{ color: '#1677ff' }}
          />
          <Statistic
            title="Active Reservations in Queue"
            value={activeReservationCount}
            valueStyle={{ color: '#722ed1' }}
          />
        </div>

        <div style={actionButtonsSectionStyle}>
          {canBorrow && (
            <Button
              type="primary"
              size="large"
              icon={<BookOutlined />}
              onClick={borrowBook}
              style={{ marginRight: '12px' }}
            >
              Borrow
            </Button>
          )}
          {canReserve && (
            <Button
              type="default"
              size="large"
              icon={<ClockCircleOutlined />}
              onClick={reserveBook}
              loading={reserving}
            >
              Reserve
            </Button>
          )}
        </div>

        {reservationQueuePosition !== null && (
          <Alert
            type="success"
            showIcon
            message={`Reservation confirmed! Your queue position: ${reservationQueuePosition}`}
            style={{ marginTop: '12px' }}
          />
        )}
      </Card>

      <Card title="Book Copies" bordered style={{ marginBottom: '24px' }}>
        <Table
          dataSource={bookCopies}
          columns={copiesTableColumns}
          pagination={false}
          size="middle"
          rowKey="id"
        />
      </Card>

      {recommendedBooks.length > 0 && (
        <Card title="Recommended for You" bordered style={{ marginBottom: '24px' }}>
          <div style={recommendedBooksGridStyle}>
            {recommendedBooks.map((book) => (
              <Card
                key={book.id}
                hoverable
                size="small"
                onClick={() => navigateToBookDetail(book.id)}
                style={{ cursor: 'pointer' }}
              >
                <Typography.Title level={5}>{book.title}</Typography.Title>
                <Typography.Text type="secondary">
                  {book.book_authors.map((ba) => ba.author.name).join(', ')}
                </Typography.Text>
              </Card>
            ))}
          </div>
        </Card>
      )}
    </div>
  );
}