'use client';

import React, { useEffect, useState, useRef } from "react";
import { Card } from 'primereact/card';
import { Image } from 'primereact/image';
import { Button } from 'primereact/button';
import { InputText } from 'primereact/inputtext';
// 页面跳转
import { useRouter } from 'next/navigation';
// 消息提醒
import { Toast } from 'primereact/toast';
// 分页
import { Paginator, type PaginatorPageChangeEvent } from 'primereact/paginator';
// 评分图标
import { Fire } from '@icon-park/react';
// 接口传输
import axios from 'axios';
// 标签
import { Tag } from 'primereact/tag';
import { Sidebar } from 'primereact/sidebar';
// 防抖函数
import { debounce } from 'lodash';
import { useLocalStorage } from '../../hook/useLocalStorage';
// 样式
import './classification.scss';

interface User {
  Id: number;
}
// 热门资源数据
interface HotResource {
  resourceId: number;
  resourceName: string;
  resourcePicture: string;
  resourceSummary: string;
  lastUpdateTime: string;
  hot: number;
  gamePlayList: { gameplayName: string }[];
}

interface HotResourceList {
  total: number;
  records: HotResource[];
}
// 主页
export default function ClassificationResource() {
  const user = useLocalStorage<User>('user');
  const userId: number = user?.Id ?? -1;

  // 热门资源列表
  const [hotResources, setHotResources] = useState<HotResource[]>([]);
  const [totalHotResource, setTotalHotResource] = useState(0);
  const [visibleRight, setVisibleRight] = useState<boolean>(false);

  // 消息提醒
  const toast = useRef<Toast>(null);
  const router = useRouter();

  // 当前选中的 classify
  const [selectedClassify, setSelectedClassify] = useState<string>('模组');
  const [selectedGameplay, setSelectedGameplay] = useState<string[]>([]);
  const [selectedVersions, setSelectedVersions] = useState<string[]>([]);
  const [searchValue, setSearchValue] = useState<string>('');
  const debouncedSearch = useRef(
    debounce((value: string) => {
      setSearchValue(value);
    }, 600)
  ).current;
  // 分页
  const [first, setFirst] = useState(0);
  const [rows, setRows] = useState(5);
  const onPageChange = (event: PaginatorPageChangeEvent) => {
    setFirst(event.first);
    setRows(event.rows);
  };
  // 获取帖子列表
  useEffect(() => {
    handleSearch();
  }, [first, rows, searchValue]);

  const handleSearch = async () => {
    try {
      const pageNumber = first / rows + 1;
      console.log(searchValue + " 当前页: " + pageNumber + "rows: " + rows + "selectedClassify: " + selectedClassify + "selectedGameplay: " + selectedGameplay + "selectedVersions: " + selectedVersions);
      const response = await axios.get<HotResourceList>(process.env.PUBLIC_URL + `/resource/search`, {
        params: {
          userId,
          pageNumber,
          rows,
          classify: selectedClassify,
          gameplayList: selectedGameplay.join(','),
          versionList: selectedVersions.join(','),
          searchValue
        }
      });
      setHotResources(response.data.records);
      setTotalHotResource(response.data.total);
      setVisibleRight(false);
    } catch (err) {
      console.error('搜索资源失败', err);
      toast.current?.show({ severity: 'error', summary: 'error', detail: '搜索资源失败' });
    }
  };

  return (
    <div className="HotResource">
      <div className="header">
        <div className="searchBar">
          <i className="pi pi-search" />
          <InputText type="search" className="search-helper" placeholder="搜索你感兴趣的帖子" onChange={(e) => { const target = e.target as HTMLInputElement; debouncedSearch(target.value); }} />
        </div>
        <Button label="查看分类" className="classificationButton" onClick={() => setVisibleRight(true)} />
      </div>
      {/* 全部社区 */}
      <div className="all-resources-list">
        {hotResources.map((hotResource) => (
          <Card key={hotResource.resourceId} className="all-resources-card" onClick={() => router.push(`/resource/resource-detail/${hotResource.resourceId}`)}>
            <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + "hotResource/" + hotResource.resourcePicture} className="resource-avatar" width="250" height="140" />
            <div className="resource-header">
              <div className="resource-content">
                <h3>{hotResource.resourceName}</h3>
                <div className="tags">
                  {hotResource.gamePlayList.map((tag, index) => (
                    <Tag key={index} value={tag.gameplayName} />
                  ))}
                </div>
              </div>
              <div className="resources-states">
                <div className="state-item">
                  <Fire theme="outline" size="16" fill="#FF8D1A" />
                  <span>热度: {hotResource.hot}</span>
                </div>
                <div className="state-item">
                  <span>最新更新时间: {hotResource.lastUpdateTime}</span>
                </div>
              </div>
            </div>
          </Card>
        ))}
      </div>
      {totalHotResource > 5 && (<Paginator className="Paginator" first={first} rows={rows} totalRecords={totalHotResource} rowsPerPageOptions={[5, 10]} onPageChange={onPageChange} />)}
      <Sidebar className="sidebar" visible={visibleRight} position="right" onHide={() => setVisibleRight(false)}>
        <div className="sidebar-content">
          <h3>分类</h3>
          <div className="filter-section">
            {['模组', '地图', '整合包', '材质包'].map((item) => (
              <Button key={item} label={item} className={selectedClassify === item ? 'p-button-primary' : 'p-button-text'} onClick={() => setSelectedClassify(item)} />
            ))}
          </div>

          <h3>主要玩法</h3>
          <div className="filter-section">
            {['不限', '科技', '魔法', '建筑', '风景', '竞技', '生存', '冒险', '跑酷', '艺术', '剧情', '社交', '策略', '极限'].map((gameplay) => (
              <Button
                key={gameplay}
                label={gameplay}
                className={selectedGameplay.includes(gameplay) ? 'p-button-primary' : 'p-button-text'}
                onClick={() => {
                  if (selectedGameplay.includes(gameplay)) {
                    setSelectedGameplay(selectedGameplay.filter((g) => g !== gameplay));
                  } else {
                    setSelectedGameplay([...selectedGameplay, gameplay]);
                  }
                }}
              />
            ))}
          </div>

          <h3>游戏版本</h3>
          <div className="filter-section">
            {['不限', '1.20.1', '1.20.4', '1.7.3', '1.12.1', '1.19.2', '1.18.3', '1.20.3', '1.19.1', '1.18.6'].map((ver) => (
              <Button
                key={ver}
                label={ver}
                className={selectedVersions.includes(ver) ? 'p-button-primary' : 'p-button-text'}
                onClick={() => {
                  if (selectedVersions.includes(ver)) {
                    setSelectedVersions(selectedVersions.filter((v) => v !== ver));
                  } else {
                    setSelectedVersions([...selectedVersions, ver]);
                  }
                }}
              />
            ))}
          </div>
          <div className="filter-confirm">
            <Button label="确定" icon="pi pi-check" onClick={handleSearch} />
          </div>
        </div>
      </Sidebar>
    </div>
  );
}
