import type { EntityID } from '@wovin/core/applog'
import type { DivergenceLeaf } from '@wovin/core/query'
import type { GenericSetter } from '@wovin/core/types'
import type { Accessor, Component } from 'solid-js'
import { reaction } from '@wovin/core/mobx'
import { Logger } from 'besonders-logger'
import stringify from 'safe-stable-stringify'
import { createSignal, For, Match, Switch } from 'solid-js'
import { BlockItem } from '../components/BlockContent'
import { HistoryPanel } from '../components/HistoryDialog'
import { ShortID } from '../components/mini-components'
import { DBContext, useBlockVM, useEntityAt } from '../ui/reactive'
import { createAsyncButtonHandler } from '../ui/utils-ui'
import { useBlockContext } from './block-ui-helpers'
import { deleteAndReplaceBlock } from './block-utils'
import { REL_DEF } from './data-types'

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

export type BlockPanelDef = BlockPanelDefPaste | BlockPanelDefHistory | BlockPanelDefSituation
export interface BlockPanelDefPaste {
	type: 'paste'
	share: string
	block: EntityID
}
export interface BlockPanelDefSituation {
	type: 'situation'
	leafs: DivergenceLeaf[]
}
export interface BlockPanelDefHistory {
	type: 'history'
}

export function useDivergencePanel(blockID: EntityID, setPanel: GenericSetter<BlockPanelDef>) {
	VERBOSE(`[useDivergencePanel#${blockID}] created`)
	const blockVM = useBlockVM(blockID)

	reaction(() => blockVM.contentDivergences, (divergences) => {
		if (divergences) {
			DEBUG(`[useDivergencePanel#${blockID}] found divergence:`, divergences)
			setPanel({ type: 'situation', leafs: divergences })
		}
	})
}

export const BlockPanel: Component<{
	blockID: EntityID
	relationID: EntityID
	panel: Accessor<BlockPanelDef>
}> = (props) => {
	const { panel } = props
	VERBOSE('[BlockPanel] created for', props)
	const { setPanel, depth, parentContext } = useBlockContext()

	const pullButtonProps = createAsyncButtonHandler(async () => {
		await deleteAndReplaceBlock(props.relationID, (panel() as BlockPanelDefPaste).block)
	})
	const blockContext = useBlockContext()

	return (
		<div border='1 solid purple-300' rounded p-4>
			<Switch fallback={`Invalid panel type: ${stringify(panel(), null, 4)}`}>
				<Match when={panel().type === 'paste'}>
					Pull from share
					{' '}
					<ShortID id={(panel() as BlockPanelDefPaste).share} />
					?
					<sl-button variant='primary' size='small' flex-self-end {...pullButtonProps}>Pull and insert</sl-button>
					<sl-button size='small' flex-self-end onClick={() => setPanel(null)}>Cancel</sl-button>
				</Match>
				<Match when={panel().type === 'history'}>
					<HistoryPanel blockID={props.blockID} />
				</Match>
				<Match when={panel().type === 'situation'}>
					<div mt--1 text-xs title={stringify(panel().leafs.map(({ log, thread }) => ({ log, thread: thread.name })), null, 4)}>
						We got a Situation
					</div>

					<div mt-2 flex='~ col' gap-2>
						<For each={panel().leafs}>
							{({ log, thread }) => {
								const [isExpanded, setExpanded] = props.relationID
									? useEntityAt<boolean>(props.relationID, REL_DEF.isExpanded, true)
									: createSignal(true) // HACK: isExpanded on root nodes?

								return (
									<div p-1 border='1 solid purple-500' rounded>
										<DBContext.Provider value={() => thread /* TODO: readonly thread */}>
											{/* <BlockContext.Provider value={{ id: blockID, relationToParent: relation?.en, /* , setPanel * / parentContext, depth}}> */}
											<BlockItem
												{...{ blockID: props.blockID, isExpanded, setExpanded }}
												relationID={props.relationID}
												readOnly={true}
												hasKids={true /* kidRelations.length > 0 */}
											/>
										</DBContext.Provider>
									</div>
								)
							}}
						</For>
					</div>
					{/* <pre>{JSON.stringify(panel().leafs.map(({log,thread})=>({log, thread:thread.name})), null, 4)}</pre> */}
				</Match>
			</Switch>
		</div>
	)
}
