import { useState, useMemo, useEffect, useCallback } from 'react';
import { Layout, Input, Card, Select, TreeSelect, Button, Space, Typography, Radio, Pagination, List, Tag, Rate, Empty, Drawer, message } from 'antd';
import { FilterOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { request } from '../api/client';
import { ROUTES } from '../router/routes.constant';

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: 'PHYSICAL' | 'DIGITAL';
  total_copies: number;
  available_copies: number;
  location: string | null;
  status: 'AVAILABLE' | 'CHECKED_OUT' | 'RESERVED' | 'MAINTENANCE' | 'LOST' | 'DAMAGED';
  created_at: string;
  updated_at: string;
}

interface CategoryResponse {
  id: string;
  name: string;
  description: string | null;
  parent_category_id: string | null;
  created_at: string;
  updated_at: string;
}

interface AuthorResponse {
  id: string;
  first_name: string;
  last_name: string;
  biography: string | null;
  birth_date: string | null;
  nationality: string | null;
  created_at: string;
  updated_at: string;
}

interface PublisherResponse {
  id: string;
  name: string;
  address: string | null;
  phone: string | null;
  email: string | null;
  website: string | null;
  created_at: string;
  updated_at: string;
}

type BookStatus = 'AVAILABLE' | 'CHECKED_OUT' | 'RESERVED' | 'MAINTENANCE' | 'LOST' | 'DAMAGED' | '';
type BookFormat = 'PHYSICAL' | 'DIGITAL' | '';

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

  const [books, setBooks] = useState<BookResponse[]>([]);
  const [categories, setCategories] = useState<CategoryResponse[]>([]);
  const [authors, setAuthors] = useState<AuthorResponse[]>([]);
  const [publishers, setPublishers] = useState<PublisherResponse[]>([]);
  const [searchQuery, setSearchQuery] = useState<string>('');
  const [selectedCategory, setSelectedCategory] = useState<string>('');
  const [selectedAuthor, setSelectedAuthor] = useState<string>('');
  const [selectedPublisher, setSelectedPublisher] = useState<string>('');
  const [statusFilter, setStatusFilter] = useState<BookStatus>('');
  const [formatFilter, setFormatFilter] = useState<BookFormat>('');
  const [sortBy, setSortBy] = useState<string>('relevance');
  const [viewMode, setViewMode] = useState<string>('card');
  const [currentPage, setCurrentPage] = useState<number>(1);
  const [pageSize, setPageSize] = useState<number>(20);
  const [loading, setLoading] = useState<boolean>(false);
  const [totalBooks, setTotalBooks] = useState<number>(0);
  const [filterDrawerVisible, setFilterDrawerVisible] = useState<boolean>(false);

  const offset = useMemo(() => (currentPage - 1) * pageSize, [currentPage, pageSize]);
  const hasResults = useMemo(() => books.length > 0, [books]);

  const fetchBooks = useCallback(async () => {
    setLoading(true);
    try {
      const queryParams: Record<string, string | number> = {
        limit: pageSize,
        offset: offset,
      };
      if (searchQuery) queryParams.search = searchQuery;
      if (statusFilter) queryParams.status_filter = statusFilter;
      if (formatFilter) queryParams.book_format = formatFilter;

      const result = await request<BookResponse[]>({
        method: 'GET',
        path: '/books',
        query: queryParams,
      });
      setBooks(result.data);
      setTotalBooks(result.data.length);
    } catch (error) {
      messageApi.error('Failed to load books. Please try again.');
    } finally {
      setLoading(false);
    }
  }, [pageSize, offset, searchQuery, statusFilter, formatFilter, messageApi]);

  const fetchCategories = useCallback(async () => {
    try {
      const result = await request<CategoryResponse[]>({
        method: 'GET',
        path: '/categories',
        query: { limit: 100, offset: 0 },
      });
      setCategories(result.data);
    } catch (error) {
      messageApi.error('Failed to load categories.');
    }
  }, [messageApi]);

  const fetchAuthors = useCallback(async () => {
    try {
      const result = await request<AuthorResponse[]>({
        method: 'GET',
        path: '/authors',
        query: { limit: 100, offset: 0 },
      });
      setAuthors(result.data);
    } catch (error) {
      messageApi.error('Failed to load authors.');
    }
  }, [messageApi]);

  const fetchPublishers = useCallback(async () => {
    try {
      const result = await request<PublisherResponse[]>({
        method: 'GET',
        path: '/publishers',
        query: { limit: 100, offset: 0 },
      });
      setPublishers(result.data);
    } catch (error) {
      messageApi.error('Failed to load publishers.');
    }
  }, [messageApi]);

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

  useEffect(() => {
    fetchCategories();
    fetchAuthors();
    fetchPublishers();
  }, [fetchCategories, fetchAuthors, fetchPublishers]);

  const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchQuery(e.target.value);
    setCurrentPage(1);
  };

  const handleCategoryChange = (value: string) => {
    setSelectedCategory(value);
    setCurrentPage(1);
  };

  const handleAuthorChange = (value: string) => {
    setSelectedAuthor(value);
    setCurrentPage(1);
  };

  const handlePublisherChange = (value: string) => {
    setSelectedPublisher(value);
    setCurrentPage(1);
  };

  const handleStatusFilterChange = (value: BookStatus) => {
    setStatusFilter(value);
    setCurrentPage(1);
  };

  const handleFormatFilterChange = (value: BookFormat) => {
    setFormatFilter(value);
    setCurrentPage(1);
  };

  const handleSortChange = (value: string) => {
    setSortBy(value);
    setCurrentPage(1);
  };

  const handleViewModeChange = (e: { target: { value: string } }) => {
    setViewMode(e.target.value);
  };

  const handlePageChange = (page: number, newPageSize?: number) => {
    setCurrentPage(page);
    if (newPageSize && newPageSize !== pageSize) {
      setPageSize(newPageSize);
      setCurrentPage(1);
    }
  };

  const handleFilterDrawerOpen = () => {
    setFilterDrawerVisible(true);
  };

  const handleFilterDrawerClose = () => {
    setFilterDrawerVisible(false);
  };

  const navigateToBookDetail = (bookId: string) => {
    navigate(`/catalog/${bookId}`);
  };

  const navigateToLogin = () => {
    navigate(ROUTES.LOGIN);
  };

  const navigateToRegister = () => {
    navigate(ROUTES.REGISTER);
  };

  const clearFilters = () => {
    setSelectedCategory('');
    setSelectedAuthor('');
    setSelectedPublisher('');
    setStatusFilter('');
    setFormatFilter('');
    setSearchQuery('');
    setCurrentPage(1);
    messageApi.success('Filters cleared');
  };

  const categoryTreeData = useMemo(() => {
    return categories.map(cat => ({
      title: cat.name,
      value: cat.id,
      key: cat.id,
    }));
  }, [categories]);

  const authorOptions = useMemo(() => {
    return authors.map(author => ({
      label: `${author.first_name} ${author.last_name}`,
      value: author.id,
    }));
  }, [authors]);

  const publisherOptions = useMemo(() => {
    return publishers.map(pub => ({
      label: pub.name,
      value: pub.id,
    }));
  }, [publishers]);

  const getStatusColor = (status: string): string => {
    const colorMap: Record<string, string> = {
      AVAILABLE: 'green',
      CHECKED_OUT: 'red',
      RESERVED: 'gold',
      MAINTENANCE: 'blue',
      LOST: 'volcano',
      DAMAGED: 'orange',
    };
    return colorMap[status] || 'default';
  };

  const getStatusLabel = (status: string): string => {
    const labelMap: Record<string, string> = {
      AVAILABLE: 'Available',
      CHECKED_OUT: 'Checked Out',
      RESERVED: 'Reserved',
      MAINTENANCE: 'Maintenance',
      LOST: 'Lost',
      DAMAGED: 'Damaged',
    };
    return labelMap[status] || status;
  };

  const filterPanel = (
    <>
      <div style={{ marginBottom: '16px' }}>
        <Typography.Text strong>Category</Typography.Text>
        <TreeSelect
          value={selectedCategory}
          onChange={handleCategoryChange}
          treeData={categoryTreeData}
          placeholder="Select category"
          allowClear
          treeDefaultExpandAll={false}
          style={{ width: '100%', marginTop: '8px' }}
        />
      </div>
      <div style={{ marginBottom: '16px' }}>
        <Typography.Text strong>Author</Typography.Text>
        <Select
          value={selectedAuthor}
          onChange={handleAuthorChange}
          options={authorOptions}
          placeholder="Select author"
          allowClear
          showSearch
          style={{ width: '100%', marginTop: '8px' }}
        />
      </div>
      <div style={{ marginBottom: '16px' }}>
        <Typography.Text strong>Publisher</Typography.Text>
        <Select
          value={selectedPublisher}
          onChange={handlePublisherChange}
          options={publisherOptions}
          placeholder="Select publisher"
          allowClear
          showSearch
          style={{ width: '100%', marginTop: '8px' }}
        />
      </div>
      <div style={{ marginBottom: '16px' }}>
        <Typography.Text strong>Availability</Typography.Text>
        <Select
          value={statusFilter}
          onChange={handleStatusFilterChange}
          placeholder="All statuses"
          allowClear
          style={{ width: '100%', marginTop: '8px' }}
          options={[
            { label: 'Available', value: 'AVAILABLE' },
            { label: 'Checked Out', value: 'CHECKED_OUT' },
            { label: 'Reserved', value: 'RESERVED' },
          ]}
        />
      </div>
      <div style={{ marginBottom: '16px' }}>
        <Typography.Text strong>Format</Typography.Text>
        <Select
          value={formatFilter}
          onChange={handleFormatFilterChange}
          placeholder="All formats"
          allowClear
          style={{ width: '100%', marginTop: '8px' }}
          options={[
            { label: 'Physical', value: 'PHYSICAL' },
            { label: 'Digital', value: 'DIGITAL' },
          ]}
        />
      </div>
      <Button type="link" block onClick={clearFilters} style={{ marginTop: '8px' }}>
        Clear All Filters
      </Button>
    </>
  );

  return (
    <div style={{ minHeight: '100vh', height: '100%', width: '100%', display: 'flex', flexDirection: 'column' }}>
      {contextHolder}
      <Layout style={{ minHeight: '100vh', width: '100%', background: '#f5f5f5' }}>
        <Layout.Header
          style={{
            background: '#fff',
            padding: '0 24px',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'space-between',
            boxShadow: '0 2px 8px rgba(0,0,0,0.06)',
          }}
        >
          <Typography.Title level={3} style={{ margin: 0 }}>
            Book Catalog
          </Typography.Title>
          <Space size="middle">
            <Button type="default" onClick={navigateToLogin}>
              Login
            </Button>
            <Button type="primary" onClick={navigateToRegister}>
              Register
            </Button>
          </Space>
        </Layout.Header>

        <Layout.Content style={{ padding: '24px' }}>
          <div style={{ textAlign: 'center', marginBottom: '24px', padding: '32px 0' }}>
            <Typography.Title level={2} style={{ marginBottom: '16px' }}>
              Discover Your Next Read
            </Typography.Title>
            <Input.Search
              value={searchQuery}
              onChange={handleSearchChange}
              placeholder="Search by title, author, or ISBN..."
              size="large"
              allowClear
              enterButton
              style={{ maxWidth: '600px', width: '100%' }}
            />
          </div>

          <div style={{ display: 'flex', gap: '24px' }}>
            <Card
              title="Filters"
              style={{ width: '280px', flexShrink: 0 }}
              className="filter-panel-desktop"
            >
              {filterPanel}
            </Card>

            <div style={{ flex: 1, minWidth: 0 }}>
              <div
                style={{
                  display: 'flex',
                  justifyContent: 'space-between',
                  alignItems: 'center',
                  marginBottom: '16px',
                }}
              >
                <Typography.Text type="secondary">
                  {totalBooks} {totalBooks === 1 ? 'book' : 'books'} found
                </Typography.Text>
                <Space size="middle">
                  <Button
                    icon={<FilterOutlined />}
                    type="default"
                    onClick={handleFilterDrawerOpen}
                    className="mobile-filter-button"
                  >
                    Filters
                  </Button>
                  <Select
                    value={sortBy}
                    onChange={handleSortChange}
                    style={{ width: '180px' }}
                    options={[
                      { label: 'Relevance', value: 'relevance' },
                      { label: 'Title A-Z', value: 'title_asc' },
                      { label: 'Author', value: 'author' },
                      { label: 'Publication Date', value: 'publication_date' },
                      { label: 'Popularity', value: 'popularity' },
                    ]}
                  />
                  <Radio.Group
                    value={viewMode}
                    onChange={handleViewModeChange}
                    optionType="button"
                    buttonStyle="solid"
                    options={[
                      { label: 'Cards', value: 'card' },
                      { label: 'List', value: 'list' },
                    ]}
                  />
                </Space>
              </div>

              {hasResults ? (
                <List
                  grid={{
                    gutter: 16,
                    xs: 1,
                    sm: 2,
                    md: 2,
                    lg: 3,
                    xl: 4,
                  }}
                  loading={loading}
                  dataSource={books}
                  renderItem={(book) => (
                    <List.Item>
                      <Card
                        hoverable
                        style={{ cursor: 'pointer' }}
                        onClick={() => navigateToBookDetail(book.id)}
                      >
                        <Typography.Title
                          level={5}
                          ellipsis={{ rows: 2 }}
                          style={{ marginBottom: '4px' }}
                        >
                          {book.title}
                        </Typography.Title>
                        <Typography.Text
                          type="secondary"
                          style={{ display: 'block', marginBottom: '8px' }}
                        >
                          {book.subtitle || ''}
                        </Typography.Text>
                        <Typography.Text
                          type="secondary"
                          style={{ fontSize: '12px', display: 'block', marginBottom: '8px' }}
                        >
                          {book.publication_date ? new Date(book.publication_date).getFullYear() : ''}
                        </Typography.Text>
                        <div style={{ marginBottom: '8px' }}>
                          <Tag color={getStatusColor(book.status)}>
                            {getStatusLabel(book.status)}
                          </Tag>
                        </div>
                        <Typography.Text type="secondary" style={{ fontSize: '12px' }}>
                          {book.available_copies} / {book.total_copies} available
                        </Typography.Text>
                      </Card>
                    </List.Item>
                  )}
                />
              ) : (
                !loading && (
                  <Empty
                    description="No books found matching your criteria"
                    style={{ padding: '48px 0' }}
                  />
                )
              )}

              <div style={{ textAlign: 'center', marginTop: '24px', paddingBottom: '24px' }}>
                <Pagination
                  current={currentPage}
                  pageSize={pageSize}
                  total={totalBooks}
                  onChange={handlePageChange}
                  showSizeChanger
                  showQuickJumper
                  pageSizeOptions={['10', '20', '40', '60']}
                />
              </div>
            </div>
          </div>
        </Layout.Content>
      </Layout>

      <Drawer
        title="Filters"
        placement="left"
        width={300}
        open={filterDrawerVisible}
        onClose={handleFilterDrawerClose}
      >
        {filterPanel}
      </Drawer>
    </div>
  );
}