import { useState, useMemo, useEffect, useCallback } from 'react';
import { Card, Table, Button, Input, Select, Space, Modal, Form, InputNumber, DatePicker, Typography, message, Tag, Upload } from 'antd';
import { PlusOutlined, EditOutlined, DeleteOutlined, UploadOutlined, InboxOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { request } from '../api/client';
import { ROUTES } from '../router/routes.constant';

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

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: BookFormat;
  total_copies: number;
  available_copies: number;
  location: string | null;
  status: BookStatus;
  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;
}

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

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

export default function BookCatalogPage() {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();
  const [addBookForm] = Form.useForm();
  const [editBookForm] = Form.useForm();

  const [books, setBooks] = useState<BookResponse[]>([]);
  const [authors, setAuthors] = useState<AuthorResponse[]>([]);
  const [publishers, setPublishers] = useState<PublisherResponse[]>([]);
  const [categories, setCategories] = useState<CategoryResponse[]>([]);
  const [loading, setLoading] = useState<boolean>(false);
  const [searchText, setSearchText] = useState<string>('');
  const [statusFilter, setStatusFilter] = useState<string>('');
  const [formatFilter, setFormatFilter] = useState<string>('');
  const [pagination, setPagination] = useState<PaginationState>({
    current: 1,
    pageSize: 20,
    total: 0,
  });
  const [addBookModalVisible, setAddBookModalVisible] = useState<boolean>(false);
  const [editBookModalVisible, setEditBookModalVisible] = useState<boolean>(false);
  const [deleteConfirmVisible, setDeleteConfirmVisible] = useState<boolean>(false);
  const [bulkImportModalVisible, setBulkImportModalVisible] = useState<boolean>(false);
  const [selectedBookId, setSelectedBookId] = useState<string | null>(null);
  const [selectedBook, setSelectedBook] = useState<BookResponse | null>(null);

  const totalBooks = useMemo(() => pagination.total, [pagination.total]);

  const fetchBooks = useCallback(async () => {
    setLoading(true);
    try {
      const result = await request<BookResponse[]>({
        method: 'GET',
        path: '/books',
        query: {
          limit: pagination.pageSize,
          offset: (pagination.current - 1) * pagination.pageSize,
          ...(searchText && { search: searchText }),
          ...(statusFilter && { status_filter: statusFilter }),
          ...(formatFilter && { book_format: formatFilter }),
        },
      });
      setBooks(result.data);
      setPagination((prev) => ({ ...prev, total: result.data.length }));
    } catch (error) {
      messageApi.error('Failed to load books');
    } finally {
      setLoading(false);
    }
  }, [pagination.current, pagination.pageSize, searchText, statusFilter, formatFilter, messageApi]);

  const fetchAuthors = useCallback(async () => {
    try {
      const result = await request<AuthorResponse[]>({
        method: 'GET',
        path: '/authors',
        query: {
          limit: 200,
          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: 200,
          offset: 0,
        },
      });
      setPublishers(result.data);
    } catch (error) {
      messageApi.error('Failed to load publishers');
    }
  }, [messageApi]);

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

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

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

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

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

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

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

  const openAddBookModal = () => {
    setAddBookModalVisible(true);
  };

  const closeAddBookModal = () => {
    setAddBookModalVisible(false);
    addBookForm.resetFields();
  };

  const openEditBookModal = (record: BookResponse) => {
    setEditBookModalVisible(true);
    setSelectedBookId(record.id);
    setSelectedBook(record);
    editBookForm.setFieldsValue(record);
  };

  const closeEditBookModal = () => {
    setEditBookModalVisible(false);
    setSelectedBookId(null);
    setSelectedBook(null);
    editBookForm.resetFields();
  };

  const openDeleteConfirm = (record: BookResponse) => {
    setDeleteConfirmVisible(true);
    setSelectedBookId(record.id);
  };

  const closeDeleteConfirm = () => {
    setDeleteConfirmVisible(false);
    setSelectedBookId(null);
  };

  const openBulkImportModal = () => {
    setBulkImportModalVisible(true);
  };

  const closeBulkImportModal = () => {
    setBulkImportModalVisible(false);
  };

  const handleAddBook = async () => {
    try {
      const values = await addBookForm.validateFields();
      await request<BookResponse>({
        method: 'POST',
        path: '/books',
        body: {
          isbn: values.isbn,
          title: values.title,
          subtitle: values.subtitle,
          publisher_id: values.publisher_id,
          publication_date: values.publication_date,
          edition: values.edition,
          language: values.language,
          pages: values.pages,
          description: values.description,
          book_format: values.book_format,
          total_copies: values.total_copies,
          available_copies: values.available_copies,
          location: values.location,
          status: values.status,
        },
      });
      messageApi.success('Book added successfully!');
      closeAddBookModal();
      fetchBooks();
    } catch (error) {
      messageApi.error('Failed to add book. Please try again.');
    }
  };

  const handleEditBook = async () => {
    try {
      const values = await editBookForm.validateFields();
      if (!selectedBookId) return;
      await request<BookResponse>({
        method: 'PUT',
        path: '/books/{book_id}',
        pathParams: { book_id: selectedBookId },
        body: {
          isbn: values.isbn,
          title: values.title,
          subtitle: values.subtitle,
          publisher_id: values.publisher_id,
          publication_date: values.publication_date,
          edition: values.edition,
          language: values.language,
          pages: values.pages,
          description: values.description,
          book_format: values.book_format,
          total_copies: values.total_copies,
          available_copies: values.available_copies,
          location: values.location,
          status: values.status,
        },
      });
      messageApi.success('Book updated successfully!');
      closeEditBookModal();
      fetchBooks();
    } catch (error) {
      messageApi.error('Failed to update book. Please try again.');
    }
  };

  const handleDeleteBook = async () => {
    try {
      if (!selectedBookId) return;
      await request({
        method: 'DELETE',
        path: '/books/{book_id}',
        pathParams: { book_id: selectedBookId },
      });
      messageApi.success('Book deleted successfully!');
      closeDeleteConfirm();
      fetchBooks();
    } catch (error) {
      messageApi.error('Failed to delete book. It may have active loans or reservations.');
    }
  };

  const navigateToAuthors = () => {
    navigate(ROUTES.AUTHORS);
  };

  const navigateToCategories = () => {
    navigate(ROUTES.CATEGORIES);
  };

  const navigateToPublishers = () => {
    navigate(ROUTES.PUBLISHERS);
  };

  const columns = useMemo(
    () => [
      {
        title: 'ID',
        dataIndex: 'id',
        key: 'id',
        width: 80,
        ellipsis: true,
      },
      {
        title: 'Title',
        dataIndex: 'title',
        key: 'title',
        width: 200,
        ellipsis: true,
      },
      {
        title: 'ISBN',
        dataIndex: 'isbn',
        key: 'isbn',
        width: 140,
      },
      {
        title: 'Format',
        dataIndex: 'book_format',
        key: 'book_format',
        width: 100,
      },
      {
        title: 'Status',
        dataIndex: 'status',
        key: 'status',
        width: 130,
        render: (status: BookStatus) => {
          const colorMap: Record<BookStatus, string> = {
            AVAILABLE: 'green',
            CHECKED_OUT: 'blue',
            RESERVED: 'orange',
            MAINTENANCE: 'gold',
            LOST: 'red',
            DAMAGED: 'volcano',
          };
          return <Tag color={colorMap[status]}>{status}</Tag>;
        },
      },
      {
        title: 'Total Copies',
        dataIndex: 'total_copies',
        key: 'total_copies',
        width: 110,
      },
      {
        title: 'Available',
        dataIndex: 'available_copies',
        key: 'available_copies',
        width: 100,
      },
      {
        title: 'Location',
        dataIndex: 'location',
        key: 'location',
        width: 120,
      },
      {
        title: 'Actions',
        key: 'actions',
        width: 150,
        fixed: 'right' as const,
        render: (_: unknown, record: BookResponse) => (
          <Space size="small">
            <Button
              type="link"
              size="small"
              icon={<EditOutlined />}
              onClick={() => openEditBookModal(record)}
            >
              Edit
            </Button>
            <Button
              type="link"
              size="small"
              danger
              icon={<DeleteOutlined />}
              onClick={() => openDeleteConfirm(record)}
            >
              Delete
            </Button>
          </Space>
        ),
      },
    ],
    []
  );

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

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

  const categoryOptions = useMemo(
    () =>
      categories.map((category) => ({
        label: category.name,
        value: category.id,
      })),
    [categories]
  );

  return (
    <div
      style={{
        minHeight: '100vh',
        height: '100%',
        width: '100%',
        display: 'flex',
        flexDirection: 'column',
      }}
    >
      {contextHolder}
      <div
        style={{
          minHeight: '100vh',
          width: '100%',
          padding: '24px',
          background: '#f5f5f5',
        }}
      >
        <div
          style={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
            marginBottom: '24px',
          }}
        >
          <Typography.Title level={2} style={{ margin: 0 }}>
            Book Management
          </Typography.Title>
          <Space size="middle">
            <Button type="default" onClick={navigateToAuthors}>
              Authors
            </Button>
            <Button type="default" onClick={navigateToCategories}>
              Categories
            </Button>
            <Button type="default" onClick={navigateToPublishers}>
              Publishers
            </Button>
            <Button type="default" icon={<UploadOutlined />} onClick={openBulkImportModal}>
              Bulk Import
            </Button>
            <Button type="primary" icon={<PlusOutlined />} onClick={openAddBookModal}>
              Add New Book
            </Button>
          </Space>
        </div>

        <Card bordered={false} style={{ marginBottom: '16px' }}>
          <Space size="middle" wrap style={{ width: '100%' }}>
            <Input.Search
              placeholder="Search by title, ISBN, or author..."
              allowClear
              style={{ width: 320 }}
              value={searchText}
              onChange={onSearchChange}
            />
            <Select
              placeholder="Filter by Status"
              allowClear
              style={{ width: 180 }}
              value={statusFilter || undefined}
              onChange={onStatusFilterChange}
              options={[
                { label: 'Available', value: 'AVAILABLE' },
                { label: 'Checked Out', value: 'CHECKED_OUT' },
                { label: 'Reserved', value: 'RESERVED' },
                { label: 'Maintenance', value: 'MAINTENANCE' },
                { label: 'Lost', value: 'LOST' },
                { label: 'Damaged', value: 'DAMAGED' },
              ]}
            />
            <Select
              placeholder="Filter by Format"
              allowClear
              style={{ width: 160 }}
              value={formatFilter || undefined}
              onChange={onFormatFilterChange}
              options={[
                { label: 'Physical', value: 'PHYSICAL' },
                { label: 'Digital', value: 'DIGITAL' },
              ]}
            />
          </Space>
        </Card>

        <Card bordered={false}>
          <Table
            rowKey="id"
            dataSource={books}
            columns={columns}
            loading={loading}
            pagination={{
              current: pagination.current,
              pageSize: pagination.pageSize,
              total: pagination.total,
              showSizeChanger: true,
              showTotal: (total) => `Total ${total} items`,
              onChange: onPaginationChange,
            }}
            scroll={{ x: 1200 }}
          />
        </Card>
      </div>

      <Modal
        title="Add New Book"
        open={addBookModalVisible}
        onOk={handleAddBook}
        onCancel={closeAddBookModal}
        width={720}
        destroyOnClose
        okText="Add Book"
      >
        <Form form={addBookForm} layout="vertical" name="addBookForm">
          <Form.Item name="isbn" label="ISBN">
            <Input placeholder="Enter ISBN" />
          </Form.Item>
          <Form.Item
            name="title"
            label="Title"
            rules={[{ required: true, message: 'Title is required' }]}
          >
            <Input placeholder="Enter book title" />
          </Form.Item>
          <Form.Item name="subtitle" label="Subtitle">
            <Input placeholder="Enter subtitle" />
          </Form.Item>
          <Form.Item name="author_ids" label="Authors">
            <Select
              mode="multiple"
              placeholder="Select authors"
              allowClear
              showSearch
              optionFilterProp="label"
              options={authorOptions}
            />
          </Form.Item>
          <Form.Item name="publisher_id" label="Publisher">
            <Select
              placeholder="Select publisher"
              allowClear
              showSearch
              optionFilterProp="label"
              options={publisherOptions}
            />
          </Form.Item>
          <Form.Item name="category_ids" label="Categories">
            <Select
              mode="multiple"
              placeholder="Select categories"
              allowClear
              showSearch
              optionFilterProp="label"
              options={categoryOptions}
            />
          </Form.Item>
          <Form.Item name="publication_date" label="Publication Date">
            <DatePicker style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="edition" label="Edition">
            <Input placeholder="e.g., 2nd Edition" />
          </Form.Item>
          <Form.Item name="language" label="Language">
            <Input placeholder="e.g., English" />
          </Form.Item>
          <Form.Item name="pages" label="Page Count">
            <InputNumber min={1} placeholder="Number of pages" style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="description" label="Description">
            <Input.TextArea rows={4} placeholder="Book description" />
          </Form.Item>
          <Form.Item name="book_format" label="Format" initialValue="PHYSICAL">
            <Select
              options={[
                { label: 'Physical', value: 'PHYSICAL' },
                { label: 'Digital', value: 'DIGITAL' },
              ]}
            />
          </Form.Item>
          <Form.Item name="total_copies" label="Total Copies" initialValue={1}>
            <InputNumber min={1} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="available_copies" label="Available Copies" initialValue={1}>
            <InputNumber min={0} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="location" label="Shelf Location">
            <Input placeholder="e.g., A-3-12" />
          </Form.Item>
          <Form.Item name="status" label="Status" initialValue="AVAILABLE">
            <Select
              options={[
                { label: 'Available', value: 'AVAILABLE' },
                { label: 'Checked Out', value: 'CHECKED_OUT' },
                { label: 'Reserved', value: 'RESERVED' },
                { label: 'Maintenance', value: 'MAINTENANCE' },
                { label: 'Lost', value: 'LOST' },
                { label: 'Damaged', value: 'DAMAGED' },
              ]}
            />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="Edit Book"
        open={editBookModalVisible}
        onOk={handleEditBook}
        onCancel={closeEditBookModal}
        width={720}
        destroyOnClose
        okText="Save Changes"
      >
        <Form form={editBookForm} layout="vertical" name="editBookForm">
          <Form.Item name="isbn" label="ISBN">
            <Input placeholder="Enter ISBN" />
          </Form.Item>
          <Form.Item
            name="title"
            label="Title"
            rules={[{ required: true, message: 'Title is required' }]}
          >
            <Input placeholder="Enter book title" />
          </Form.Item>
          <Form.Item name="subtitle" label="Subtitle">
            <Input placeholder="Enter subtitle" />
          </Form.Item>
          <Form.Item name="publisher_id" label="Publisher">
            <Select
              placeholder="Select publisher"
              allowClear
              showSearch
              optionFilterProp="label"
              options={publisherOptions}
            />
          </Form.Item>
          <Form.Item name="publication_date" label="Publication Date">
            <DatePicker style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="edition" label="Edition">
            <Input placeholder="e.g., 2nd Edition" />
          </Form.Item>
          <Form.Item name="language" label="Language">
            <Input placeholder="e.g., English" />
          </Form.Item>
          <Form.Item name="pages" label="Page Count">
            <InputNumber min={1} placeholder="Number of pages" style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="description" label="Description">
            <Input.TextArea rows={4} placeholder="Book description" />
          </Form.Item>
          <Form.Item name="book_format" label="Format">
            <Select
              options={[
                { label: 'Physical', value: 'PHYSICAL' },
                { label: 'Digital', value: 'DIGITAL' },
              ]}
            />
          </Form.Item>
          <Form.Item name="total_copies" label="Total Copies">
            <InputNumber min={1} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="available_copies" label="Available Copies">
            <InputNumber min={0} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="location" label="Shelf Location">
            <Input placeholder="e.g., A-3-12" />
          </Form.Item>
          <Form.Item name="status" label="Status">
            <Select
              options={[
                { label: 'Available', value: 'AVAILABLE' },
                { label: 'Checked Out', value: 'CHECKED_OUT' },
                { label: 'Reserved', value: 'RESERVED' },
                { label: 'Maintenance', value: 'MAINTENANCE' },
                { label: 'Lost', value: 'LOST' },
                { label: 'Damaged', value: 'DAMAGED' },
              ]}
            />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="Confirm Delete"
        open={deleteConfirmVisible}
        onOk={handleDeleteBook}
        onCancel={closeDeleteConfirm}
        width={420}
        okText="Delete"
        okButtonProps={{ danger: true }}
      >
        <Typography.Text>
          Are you sure you want to delete this book? This action cannot be undone. Books with
          active loans or reservations cannot be deleted.
        </Typography.Text>
      </Modal>

      <Modal
        title="Bulk Import Books"
        open={bulkImportModalVisible}
        onCancel={closeBulkImportModal}
        width={520}
        footer={null}
      >
        <Upload.Dragger accept=".csv" maxCount={1}>
          <p className="ant-upload-drag-icon">
            <InboxOutlined />
          </p>
          <p className="ant-upload-text">Click or drag CSV file to upload</p>
        </Upload.Dragger>
        <Typography.Paragraph type="secondary" style={{ marginTop: '16px' }}>
          Upload a CSV file with columns: isbn, title, subtitle, publisher, publication_date,
          edition, language, pages, description, format, total_copies, location, status
        </Typography.Paragraph>
      </Modal>
    </div>
  );
}