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

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

interface CategoryCreate {
  name: string;
  description?: string | null;
  parent_category_id?: string | null;
}

interface CategoryUpdate {
  name?: string | null;
  description?: string | null;
  parent_category_id?: string | null;
}

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

  const [categories, setCategories] = useState<CategoryResponse[]>([]);
  const [isModalVisible, setIsModalVisible] = useState<boolean>(false);
  const [editingCategory, setEditingCategory] = useState<CategoryResponse | null>(null);
  const [loading, setLoading] = useState<boolean>(false);
  const [searchText, setSearchText] = useState<string>('');

  const filteredCategories = useMemo(() => {
    return categories.filter(c => 
      c.name.toLowerCase().includes(searchText.toLowerCase())
    );
  }, [categories, searchText]);

  const parentCategoryOptions = useMemo(() => {
    return categories
      .filter(c => c.id !== editingCategory?.id)
      .map(c => ({ label: c.name, value: c.id }));
  }, [categories, editingCategory]);

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

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

  const openAddModal = useCallback(() => {
    setIsModalVisible(true);
    setEditingCategory(null);
    form.resetFields();
  }, [form]);

  const openEditModal = useCallback((record: CategoryResponse) => {
    setIsModalVisible(true);
    setEditingCategory(record);
    form.setFieldsValue({
      name: record.name,
      description: record.description,
      parent_category_id: record.parent_category_id
    });
  }, [form]);

  const closeModal = useCallback(() => {
    setIsModalVisible(false);
    setEditingCategory(null);
    form.resetFields();
  }, [form]);

  const submitCategory = useCallback(async () => {
    try {
      const formValues = await form.validateFields();
      setLoading(true);

      if (editingCategory) {
        const body: CategoryUpdate = {
          name: formValues.name || null,
          description: formValues.description || null,
          parent_category_id: formValues.parent_category_id || null
        };
        await request<CategoryResponse>({
          method: 'PUT',
          path: '/catalog/categories/{category_id}',
          pathParams: { category_id: editingCategory.id },
          body
        });
        messageApi.success('Category updated successfully');
      } else {
        const body: CategoryCreate = {
          name: formValues.name,
          description: formValues.description || null,
          parent_category_id: formValues.parent_category_id || null
        };
        await request<CategoryResponse>({
          method: 'POST',
          path: '/catalog/categories',
          body
        });
        messageApi.success('Category created successfully');
      }

      setIsModalVisible(false);
      setEditingCategory(null);
      form.resetFields();
      await fetchCategories();
    } catch (error) {
      if (editingCategory) {
        messageApi.error('Failed to update category');
      } else {
        messageApi.error('Failed to create category');
      }
    } finally {
      setLoading(false);
    }
  }, [form, editingCategory, messageApi, fetchCategories]);

  const deleteCategory = useCallback((categoryId: string) => {
    Modal.confirm({
      title: 'Delete Category',
      content: 'Are you sure you want to delete this category?',
      okText: 'Delete',
      okType: 'danger',
      cancelText: 'Cancel',
      onOk: async () => {
        setLoading(true);
        try {
          await request({
            method: 'DELETE',
            path: '/catalog/categories/{category_id}',
            pathParams: { category_id: categoryId }
          });
          messageApi.success('Category deleted successfully');
          await fetchCategories();
        } catch (error) {
          messageApi.error('Cannot delete category that has books assigned');
        } finally {
          setLoading(false);
        }
      }
    });
  }, [messageApi, fetchCategories]);

  const navigateToDashboard = useCallback(() => {
    navigate(ROUTES.STAFF_DASHBOARD || '/staff/dashboard');
  }, [navigate]);

  const navigateToBooks = useCallback(() => {
    navigate(ROUTES.STAFF_BOOKS || '/staff/books');
  }, [navigate]);

  const getParentCategoryName = useCallback((parentId: string | null) => {
    if (!parentId) return '-';
    const parent = categories.find(c => c.id === parentId);
    return parent ? parent.name : '-';
  }, [categories]);

  const columns = useMemo(() => [
    {
      title: 'Name',
      dataIndex: 'name',
      key: 'name',
      sorter: (a: CategoryResponse, b: CategoryResponse) => a.name.localeCompare(b.name)
    },
    {
      title: 'Description',
      dataIndex: 'description',
      key: 'description',
      ellipsis: true,
      render: (text: string | null) => text || '-'
    },
    {
      title: 'Parent Category',
      dataIndex: 'parent_category_id',
      key: 'parent_category_id',
      render: (parentId: string | null) => getParentCategoryName(parentId)
    },
    {
      title: 'Created',
      dataIndex: 'created_at',
      key: 'created_at',
      render: (date: string) => new Date(date).toLocaleDateString()
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, record: CategoryResponse) => (
        <Space size="small">
          <Button
            type="link"
            icon={<EditOutlined />}
            size="small"
            onClick={() => openEditModal(record)}
          >
            Edit
          </Button>
          <Button
            type="link"
            danger
            icon={<DeleteOutlined />}
            size="small"
            onClick={() => deleteCategory(record.id)}
          >
            Delete
          </Button>
        </Space>
      )
    }
  ], [getParentCategoryName, openEditModal, deleteCategory]);

  const rootStyle: CSSProperties = {
    minHeight: '100vh',
    height: '100%',
    width: '100%',
    display: 'flex',
    flexDirection: 'column',
    padding: '24px',
    background: '#f5f5f5'
  };

  const headerSectionStyle: CSSProperties = {
    marginBottom: '24px'
  };

  const titleRowStyle: CSSProperties = {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center'
  };

  const searchBarStyle: CSSProperties = {
    maxWidth: '400px',
    marginBottom: '16px'
  };

  const cardStyle: CSSProperties = {
    borderRadius: '6px'
  };

  return (
    <div style={rootStyle}>
      {contextHolder}
      <div style={headerSectionStyle}>
        <Breadcrumb
          style={{ marginBottom: '16px' }}
          items={[
            {
              title: <a onClick={navigateToDashboard}>Dashboard</a>
            },
            {
              title: 'Categories'
            }
          ]}
        />
        <div style={titleRowStyle}>
          <Typography.Title level={2} style={{ margin: 0 }}>
            Category Management
          </Typography.Title>
          <Button
            type="primary"
            icon={<PlusOutlined />}
            onClick={openAddModal}
          >
            Add Category
          </Button>
        </div>
      </div>

      <Card style={cardStyle}>
        <Input.Search
          placeholder="Search categories by name..."
          allowClear
          value={searchText}
          onChange={(e) => setSearchText(e.target.value)}
          style={searchBarStyle}
        />
        <Table
          rowKey="id"
          dataSource={filteredCategories}
          columns={columns}
          loading={loading}
          pagination={{ pageSize: 20 }}
        />
      </Card>

      <Modal
        title={editingCategory ? 'Edit Category' : 'Add Category'}
        open={isModalVisible}
        onCancel={closeModal}
        destroyOnClose
        footer={null}
      >
        <Form
          form={form}
          layout="vertical"
          onFinish={submitCategory}
        >
          <Form.Item
            label="Category Name"
            name="name"
            rules={[{ required: true, message: 'Please enter category name' }]}
          >
            <Input placeholder="Enter category name" />
          </Form.Item>

          <Form.Item
            label="Description"
            name="description"
          >
            <Input.TextArea
              placeholder="Enter category description"
              rows={3}
            />
          </Form.Item>

          <Form.Item
            label="Parent Category"
            name="parent_category_id"
          >
            <Select
              placeholder="Select parent category (optional)"
              allowClear
              showSearch
              optionFilterProp="label"
              options={parentCategoryOptions}
            />
          </Form.Item>

          <Button
            type="primary"
            htmlType="submit"
            block
            loading={loading}
            style={{ marginTop: '8px' }}
          >
            Save
          </Button>
        </Form>
      </Modal>
    </div>
  );
}