import type { SlSelect } from '@shoelace-style/shoelace'
import type { useNavigate } from '@solidjs/router'
import type { IShare, WriteableThread } from '@wovin/core'
import type { Applog } from '@wovin/core/applog'
import type { Accessor, Component } from 'solid-js'
import { entityCount, filterAndMap, lastWriteWins, prepareSnapshotForPush, withTimeout } from '@wovin/core'
import { isoDateStrCompare } from '@wovin/core/applog'
import { computed, toJS } from '@wovin/core/mobx'
import { catchReturn } from '@wovin/utils'
import { Logger } from 'besonders-logger'
import { groupBy, last } from 'lodash-es'
import sortBy from 'lodash-es/sortBy'
import { Collapse } from 'solid-collapse'
import { createEffect, createMemo, createSignal, For, Match, Show, Suspense, Switch, untrack } from 'solid-js'
import { boundInput, getAgentString, useAgent } from '../../data/agent/AgentState'

import { DefaultAgentBanner, StorageMissingBanner } from '../../data/agent/utils-agent'
import { appLogIDB } from '../../data/datalog/local-applog-idb'
import {
	getShareThread,
	makeBlocksSelector,
	makeTagSelector,
	RE_SELECTOR_BLOCKS,
	RE_SELECTOR_TAGS,
	RE_SELECTOR_WITHOUT_HISTORY,
	toggleLastWriteWinsSelector,
} from '../../data/getShareThread'
import { useBlk } from '../../data/VMs/BlockVM'
import { addShare, updateShareEncryption } from '../../ipfs/share-sync'
import { doSync } from '../../ipfs/sync-service'
import { useAllTags, useRawThread, useRoots } from '../../ui/reactive'
import {
	createAsyncButtonHandler,
	createAsyncMemo,
	makeNote3Url,
	promptBlobDownload,
	singleBlockOfShare,
	useLocationNavigate,
} from '../../ui/utils-ui'
import { BackLink } from '../BackLink'
import { CopyableID, DeleteWithConfirm, Iconify, KeyValueDiv, NameValueBadge, Spinner } from '../mini-components'

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

export const SharesSettings: Component<{
	navigate: ReturnType<typeof useNavigate> // HACK: context is broken by w3 keyring provider
	activeSection?: Accessor<string>
	params?: Accessor<string[]>
}> = (
	props,
) => {
	const focussedShare = createMemo(() => props.params()?.[0])
	const agent = useAgent()
	const isAllSetUp = computed(() => agent.hasStorageSetup && agent.isAgentStringSetup)
	untrack(() =>
		DEBUG(`Creating <PublicationsPanel>`, {
			agent,
			hasStorageSetup: agent.hasStorageSetup,
			isAllSetUp: isAllSetUp.get(),
			props,
		}),
	)
	return (
		// <Show when={activeSection().startsWith('publications')}>
		<div w-full flex='~ col' gap-4>
			<DefaultAgentBanner />
			<StorageMissingBanner />
			<Show when={isAllSetUp.get()}>
				<Switch>
					<Match when={!focussedShare()}>
						<AddShareButton />
					</Match>
					<Match when={focussedShare()}>
						<h4 m-0 flex='inline items-center gap-4'>
							<BackLink text='Back to list' href='/settings/shares' />
						</h4>
					</Match>
				</Switch>
				<SharesList {...{ focussedShare }} />
			</Show>
		</div>
		// </Show>
	)
}

export const SharesList: Component<{
	focussedShare?: Accessor<string>
}> = (props) => {
	DEBUG('create <SharesList>')
	const agent = useAgent()
	// const {navigate }=useLocationNavigate()

	const list = createMemo(() => {
		const list = agent.shares.slice() // .slice is also to un-mobx proxy
		list.sort((a, b) => isoDateStrCompare(a.createdAt, b.createdAt, 'desc')) // newest first
		DEBUG(`list:`, { list })
		return list
	})
	const focusedOrList = createMemo(() => {
		let newList = list()
		if (props.focussedShare()) {
			newList = newList.filter(p => p.id === props.focussedShare())
		}
		DEBUG(`focusedOrList: FOCUSSSED???`, props.focussedShare(), { list, newList })
		return newList
	})
	createEffect(() => DEBUG(`focussed:`, props.focussedShare()))
	createEffect(() => DEBUG(`shares:`, toJS(agent.shares)))

	return (
		<div flex='~ col items-stretch' gap-2>
			<For
				each={focusedOrList()}
				fallback={(
					<Switch>
						<Match when={props.focussedShare()}>
							<sl-alert variant='danger' open>
								<div flex='~ items-center gap-4' text-xl>
									<div class='i-ph:warning-bold' />
									<strong>Share not found:</strong>
								</div>
								<pre mb-0>{props.focussedShare()}</pre>
							</sl-alert>
						</Match>
						<Match when={!props.focussedShare()}>
							No shares (yet)
						</Match>
					</Switch>
				)}
			>
				{(share: IShare, _nodeIdx) => {
					const isFocussed = createMemo(() => props.focussedShare() === share.id)
					return <SingleSharePanel share={share} {...{ isFocussed }} />
				}}
			</For>
			<style>
				{`.card-overview::part(base){ height: 100%;}`}
			</style>
		</div>
	)
}
export const AddShareButton: Component<{}> = (props) => {
	const { navigate } = useLocationNavigate()
	const addButtonProps = createAsyncButtonHandler(async () => {
		const share = await addShare()
		navigate(`/settings/shares/${share.id}`)
	})

	return (
		<div>
			<sl-button variant='primary' {...addButtonProps()}>
				<div class='i-ph:plus-bold' slot='prefix' />
				Create share
			</sl-button>
			{
				/* Publish all {/* db.count() * /}applogs {encryptFor() ? `for: ${encryptFor()}` : 'unencrypted'}
			<br /> to: <br />
			<ChoosePubPulldown getPub={share} setPub={setPub} />
			{/* <EditPubPulldown /> * /}
			<br />to IPNS (hosted in your Web3.storage):
			{/* <code dir='rtl' max-w-full overflow-hidden text='3 right'>{currentPub() ? `${currentPub().id}` : 'No w3name set up'}</code> * /}
			<br />

			<div flex='~ justify-end'>
				Push All Applogs
				<sl-button mt-2 variant='primary' onclick={null}>
					{/* loading={uploading()} disabled={!getW3NamePublic()} * /}
					<div class='i-ph:upload-simple-bold' slot='prefix'></div>
					Push
				</sl-button>
			</div> */
			}
		</div>
	)
}
export async function purgeIrrelevantShareLogs(ds: WriteableThread, share: IShare, forcePurge = false, timeSpanMinutes: number = 5) {
	// TODO avoid inconsistencies, notes from call:
	// check if the purged logs are already published elsewhere
	// how to prepare for real-time
	// do we need to change the pv pointer ? is that dangerously mutable?
	// what part of this belongs in wovin?
	// interim applog/tuple that points from newest purged cid (that has a pv pointing to it) to the newest preserved applog in the chain
	// how to prevent eventually purgable applogs from being written in the first place

	const shareThread = getShareThread(ds, share)
	const thresholdMS = timeSpanMinutes * 60000
	type LogsByEntity = Record<string, Array<Partial<Applog>>>

	const entitiesWithContentLogs = groupBy(
		sortBy([...filterAndMap(shareThread, { at: 'block/content' }, ({ en, cid, ts, vl }) => ({ en, cid, ts, vl }))], 'ts')
			.reverse(),
		'en',
	) as unknown as LogsByEntity
	LOG({ entitiesWithContentLogs })
	const logsToPurge = []
	const entityMapPurged: LogsByEntity = {}
	for (const [eachEN, eachLogArray] of Object.entries(entitiesWithContentLogs)) {
		for (const [_eachEN, eachLog] of Object.entries(eachLogArray)) {
			entityMapPurged[eachEN] = entityMapPurged[eachEN] || [eachLog]
			const lastLogForThisEN = last(entityMapPurged[eachEN])
			const lastTS = new Date(lastLogForThisEN.ts).getTime()
			const thisTS = new Date(eachLog.ts).getTime()
			const diffTS = lastTS - thisTS

			const isPurgable = diffTS > 0 && diffTS < thresholdMS
			if (isPurgable) {
				logsToPurge.push(eachLog.cid)
			} else {
				entityMapPurged[eachEN].push(eachLog)
			}
		}
	}
	DEBUG({ entityMapPurged, logsToPurge })
	if (forcePurge || share.purgeBeforePush) {
		await appLogIDB.applogs.bulkDelete(logsToPurge)
		const purgeCount = ds.purge(logsToPurge)
		LOG({ purgeCount, entityMapPurged, logsToPurge })
	}
	// const mapped = entitiesWithContentLogs.reduce(())
}
export const SingleSharePanel: Component<{
	share: IShare
	isFocussed?: Accessor<boolean> | undefined
}> = (
	props,
) => {
	const { navigate } = useLocationNavigate()
	const rawDS = useRawThread()
	// const [uploadState, uploader] = useW3Uploader()
	const agent = useAgent()
	const [isExpanded, setIsExpanded] = createSignal(props.isFocussed?.())
	const [expandedOnce, setExpandedOnce] = createSignal(isExpanded())
	createEffect(() => {
		if (props.isFocussed?.()) {
			setIsExpanded(true)
			setExpandedOnce(true)
		} // if it was in the list, but not focussed - it will not be recreated
	})
	const encryptedFor = createMemo(() => props.share.sharedAgents?.join(',') ?? '')

	async function deleteShare(id) {
		await agent.deleteShare(id)
		if (props.isFocussed?.()) navigate(`/settings/shares`)
	}
	const pushButtonProps = createAsyncButtonHandler(async () => {
		DEBUG(`Pushing '${props.share.name}'`, { share: props.share, rawDS })

		// purgeIrrelevantShareLogs(rawDS, share) - //TODO consider thoroughly
		await doSync({ share: props.share.id })
	})
	async function downloadCar() {
		LOG(`Download as CAR: '${props.share.name}'`, { share: props.share, rawDS })
		const shareData = getShareThread(rawDS, props.share)
		const { cid, blob } = await prepareSnapshotForPush(agent, rawDS, shareData, props.share, null) // TODO: download incremental?
		promptBlobDownload(blob, `${props.share.name ?? props.share.id} - ${new Date().toISOString()}.car`)
		// download `car` as file in javascript
	}
	async function resetPrev() {
		LOG(`Resetting prev to nothing: '${props.share.name}'`, { share: props.share })
		await agent.updateShare(props.share.id, {
			lastCID: null,
			// ? lastPush: null,
		})
	}

	const selectedBlockIDs = createMemo(() => {
		const selectors = props.share.selectors?.filter(s => s.match(RE_SELECTOR_BLOCKS))
		if (!selectors?.length) return []
		if (selectors.length > 1) WARN(`Multi selector not supported yet:`, selectors) // TODO: multi rootBlockIDs
		return selectors[0].split(/[()]/, 3)[1].split(',')
	})
	function onBlockIDsChanged(e: CustomEvent) {
		const newRoots = (e.target as SlSelect).value as string[] // HACK: event doesn't seem to have that info
		DEBUG(`RootIDs changed:`, e, newRoots)
		const prevSelectors = props.share.selectors ?? []
		const prevSelector = prevSelectors.find(s => s.match(RE_SELECTOR_BLOCKS))
		const selectorIdx = prevSelector && prevSelectors.indexOf(prevSelector)
		const newSelector = newRoots.length
			? (prevSelector ? prevSelector.replace(RE_SELECTOR_BLOCKS, makeBlocksSelector(newRoots)) : makeBlocksSelector(newRoots))
			: null
		const newSelectors = [...prevSelectors]
		if (prevSelector) newSelectors.splice(selectorIdx)
		if (newSelector) newSelectors.push(newSelector)
		DEBUG(`[share] updating selectors`, props.share.id, prevSelectors, newSelectors, { prevSelector, newSelector, newRoots })
		agent.updateShare(props.share.id, { selectors: newSelectors })
	}
	const tags = createMemo(() => {
		const selectors = props.share.selectors?.filter(s => s.match(RE_SELECTOR_TAGS))
		if (!selectors?.length) return []
		if (selectors.length > 1) WARN(`Multi selector not supported yet:`, selectors)
		return selectors[0].split(/[()]/, 3)[1].split(',')
	})
	function onTagsChanged(e: CustomEvent) {
		const newTags = (e.target as SlSelect).value as string[] // HACK: event doesn't seem to have that info
		DEBUG(`Tags changed:`, e, newTags)
		const prevSelectors = props.share.selectors ?? []
		const prevSelector = prevSelectors.find(s => !!s.match(RE_SELECTOR_TAGS))
		const selectorIdx = prevSelector && prevSelectors.indexOf(prevSelector)
		const newSelector = newTags.length
			? (prevSelector ? prevSelector.replace(RE_SELECTOR_TAGS, makeTagSelector(newTags)) : makeTagSelector(newTags))
			: null
		const newSelectors = [...prevSelectors]
		if (prevSelector) newSelectors.splice(selectorIdx)
		if (newSelector) newSelectors.push(newSelector)
		DEBUG(`[share] updating selectors`, props.share.id, prevSelectors, newSelectors, { prevSelector, newSelector, newRoots: newTags })
		agent.updateShare(props.share.id, { selectors: newSelectors })
	}

	const isWithoutHistory = createMemo(() => {
		return !!props.share.selectors?.find(s => s.match(RE_SELECTOR_WITHOUT_HISTORY))
	})
	const onToggleWithHistory = (e) => {
		const lastWriteWins = e.target.checked
		const prevSelectors = props.share.selectors ?? []
		let newSelectors: string[]
		if (!prevSelectors.length) {
			newSelectors = lastWriteWins ? ['lastWriteWins'] : []
		} else {
			newSelectors = prevSelectors.map(s => toggleLastWriteWinsSelector(s, lastWriteWins)).filter(s => !!s)
		}
		DEBUG(`[share] Setting new selectors`, props.share.id, newSelectors, { prevSelectors })
		return agent.updateShare(props.share.id, { selectors: newSelectors })
	}
	const onToggleAutopush = e => agent.updateShare(props.share.id, { autopush: e.target.checked })
	const isAutopush = createMemo(() => {
		return props.share.autopush
	})
	const shortDerivationPublicKey = createAsyncMemo(async () => {
		await agent.getPublicDerivationECDH()
		return agent.getPublicDerivationECDHshortSync()
	})
	const allTags = useAllTags()
	const resultThreadOrError = computed(() =>
		catchReturn(() => {
			return withTimeout(700, () => getShareThread(rawDS, props.share))
		}),
	)
	// const pubRoots = computed(() => pubData.get() && withDS(pubData.get(), () => useRoots()))
	const knownAgentMap = agent.getKnownAgents(rawDS)
	const setEncryptionTargets = (evt: CustomEvent) => {
		const { value: selectedAgentIDs } = evt.target as SlSelect
		const shareUpdate: Parameters<typeof updateShareEncryption>[0] = { id: props.share.id }
		if (selectedAgentIDs?.length) {
			shareUpdate.sharedAgents = selectedAgentIDs as string[]
			shareUpdate.encryptedFor = null // TODO fully deprecate
			// shareUpdate.encryptedWith = null
			DEBUG('updating', { share: props.share, shareUpdate })
			updateShareEncryption(shareUpdate)
		} else {
			shareUpdate.sharedAgents = null
			shareUpdate.encryptedFor = null
			// shareUpdate.encryptedWith = null
			updateShareEncryption(shareUpdate)
		}
		LOG('setEncryptionTargets', { evt, selectedAgentIDs, shareUpdate })
	}
	const [loadAllRoots, setLoadAllRoots] = createSignal(false)
	const allRootIDs = createMemo(() => !loadAllRoots() ? selectedBlockIDs() : useRoots())

	const encryptionSelectValue = () => props.share?.sharedAgents ?? ''
	const pushAndPurge = async () => {
		purgeIrrelevantShareLogs(rawDS, props.share, true)
		await doSync({ share: props.share.id })
	}

	let panelRef: HTMLDivElement
	let caretRef: HTMLDivElement
	let buttonRow: HTMLDivElement
	return (
		<div flex='~ col' rounded border='solid 1' border-gray-400>
			<div
				ref={panelRef}
				px-3
				py-2
				flex='~ wrap space-between items-center justify-between'
				gap-2
				bg-white-200
				cursor-pointer
				onClick={(e) => {
					DEBUG(`<SingleSharePanel>.onClick`, e, { panelRef })
					if (e.target !== panelRef && e.target !== caretRef && e.target !== buttonRow) return
					e.stopPropagation()
					setIsExpanded(!isExpanded())
					setExpandedOnce(true)
				}}
			>
				<div mr-2 flex='~ wrap items-center gap-1'>
					<span text-lg font-bold>
						{boundInput('sharesMap', [], { shareID: props.share.id, padding: 'py-1 px-2' })}
					</span>
					<span text-xs class='opacity-60 hover:opacity-100'>
						{props.share.lastPush ? <sl-relative-time date={props.share.lastPush} /> : 'never pushed'}
						{/* <Iconify name={pub.autopush ? 'clock-light' : 'text-strikethrough-bold'} />  */}
						{/* , {pub.autopush ? 'auto' : 'manual'} */}
					</span>
				</div>
				<div ref={buttonRow} flex='~ items-center grow-1 justify-end' gap-2>
					{
						/* <span>
						({pub.encryptedFor ? `for ${pub.encryptedFor}` : 'unencrypted'}, last push:{' '}
					</span> */
					}
					<div flex='~ items-center' gap-2>
						<div flex='~ items-center' gap-2>
							<CopyableID id={props.share.id} label='Copy IPNS ID' />
							<sl-copy-button
								m='l--2'
								value={makeNote3Url({ pub: props.share.id, block: singleBlockOfShare(props.share) })}
								copy-label='Copy Note3 URL'
							>
								<Iconify name='link' size='5' slot='copy-icon' />
							</sl-copy-button>
							<sl-tooltip content='Open preview (new window)'>
								<a
									href={makeNote3Url({ pub: props.share.id, previewPub: true })}
									target='_blank'
									color='white visited:white'
									flex='inline justify-center'
								>
									<Iconify class='ml--1' size='5' name='eye' />
								</a>
							</sl-tooltip>
							<sl-tooltip placement='top'>
								<Iconify class='mx-1' size='5' name={encryptedFor() ? 'lock-key-fill' : 'lock-simple-open-light'} />
								<div slot='content'>
									{encryptedFor() ? `for ${encryptedFor()}` : 'unencrypted'}
								</div>
							</sl-tooltip>
							<DeleteWithConfirm
								handler={() => deleteShare(props.share.id)}
								confirmText={'Sure you want to delete this share?\n(local only, already published data will not change)'}
							/>
							<sl-tooltip
								placement='top'
								content={(
									<span>
										<strong>last push:</strong>
										{' '}
										<Show when={props.share.lastPush}>
											<sl-relative-time date={props.share.lastPush} />
										</Show>
										<Show when={!props.share.lastPush}>
											never
										</Show>
										<br />
										<strong>autopush</strong>
										:
										{props.share.autopush ? 'on' : 'off'}
									</span>
								)}
							>
								<sl-button
									variant={props.share.autopush ? 'success' : 'default'}
									size='small'
									{...pushButtonProps()}
									disabled={false /* HACK: as long as login is broken */ && !agent.hasStorageSetup}
								>
									<Iconify slot='prefix' size='4' name='upload-simple-bold' />
								</sl-button>
							</sl-tooltip>
						</div>
						<div
							ref={caretRef}
							class={'i-ph:caret-down-bold h-5 w-5 cursor-pointer ' + `${isExpanded() ? 'rotate-180' : 'rotate-0'}`}
							duration-300
							transition-property='[transform]'
						/>
					</div>
				</div>
			</div>

			{/* PANEL CONTENT */}
			<Collapse value={isExpanded()} class='duration-300 transition-property-[height]'>
				<Show when={expandedOnce() || isExpanded()} fallback={<div color-green>collapsed content</div>}>
					<Suspense fallback={<Spinner size='3rem' color='purple' />}>
						<div px-3 text-sm flex='~ items-center wrap' gap-1>
							<NameValueBadge name='Created'>
								<sl-relative-time date={props.share.createdAt} />
							</NameValueBadge>
							<NameValueBadge name='Last push'>
								<Show when={props.share.lastPush}>
									<sl-relative-time date={props.share.lastPush} />
								</Show>
								<Show when={!props.share.lastPush}>
									never
								</Show>
								<Show when={props.share.lastCID}>
									⇒
									{' '}
									<CopyableID id={props.share.lastCID} buttonSize='4' />
								</Show>
							</NameValueBadge>
						</div>
						<div flex='~ wrap justify-items-stretch' px-3 p-2 gap-2>
							<sl-card class='card-overview min-h-32 md:min-w-md' flex='grow-1'>
								<div slot='header' flex='~ items-center justify-between'>
									<strong>Push</strong>
									<div text-sm flex='~ items-center' gap-4>
										<sl-button size='small' onClick={downloadCar}>
											<Iconify slot='prefix' name='archive-box' size={4} />
											Download as file
										</sl-button>
										Autopush
										{' '}
										<sl-switch checked={isAutopush()} onsl-change={onToggleAutopush} size='small' mr--1 />
									</div>
								</div>
								<sl-select
									size='small'
									label={`Select agent to encrypt for: (Currently: ${encryptionSelectValue()})`}
									value={encryptionSelectValue()}
									defaultValue={encryptionSelectValue()}
									clearable
									multiple
									onsl-after-hide={setEncryptionTargets}
								>
									<For each={[...knownAgentMap.get().values()]}>
										{({ ag: eachAg, jwkd: eachJwkString }, _logIdx) => {
											const agString = getAgentString(eachAg)
											return (
												<sl-option value={`${eachAg}`} text-xs>
													{`[${eachAg} : ${agString}] : ...${(eachJwkString as string).slice(-8)}`}
												</sl-option>
											)
										}}
									</For>
								</sl-select>
								<div slot='footer'>
									<DeleteWithConfirm
										buttonVariant='secondary'
										buttonIcon='arrow-counter-clockwise-fill'
										handler={() => resetPrev()}
										label='Reset share history'
										confirmText={`Ignore previously published data and start over.\nYou will loose history that is not on this device.`}
										confirmButtonLabel='Forget history'
									/>
								</div>
							</sl-card>
							<sl-card class='card-overview min-h-32 min-w-sm flex-auto'>
								<div slot='header' flex='~ justify-between'>
									<strong>Selectors</strong>
									<div text-sm>
										Without history&ensp;
										<sl-switch checked={isWithoutHistory()} onsl-change={onToggleWithHistory} size='small' mr--1 />
									</div>
								</div>
								<div flex='~ col' gap-4>
									<sl-select
										class='min-w-xs'
										label='Blocks to publish'
										help-text='recursive (will include their kids too)'
										placeholder='Select blocks to include'
										value={selectedBlockIDs()}
										multiple
										clearable
										onsl-input={onBlockIDsChanged}
										onClick={() => setLoadAllRoots(true)}
									>
										<div w-8 h-8 slot='prefix' class='i-ph:dot-duotone scale-115' />
										<For each={allRootIDs()}>
											{(rootID) => {
												const block = useBlk(rootID)
												return <sl-option value={rootID}>{block.contentPlaintext}</sl-option>
											}}
										</For>
									</sl-select>
									<sl-select
										class='min-w-xs'
										label='Tags'
										help-text='include all blocks referencing this tag (and their kids)'
										value={tags()}
										multiple
										clearable
										onsl-input={onTagsChanged}
									>
										<For each={[...allTags.entries()].sort(([, a], [, b]) => b - a)}>
											{([tag, count]) => {
												return (
													<sl-option value={tag} label={tag}>
														{tag}
														{' '}
														<span opacity-60 slot='prefix'>({count})</span>
													</sl-option>
												)
											}}
										</For>
									</sl-select>
									{
										/* <sl-input placeholder='Search for a block to "track"' size='medium' disabled>
										<div w-8 h-8 slot='prefix' class='i-ph:dot-duotone scale-115' />
										<div w-4 h-4 slot='suffix' class='i-ph:magnifying-glass' />
									</sl-input> */
									}
									<Show when={props.share.selectors?.length}>
										Selectors:
										{' '}
										<pre m-0>{JSON.stringify(props.share.selectors, undefined, 4).replaceAll(/\n\s*/g, ' ')}</pre>
									</Show>
								</div>
							</sl-card>
							<sl-card class='card-overview min-h-32 flex-auto md:min-w-20'>
								<Show when={resultThreadOrError.get()} fallback={<div color-red>Publication contains no data</div>}>
									<div slot='header' flex='~ items-center justify-between'>
										<span>Result</span>
										{
											/* <sl-button onclick={pushAndPurge} size='small' variant='primary'>
											<Iconify slot='prefix' size='4' name='upload-simple-bold' />
											Push & Purge
										</sl-button> */
										}
										<Show when={!!props.share.lastCID}>
											<div flex='~ items-center' gap-2>
												(after you pushed):
												<a href={makeNote3Url({ pub: props.share.id, previewPub: true })} target='_blank'>
													<sl-button size='small' variant='primary'>
														<div class='i-ph:eye-bold' slot='prefix' />
														Preview
													</sl-button>
												</a>
											</div>
										</Show>
									</div>
									<Show
										when={resultThreadOrError.get() instanceof Error}
										fallback={<div color-red>Error generating: {resultThreadOrError.get().message}</div>}
									>
										<KeyValueDiv label='Entities' class='text-sm'>
											{entityCount(lastWriteWins(resultThreadOrError.get()))}
										</KeyValueDiv>
										<KeyValueDiv label='Applogs' class='text-sm'>
											{resultThreadOrError.get().size}
										</KeyValueDiv>
										<KeyValueDiv label='Timespan' class='text-sm'>
											<sl-relative-time date={resultThreadOrError.get().firstLog?.ts} />
											➜
											<sl-relative-time date={resultThreadOrError.get().latestLog?.ts} />
										</KeyValueDiv>
										{
											/* <For each={pubRoots.get()}>
										{(rootID) => {
											// const content = useBlockAt(rootID, 'content')
											const block = useBlk(rootID)
											return (
												<div>
													- {block.contentPlaintext} ? (<KidCount block={rootID} /> kids)
												</div>
											)
										}}
									</For> */
										}
									</Show>
								</Show>
							</sl-card>
							<sl-card class='card-overview min-h-32 w-full flex-auto md:min-w-20'>
								<Show when={props.share.pubCounter} fallback={<div color-red>Share is legacy - no derivation info</div>}>
									<div slot='header' flex='~ items-center justify-between'>
										<span>Derivation Info</span>
									</div>
									This share is derived from your local agent's key:
									{' '}
									<br />
									agent:
									{' '}
									{agent.ag}
									{' '}
									[
									{agent.agentString}
									]
									{' '}
									<br />
									ECDH publickey:
									{' '}
									{shortDerivationPublicKey()}
									{' '}
									<br />
									<CopyableID id={agent.did} />
								</Show>
							</sl-card>
						</div>
					</Suspense>
				</Show>
			</Collapse>
		</div>
	)
}
