import {Input} from "antd";
import {useBoolean, useLocalStorageState, useSetState,useClickAway} from "ahooks";
import {useCallback, useEffect, useMemo, useRef, useState} from "react";
import {clsx} from "clsx";
import useArticleTags from "@/hooks/useArticleTags.ts";

import {UpOutlined, MenuOutlined, SearchOutlined} from "@ant-design/icons";
import TimeSelect from "@/components/form/time-select.tsx";

import styles from './style.module.scss'
import {IconPin} from "@/components/icons";
import {useTranslation} from "react-i18next";

type SearchPanelProps = {
	onSearch?: (params: ApiArticleSearchParams) => void;
	defaultParams?: Partial<ApiArticleSearchParams>;
}
const pagination = {
	limit: 12, page: 1
}
const DEFAULT_STATE = {
	tag_level_1_id: -1,
	tag_level_2_id: -1,
	subOptions: []
}
export default function SearchPanel({onSearch,defaultParams}: SearchPanelProps) {
	const tags = useArticleTags();
	const {t} = useTranslation()
	const [params, setParams] = useSetState<ApiArticleSearchParams>({
		pagination,
		time_flag:1,
		...(defaultParams || {})
	});
	const [prevSearchName, setPrevSearchName] = useState<string>(defaultParams?.title||'')

	const [state, setState] = useSetState<{
		tag_level_1_id: number;
		tag_level_2_id: number;
		subOptions: (string | number)[]
	}>({
		...DEFAULT_STATE,
		...(defaultParams&&defaultParams.tag_level_1_id?{tag_level_1_id:defaultParams.tag_level_1_id}: {}),
		...(defaultParams&&defaultParams.tag_level_2_id?{tag_level_2_id:defaultParams.tag_level_2_id}: {})
	})
	useEffect(()=>{
		if(!defaultParams){
			return;
		}
		const _state = {
			tag_level_1_id: -1,
			tag_level_2_id: -1,
		}

		if(defaultParams.tag_level_1_id){
			_state.tag_level_1_id = defaultParams.tag_level_1_id
			if(tags && tags.length > 0){
				const tag = tags.find(s => s.value == defaultParams.tag_level_1_id)
				setSubOptions(tag?.children || [])
			}
		}
		if(defaultParams.tag_level_2_id){
			_state.tag_level_2_id = defaultParams.tag_level_2_id
		}
		setState(_state)
	},[tags])
	const [pinnedTag, setPinnedTag] = useLocalStorageState<number[]>(
		'user-pinned-tag-list',
		{
			defaultValue: [],
		},
	);

	// 二级分类
	const [subOptions, setSubOptions] = useState<OptionItem[]>([])
	const onFinish = () => {
		if (params.title == prevSearchName || (!params.title && !prevSearchName)) return
		params.title = prevSearchName;
		setParams({title: prevSearchName})

		onSearch?.({
			...params,
			title: prevSearchName,
			tag_level_1_id: state.tag_level_1_id > 0 ? state.tag_level_1_id : undefined,
			tag_level_2_id: state.tag_level_2_id > 0 ? state.tag_level_2_id : undefined,
			pagination
		})
	}
	const handleTimeFilter = (time_flag: number) => {
		const searchParams = {
			...params,
			time_flag,
			pagination
		}
		setParams(searchParams)
		onSearch?.(searchParams)
	}
	const handleFilter = (_params: Partial<ApiArticleSearchParams>) => {
		const searchParams = {
			...params,
			..._params,
			pagination
		}
		setParams(searchParams)
		setState({
			...state,
			tag_level_1_id: _params.tag_level_1_id || -1,
			tag_level_2_id: _params.tag_level_2_id || -1,
		})
		onSearch?.(searchParams)
	}
	const pinnedList = useMemo(() => {
		if (tags?.length > 0) {
			const pinnedList = pinnedTag && pinnedTag?.length > 0 ? pinnedTag : tags.map(s => s.value)
			return pinnedList.filter(it => tags.findIndex(s => s.value == it) != -1)
				.sort((a, b) => Number(a) - Number(b))
				.map(it => (tags.find(s => s.value == it) as OptionItem))
		}
		return [] as OptionItem[];
	}, [pinnedTag, tags])
	const pinnedManagePanel = useRef<HTMLDivElement|null>(null)

	const togglePinnedManagePanel = useCallback((visible: boolean) => {
			if(!pinnedManagePanel.current){
				return;
			}
			const _target = pinnedManagePanel.current!;
			if(visible){
				_target.style.height = 'auto'
				const {height} = _target.getBoundingClientRect()
				_target.style.height = '38px'
				requestAnimationFrame(()=>{
					_target.style.height = `${height}px`
				})
			}else{
				requestAnimationFrame(()=>{
					_target.style.height = '0'
				})
			}
		},[pinnedManagePanel])
	const setTrue = ()=> togglePinnedManagePanel(true)
	const setFalse = ()=>togglePinnedManagePanel(false)
	useClickAway(() => setFalse(), pinnedManagePanel)

	return (<div className={`${styles.searchPanel} pt-6 pb-2`}>
		<div className="flex justify-between items-center">
			<div className="search-form flex items-center gap-4">
				<Input
					value={prevSearchName}
					onChange={e => setPrevSearchName(e.target.value)}
					className="w-[270px] rounded-3xl"
					placeholder={t('news.search_key_title')}
					onPressEnter={onFinish}
					onBlur={onFinish}
					prefix={<SearchOutlined/>}
				/>
				<TimeSelect
					className="w-[140px] ml-1"
					value={typeof(params.time_flag) != "undefined" ? params.time_flag : 1}
					onChange={handleTimeFilter}
				/>
			</div>
		</div>
		<div className="filter-container mt-5">
			<div className="list-container relative">
				<div className="justify-between flex items-start border-b pb-2 overflow-hidden">
					<div className="pinned-tag-list flex flex-wrap flex-1 min-w-0">
						<div
							className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.tag_level_1_id == -1 ? 'selected' : ''}`}
							onClick={() => {
								handleFilter({tag_level_1_id: -1, tag_level_2_id: -1})
								setSubOptions([])
							}}>{t('news.filter_all')}
						</div>
						{pinnedList.filter(s => (Number(s.value) !== 999999)).map(it => (
							<span
								className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.tag_level_1_id == it.value ? 'selected' : ''}`}
								key={it.value}
								onClick={() => {
									handleFilter({tag_level_1_id: Number(it.value), tag_level_2_id: -1})
									setSubOptions(it.children || [])
								}}>{it.label}</span>)
						)}
					</div>
					<div className="pinned-menu mt-2">
						<span className={'cursor-pointer block hover:text-blue-500'} onClick={e=>{
							e.stopPropagation();
							e.preventDefault();
							setTrue();
						}}>
							<MenuOutlined style={{fontSize: 20}}/>
						</span>
					</div>
				</div>

				<div ref={pinnedManagePanel} className={clsx(styles.pinnedManagePanelContainer)}>
				{/* 固定新闻来源 */}
				<div className={clsx(styles.pinnedManagePanel)}>
					<div className="header flex justify-between">
						<div className="title font-bold">{t('news.filter_source')}</div>
						<div className={'cursor-pointer block hover:text-blue-500'} onClick={setFalse}>
							<UpOutlined style={{fontSize: 20}}/>
						</div>
					</div>
					<div className="tags-list-container">
						{
							tags.filter(s => s.value !== 999999).map(it => {
								const currentPinned = pinnedTag?.includes(Number(it.value));
								return (<div
									className={`filter-item border flex items-center px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${currentPinned?'bg-gray-100':''} hover:border-gray-400`}
									key={it.value}
									onClick={() => {
										const value = Number(it.value)
										if (pinnedTag && pinnedTag.includes(value)) {
											setPinnedTag(pinnedTag.filter(s => s != value))
										} else {
											setPinnedTag([...(pinnedTag || []), value])
										}
									}}>
									<span>{it.label}</span>
									{currentPinned &&
                                        <span className={'ml-2'}><IconPin/></span>}
								</div>)
							})

						}
					</div>
				</div>
				</div>
				{/* 二级目录 */}
				{state.tag_level_1_id != -1 && subOptions.length > 0 &&
                    <div
                        className="absolute news-source-lv-2 flex items-center absolute left-0 right-0">
						{
							subOptions.map(it => (
								<div
									className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.tag_level_2_id == it.value ? 'text-black' : ' text-gray-400 hover:text-gray-600'}`}
									key={it.value}
									onClick={() => {
										handleFilter({tag_level_1_id:state.tag_level_1_id,tag_level_2_id: Number(it.value)})
									}}>{it.label}</div>)
							)
						}
                    </div>}
			</div>

		</div>
	</div>)
}