import type { Component } from 'solid-js'
import type { DivProps } from '../../ui/utils-ui'
import { filterAndMap, lastWriteWins } from '@wovin/core/query'
import { Logger } from 'besonders-logger'
import { createEffect, createMemo, createSignal, Show, splitProps, untrack } from 'solid-js'
import { getMnemonicFromIDB, initializeCryptoKeypairs } from '../../data/agent/AgentCrypto'
import { boundInput, useAgent } from '../../data/agent/AgentState'
import { getApplogDB } from '../../data/ApplogDB'
import { copyToClipboard } from '../../data/block-ui-helpers-paste'
import { Iconify } from '../mini-components'

const { WARN, LOG, DEBUG, VERBOSE, ERROR } = Logger.setup(Logger.DEBUG) // eslint-disable-line unused-imports/no-unused-vars
const persist = ['username', 'devicename', 'agentcode'] // will sync to localStorage

const buttonStyle = {
	// '--sl-spacing-small': '6px',
}
export const AgentEditor: Component<DivProps & { initialSetup?: boolean, onSave?: () => void }> = (allProps) => {
	const [props, restProps] = splitProps(allProps, ['initialSetup', 'onSave'])
	const agent = useAgent()
	const originalAg = agent.expectedAgentHash
	const [dirty, setDirty] = createSignal(false)
	const dirtyOrInitial = createMemo(() => props.initialSetup || dirty())
	createEffect(() => {
		DEBUG(`Updating dirty flag from`, untrack(() => dirty()), 'to', !agent.isAgentStringMatching.get(), {
			dbLogs: filterAndMap(lastWriteWins(getApplogDB()), { en: agent.ag, at: 'agent/appAgent' }, 'vl'),
		})
		setDirty(!agent.isAgentStringMatching.get())
	})
	const onChange = (_newVal) => {
		DEBUG(`Changed, setting dirty`, { before: dirty() })
		setDirty(true)
	}

	const onSave = async () => {
		// agent.ensureAgentAtoms() // recycle the old mnemonic and write the new agent situation to idb and atoms
		const { ag, expectedAgentHash } = agent
		DEBUG({ ag, expectedAgentHash, originalAg })
		const existingMnemonicToRecycle = await getMnemonicFromIDB(agent, originalAg)
		if (!existingMnemonicToRecycle) throw ERROR('saving a new agent string requires a mnemonic', { ag, expectedAgentHash, originalAg })
		const cleanedMnemString = existingMnemonicToRecycle.replaceAll(' ', ',').replaceAll(',,,', ',').replaceAll(',,', ',')
		const cleanedMnemArray = cleanedMnemString.split(',')
		DEBUG({ cleanedMnemArray })
		const expectedAgentHashBeforeInitialize = expectedAgentHash
		initializeCryptoKeypairs(agent, cleanedMnemArray, true) // recycle the previous mnemonic and skip the warning
		props.onSave?.()
		if (props.initialSetup) {
			WARN({ expectedAgentHashBeforeInitialize, expectedAgentHash }, '//TODO consider cleaning up IDB if this was an initial setup save')
		}
		setDirty(false)
	}
	const saveButtonLabel = () => props.initialSetup && !dirty() ? 'Continue as \'demouser\'' : 'Save'
	return (
		<div w-full flex='~ wrap items-center gap-4 gap-y-2' box-border py-1 {...restProps}>
			<div overflow-auto text='xs md:base lg:lg'>
				{boundInput('username', persist, {}, onChange /* , !!props.initialSetup */)}
				.
				<span title={`The end of your DID:\n${agent.did}`} cursor-help>{agent.shortDID}</span>
				@
				{
					agent.app //
				}
				.
				{
					boundInput('agentcode', persist, {}, onChange) //
				}
				.
				{
					boundInput('devicename', persist, {}, onChange) //
				}
			</div>
			<div flex='~ items-center wrap' gap-2>
				{/* ? might not be needed anymore */}
				<Show when={dirtyOrInitial()}>
					<sl-button
						style={buttonStyle}
						size='small'
						class='mx-4'
						variant={dirtyOrInitial() ? 'success' : 'primary'}
						// outline={dirty()}
						onClick={onSave}
					>
						<Iconify
							size={4}
							name={!dirtyOrInitial() ? 'checks-bold' : 'floppy-disk'}
							slot='prefix'
						/>
						{saveButtonLabel()}
					</sl-button>
				</Show>
				<Show when={!dirtyOrInitial()}>
					{
						/* <sl-copy-button
					class='copy-button-compact'
					value={agent.agentString}
					copy-label='Copy agent string'
				>
					<Iconify name='copy-light' size={5} slot='copy-icon' />
				</sl-copy-button> */
					}
					<sl-button
						style={buttonStyle}
						size='small'
						title='Copy agent string'
						onClick={() => {
							copyToClipboard(agent.agentString)
						}}
					>
						<Iconify name='copy-light' size={4} slot='prefix' />
						Copy
					</sl-button>
					<sl-button
						style={buttonStyle}
						size='small'
						title={agent.did}
						onClick={() => {
							copyToClipboard(agent.did)
						}}
					>
						<Iconify name='copy-light' size={4} slot='prefix' />
						Copy DID
					</sl-button>
				</Show>
			</div>
		</div>
	)
}
