import type { Component, JSX } from 'solid-js'
import type { IconName } from './mini-components'
import { A, useLocation, useSearchParams } from '@solidjs/router'
import { Logger } from 'besonders-logger'
import { createMemo, For, Show, splitProps } from 'solid-js'
import { useSearchContext } from '../data/search'
import { useAppSettings } from '../ui/app-settings'
import { useFocus } from '../ui/reactive'
import { replaceSearchParamsInUrl, useLocationNavigate } from '../ui/utils-ui'
import { Iconify } from './mini-components'

const { WARN, LOG, DEBUG, VERBOSE, ERROR } = Logger.setup(Logger.INFO) // eslint-disable-line unused-imports/no-unused-vars

interface Pill {
	key: string
	title?: string
	icon?: IconName
	link?: string | Record<string, string>
	filter?: string
	isActive?: boolean
}

const ByTag = { key: 'by-tag', icon: 'tag', title: 'By Tag', filter: 'by-tag' } as const
const Timeline = { key: 'timeline', icon: 'clock-light', title: 'Timeline', link: `/timeline` } as const
function HomeBlock() {
	const appSettings = useAppSettings()
	return { key: 'home', icon: 'house', title: 'Home', link: `/block/${appSettings.homeBlock}` } as const
}

export const Pills = {
	ByTag,
	Timeline,
	HomeBlock,
} as const

export const PillFilter: Component<
	JSX.HTMLAttributes<HTMLDivElement> & {
		leftPills?: Pill[]
		rightPills?: Pill[]
	}
> = (allProps) => {
	const [props, restProps] = splitProps(allProps, ['leftPills', 'rightPills'])

	const { locnav, location, navigate } = useLocationNavigate()
	const focus = useFocus()
	const appSettings = useAppSettings()
	const [search, setSearch] = useSearchContext()
	const [params, setParams] = useSearchParams()

	const leftPills = createMemo(() => {
		const pills = props.leftPills ?? []
		const isOnHomeBlock = !!(focus() === appSettings.homeBlock)
		if (!isOnHomeBlock && focus() || params.preview) return pills // HACK: if params.pub, then too - refactor the responsibility outta here
		if (!search()) {
			// TODO refactor to props
			pills.push(HomeBlock())
			pills.push(Timeline)
		}
		DEBUG(`leftPills:`, pills)
		return pills satisfies readonly Pill[]
	})
	const rightPills = createMemo(() => {
		const pills = props.rightPills ?? []

		if (search()) {
			pills.push(ByTag)
		}
		// if (focus()) return pills
		DEBUG(`rightPills:`, pills)
		return pills satisfies readonly Pill[]
	})

	return (
		<Show when={leftPills()?.length || rightPills()?.length}>
			<div flex='~ items-center wrap justify-between' gap-2 {...restProps}>
				{
					/* <Show when={active().length}>
					<A class='no-underline text-white' href={replaceSearchParamInUrl(location, 'filters', null)}>
						<sl-tag size='small' pill removable variant='primary'>
						</sl-tag>
					</A>
					<A class='no-underline text-white' href={replaceSearchParamInUrl(location, 'filters', null)}>
						<sl-tag size='small' pill variant='primary'>
							<Iconify name='x' />
						</sl-tag>
					</A>
					<A class='no-underline text-white' href={replaceSearchParamInUrl(location, 'filters', null)}>
						<sl-tag size='small' pill variant={'primary'} removable={false}>
							<Iconify size={4} name='clock-light' />
							{'Title'}
						</sl-tag>
					</A>
				</Show> */
				}
				<div flex='~ items-center wrap' gap-2>
					<For
						each={leftPills()}
					>
						{pill => <SinglePill pill={pill} />}
					</For>
				</div>
				<div flex='~ items-center wrap' gap-2>
					<For
						each={rightPills()}
					>
						{pill => <SinglePill pill={pill} />}
					</For>
				</div>
			</div>
		</Show>
	)
}

const SinglePill: Component<{ pill: Pill }> = (props) => {
	const location = useLocation()
	const [params, setParams] = useSearchParams()

	const activeFilters = useFilters()

	const isActive = createMemo(() =>
		props.pill.isActive
		|| (typeof props.pill.link === 'string' && location.pathname.startsWith(props.pill.link))
		|| activeFilters().includes(props.pill.key),
	)
	const filterAfterToggle = createMemo(() =>
		isActive()
			? params.filters?.replace(props.pill.filter ?? props.pill.key, '').trim()
			: `${params.filters ?? ''} ${props.pill.filter ?? props.pill.key}`.trim(),
	)
	const link = createMemo(() => {
		if (props.pill.link) {
			if (typeof props.pill.link === 'string') {
				return `${props.pill.link}${new URLSearchParams(location.query).size ? '?' : ''}${new URLSearchParams(location.query).toString()}` // (i) keep search, filters, ...
			}
			const url = location
			if (Object.keys(props.pill.link).length !== 1) throw new Error(`TODO: pill link multi param`)
			for (const [param, val] of Object.entries(props.pill.link)) {
				return replaceSearchParamsInUrl(location, { [param]: val })
			}
		}
		return replaceSearchParamsInUrl(location, { filters: filterAfterToggle() })
	})
	return (
		<A class='a-unstyled' href={link()}>
			<sl-tag size='small' pill variant={isActive() ? 'primary' : null} removable={false}>
				<Iconify name={props.pill.icon} />
				{props.pill.title}
			</sl-tag>
		</A>
	)
}
export function useFilters() {
	const [params] = useSearchParams()
	return createMemo(() => {
		const filterStrings = (params.filters && !Array.isArray(params.filters)) // params weirdly might be string or array :/
			? [params.filters] as const
			: params.filters as string[] | null
		const tokens = filterStrings?.flatMap(f => f.split(/\s+/))
		DEBUG(`Search tokens`, { tokens, search: params.filters })
		return tokens ?? []
	})
}
