import React, { useEffect, useMemo } from 'react';
import { useDispatch } from 'react-redux';
import { Input, Spin, Alert } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import type { Section, Artwork } from './types';
import { initializeArtworks, selectFilteredArtworks, selectSearchTerm, selectWorkListError, selectWorkListLoading, setSearchTerm } from './workListSlice';
import { useAppSelector } from '../../store/hooks';
import { selectSections, selectCategoryLoading, selectCategoryError, initializeSections } from './categorySlice';
import Category from './Category';

const Home: React.FC = () => {
    const dispatch = useDispatch();

    // 从Redux store获取状态
    const sections = useAppSelector(selectSections);
    const filteredArtworks = useAppSelector(selectFilteredArtworks);
    const searchTerm = useAppSelector(selectSearchTerm);
    const workListLoading = useAppSelector(selectWorkListLoading);
    const workListError = useAppSelector(selectWorkListError);
    const categoryLoading = useAppSelector(selectCategoryLoading);
    const categoryError = useAppSelector(selectCategoryError);

    // 综合加载状态和错误状态
    const loading = workListLoading || categoryLoading;
    const error = workListError || categoryError;

    // 示例数据
    const sampleSections: Section[] = [
        {
            id: 1,
            childrenid: [1, 2, 3],
            name: "数字艺术"
        },
        {
            id: 2,
            childrenid: [4, 5],
            name: "传统绘画"
        }
    ];

    const sampleArtworks: Artwork[] = [
        {
            id: 1,
            title: "未来城市概念设计",
            author: "视觉设计师张三",
            views: 1247,
            category: {
                id: 1,
                name: "数字艺术",
                children: ["概念设计", "建筑设计"]
            },
            description: "一个关于2050年智慧城市的概念设计作品，融合了可持续发展、人工智能和绿色科技的理念",
            createTime: "2024-01-15T10:30:00Z",
            cover: "https://picsum.photos/300/200?random=1"
        },
        {
            id: 2,
            title: "移动应用界面设计套件",
            author: "UI设计师李四",
            views: 856,
            category: {
                id: 2,
                name: "界面设计",
                children: ["UI/UX设计", "移动端设计"]
            },
            description: "一套完整的移动端UI设计规范和组件库，包含100+个精美界面和500+个设计组件",
            createTime: "2024-02-20T14:15:00Z",
            cover: "https://picsum.photos/300/200?random=2"
        },
        {
            id: 3,
            title: "React组件库开发指南",
            author: "刘松林",
            views: 432,
            category: {
                id: 3,
                name: "程序开发",
                children: ["前端开发", "React技术"]
            },
            description: "一套完整的企业级React组件库开发教程和源码，包含从设计到发布的完整流程",
            createTime: "2024-03-10T09:45:00Z",
            cover: "https://picsum.photos/300/200?random=3"
        },
        {
            id: 4,
            title: "机械战士3D模型",
            author: "3D艺术家王五",
            views: 789,
            category: {
                id: 1,
                name: "数字艺术",
                children: ["3D建模", "科幻设计"]
            },
            description: "一个高精度的科幻机械战士3D模型，包含完整的材质贴图和动画骨骼系统",
            createTime: "2024-01-25T16:20:00Z",
            cover: "https://picsum.photos/300/200?random=4"
        },
        {
            id: 5,
            title: "城市夜景摄影集",
            author: "摄影师赵六",
            views: 1123,
            category: {
                id: 4,
                name: "摄影艺术",
                children: ["摄影作品", "城市风光"]
            },
            description: "一组精美的城市夜景摄影作品，捕捉了都市夜晚的璀璨光影",
            createTime: "2024-02-14T11:30:00Z",
            cover: "https://picsum.photos/300/200?random=5"
        },
        {
            id: 6,
            title: "奇幻世界插画系列",
            author: "插画师孙七",
            views: 945,
            category: {
                id: 5,
                name: "插画艺术",
                children: ["插画艺术", "奇幻风格"]
            },
            description: "一套充满想象力的奇幻题材插画作品，包含角色设计、场景概念图和完整插图",
            createTime: "2024-03-05T13:20:00Z",
            cover: "https://picsum.photos/300/200?random=6"
        }
    ];

    // 初始化数据
    useEffect(() => {
        dispatch(initializeArtworks(sampleArtworks));
        dispatch(initializeSections(sampleSections));
    }, [dispatch]);

    // 处理搜索输入
    const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        dispatch(setSearchTerm(e.target.value));
    };

    // 根据分区ID获取对应的作品
    const getArtworksBySection = useMemo(() => {
        return (childrenIds: number[]): Artwork[] => {
            return filteredArtworks.filter(artwork => childrenIds.includes(artwork.id));
        };
    }, [filteredArtworks]);

    // 渲染加载状态
    if (loading) {
        return (
            <div style={{
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center',
                height: '100vh'
            }}>
                <Spin size="large" tip="加载中..." />
            </div>
        );
    }

    // 渲染错误状态
    if (error) {
        return (
            <div style={{ padding: '24px' }}>
                <Alert
                    message="加载失败"
                    description={error}
                    type="error"
                    showIcon
                />
            </div>
        );
    }

    return (
        <div style={{
            backgroundColor: '#f5f5f5',
            minHeight: '100vh',
            padding: '24px'
        }}>
            <div style={{ maxWidth: 1200, margin: '0 auto' }}>
                {/* 搜索栏 */}
                <div style={{ marginBottom: '32px' }}>
                    <Input
                        size="large"
                        placeholder="搜索作品标题、作者、分类..."
                        prefix={<SearchOutlined />}
                        value={searchTerm}
                        onChange={handleSearchChange}
                        style={{ maxWidth: 600, width: '100%' }}
                        allowClear
                    />
                </div>

                {/* 分区展示 */}
                {sections.map((section) => {
                    const sectionArtworks = getArtworksBySection(section.childrenid);

                    return (
                        <Category
                            key={section.id}
                            section={section}
                            artworks={sectionArtworks}
                        />
                    );
                })}

                {/* 无搜索结果提示 */}
                {searchTerm && filteredArtworks.length === 0 && (
                    <div style={{
                        textAlign: 'center',
                        padding: '48px 0',
                        color: '#999'
                    }}>
                        <p style={{ fontSize: 16 }}>未找到相关作品</p>
                        <p>尝试使用其他关键词搜索</p>
                    </div>
                )}
            </div>
        </div>
    );
};

export default Home;
