import type { Thread } from '@wovin/core/thread'
import { A } from '@solidjs/router'
import { dateNowIso, EntityID_LENGTH, tsNearlySame } from '@wovin/core/applog'
import { tryJsonParse } from '@wovin/utils/conversion'
import { Logger } from 'besonders-logger'
import { Collapse } from 'solid-collapse'
import { createMemo, createSignal, For, Match, Show, Switch } from 'solid-js'
import { tiptapToPlaintext } from '../data/note3-utils-nodeps'
import { useRawThread } from '../ui/reactive'
import { copyOnClick, devMode, explorerUrl, setDevMode } from '../ui/utils-ui'
import { DynamicColored, HighlightSameOnHover } from './mini-components'

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

const MAX_BEFORE_TOGGLE = -50

export function ApplogView({ thread, alwaysOpen }: {
	thread?: Thread
	alwaysOpen?: boolean
} = {}) {
	DEBUG(`<ApplogView>`, { thread, alwaysOpen })
	if (!thread) thread = useRawThread()

	const [showAll, setShowAll] = createSignal(false)
	const reversed = createMemo(() =>
		thread.applogs
			.slice(showAll() ? undefined : MAX_BEFORE_TOGGLE) // TODO: make it a virtual container - e.g. https://github.com/minht11/solid-virtual-container
			.reverse(),
	)

	return (
		<div w-full overflow-auto text-xs border='1 solid rd-1 gray-500' box-border p-1 color={!alwaysOpen && 'gray-400 hover:text'}>
			{
				/* <For each={applogs().reverse()} fallback={<div>No Applogs</div>}>
				{(item, index) => <pre data-index={index()} m-0 text-xs>{JSON.stringify(item)}</pre>}
			</For> */
			}

			<div
				w-full
				text-center
				truncate
				cursor-pointer
				onClick={() => setDevMode(!devMode())}
			>
				<strong>{thread.size} Applogs</strong>
				&emsp;–&emsp;
				<code>{thread.name}</code>
				<div
					class={'i-ph:caret-down-bold h-5 w-5 float-right ' + `${devMode() ? 'rotate-0' : 'rotate-180'}`}
					duration-300
					transition-property='[transform]'
				/>
			</div>
			<Collapse value={alwaysOpen || devMode()} class='duration-300 transition-property-[height]'>
				<Show when={alwaysOpen || devMode()}>
					<table mt-2 relative right-1 w-full cellpadding='1' style={{ 'border-collapse': 'collapse' }}>
						{/* cellspacing='0' cellpadding='0' */}
						<thead>
							<tr text-left font-mono>
								<th class='pr-0.5'>Time</th>
								<th class='px-0.5'>Agent</th>
								<th class='px-0.5'>Entity</th>
								<th class='px-0.5'>Attribute</th>
								<th class='px-0.5'>Value</th>
								<th class='pl-0.5'>CID,Prev</th>
							</tr>
						</thead>
						<tbody>
							<For
								each={reversed()}
								fallback={(
									<tr>
										<td colspan='5'>
											No Applogs
										</td>
									</tr>
								)}
							>
								{(item, index) => {
									const clumpingClass = createMemo(() =>
										reversed()[index() + 1]?.ts && tsNearlySame(reversed()[index() + 1]?.ts, item.ts) ? '' : 'pb-2',
									)
									let valueToDisplay = item.vl
									const valueParsed = typeof item.vl === 'string' ? tryJsonParse(item.vl) : undefined

									if (valueParsed?.type === 'doc') {
										valueToDisplay = tiptapToPlaintext(valueParsed)
									}
									return (
										<tr
											data-index={index()}
											whitespace-nowrap
											font-mono
											bg='hover:black/40'
											data-cid={item.cid}
										>
											<td text-right class={`pr-0.5 ${clumpingClass()}`} title={item.ts} cursor-pointer use:copyOnClick={item.ts}>
												{
													item.ts
														.replace(dateNowIso().slice(0, 11), '') // remove date if it's today
														.slice(0, -5) // remove ms
												}
											</td>
											<td title='TODO: agent info' class={`px-0.5 ${clumpingClass()}`}>
												<HighlightSameOnHover id={item.ag} style={alwaysOpen && 'opacity: 1.0' /* HACK */}>
													<DynamicColored text={item.ag} />
												</HighlightSameOnHover>
											</td>
											<td max-w-5em truncate title={item.en} overflow-hidden class={`px-0.5 ${clumpingClass()}`}>
												<HighlightSameOnHover id={item.en} style={alwaysOpen && 'opacity: 1.0' /* HACK */}>
													<DynamicColored text={item.en} />
												</HighlightSameOnHover>
											</td>
											<td title={item.cid} class={clumpingClass()}>{item.at}</td>
											<td
												title={JSON.stringify(valueParsed || item.vl, undefined, 4)}
												class={`px-0.5 ${clumpingClass()}`}
												max-w-md
												truncate
											>
												<Switch>
													<Match when={typeof valueToDisplay === 'string' && valueToDisplay.length === EntityID_LENGTH}>
														{/* HACK: heuristic to check for EntityID */}
														<HighlightSameOnHover id={valueToDisplay.toString()} style={alwaysOpen && 'opacity: 1.0' /* HACK */}>
															<DynamicColored text={valueToDisplay.toString()} />
														</HighlightSameOnHover>
													</Match>
													<Match when={true}>
														{typeof valueToDisplay === 'string' && valueToDisplay ? valueToDisplay : JSON.stringify(valueToDisplay)}
													</Match>
												</Switch>
											</td>
											<td class={`pl-0.5 ${clumpingClass()}`}>
												<A class='a-unstyled' target='_blank' href={explorerUrl(item.cid)}>
													<HighlightSameOnHover id={item.cid.slice(-8)} style={alwaysOpen && 'opacity: 1.0' /* HACK */}>
														<DynamicColored text={item.cid.slice(-8)} />
													</HighlightSameOnHover>
												</A>
												,
												<Show when={!!item.pv}>
													<A
														class='a-unstyled'
														target='_blank'
														href={explorerUrl(item.pv)}
														title={item.pv && JSON.stringify(thread.getApplog(item.pv), undefined, 2)}
													>
														<HighlightSameOnHover id={item.pv.slice(-8)} style={alwaysOpen && 'opacity: 1.0' /* HACK */}>
															<DynamicColored text={item.pv.slice(-8)} />
														</HighlightSameOnHover>
													</A>
												</Show>
												<Show when={!item.pv}>
													null
												</Show>
											</td>
										</tr>
									)
								}}
							</For>
						</tbody>
					</table>
					<Show when={showAll() || reversed.length < MAX_BEFORE_TOGGLE}>
						<sl-button
							relative
							right-1
							bottom-1
							mt-1
							onClick={() => setShowAll(!showAll())}
						>
							Show {showAll() ? 'fewer' : 'all'}
						</sl-button>
					</Show>
				</Show>
			</Collapse>
		</div>
	)
}
