<script lang="ts">
	import { Code, Copy, MoveLeft, MoveRight, Paintbrush2 } from 'lucide-svelte'
	import { createEventDispatcher } from 'svelte'
	import { slide } from 'svelte/transition'
	import { addWhitespaceBeforeCapitals, copyToClipboard, sendUserToast } from '../../../../utils'
	import { Button, ClearableInput } from '../../../common'
	import type { ComponentCssProperty } from '../../types'
	import { ccomponents, type TypedComponent } from '../component'
	import QuickStyleMenu from './QuickStyleMenu.svelte'
	import type { PropertyGroup } from './quickStyleProperties'
	import Tooltip from '$lib/components/Tooltip.svelte'
	import Badge from '$lib/components/common/badge/Badge.svelte'
	import Toggle from '$lib/components/Toggle.svelte'
	import CssEval from './CssEval.svelte'
	import parse from 'style-to-object'
	import SimpleEditor from '$lib/components/SimpleEditor.svelte'
	import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte'
	import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte'
	import Popover from '$lib/components/Popover.svelte'
	import { tailwindClasses } from './tailwindUtils'

	export let name: string
	export let value: ComponentCssProperty = {}
	export let forceStyle: boolean = false
	export let forceClass: boolean = false
	export let quickStyleProperties: PropertyGroup[] | undefined = undefined
	export let componentType: TypedComponent['type'] | undefined = undefined
	export let tooltip: string | undefined = undefined
	export let shouldDisplayLeft: boolean = false
	export let shouldDisplayRight: boolean = false
	export let overriden: boolean = false
	export let overridding: boolean = false
	export let wmClass: string | undefined = undefined

	const dispatch = createEventDispatcher()
	let isQuickMenuOpen = false

	$: dispatch('change', value)

	function toggleQuickMenu() {
		try {
			if (!value.style) {
				value.style = ''
			}
			parse(value.style)

			isQuickMenuOpen = !isQuickMenuOpen
		} catch {
			sendUserToast('Invalid CSS: Rich editor cannot be toggled', true)
		}
	}

	let richEditorOpen = false

	let dynamicClass: boolean = value?.evalClass !== undefined
	let render = 0
</script>

{#key render}
	<div class="flex justify-between items-center p-2 text-xs leading-6 font-bold w-full">
		<div class="capitalize">
			{addWhitespaceBeforeCapitals(name)}
		</div>
		<div class="flex flex-row items-center gap-1">
			{#if shouldDisplayLeft}
				<Popover placement="bottom" notClickable disappearTimeout={0}>
					<Button
						color="light"
						size="xs2"
						iconOnly
						startIcon={{ icon: MoveLeft }}
						on:click={() => dispatch('left')}
					/>
					<svelte:fragment slot="text">{'Copy for this component'}</svelte:fragment>
				</Popover>
			{/if}
			{#if shouldDisplayRight}
				<Popover placement="bottom" notClickable disappearTimeout={0}>
					<Button
						color="light"
						size="xs2"
						iconOnly
						startIcon={{ icon: MoveRight }}
						on:click={() => dispatch('right')}
					/>
					<svelte:fragment slot="text">
						Copy for every {componentType ? ccomponents[componentType].name : 'component'}
					</svelte:fragment>
				</Popover>
			{/if}
			<Popover placement="bottom" notClickable disappearTimeout={0}>
				<Button
					color="light"
					size="xs2"
					iconOnly
					startIcon={{ icon: Copy }}
					on:click={() => copyToClipboard(wmClass)}
				/>
				<svelte:fragment slot="text">
					Copy {wmClass}
				</svelte:fragment>
			</Popover>
		</div>
	</div>

	{#if value}
		<div class="p-2 flex flex-col gap-2">
			{#if tooltip}
				<div class="text-tertiary text-2xs py-2">{tooltip}</div>
			{/if}

			{#if value.style !== undefined || forceStyle}
				<div class="pb-2">
					<!-- svelte-ignore a11y-label-has-associated-control -->
					<div class="block w-full">
						<div class="flex flex-row justify-between items-center w-full h-8 mb-1">
							<div class="text-xs font-medium text-tertiary"> Plain CSS </div>

							<div class="flex flex-row gap-1">
								{#if overriden}
									<Badge color="red" small>Overriden by local</Badge>
								{:else if overridding}
									<Badge color="blue" small>Overriding global</Badge>
								{/if}
								{#if quickStyleProperties?.length}
									<ToggleButtonGroup
										bind:selected={richEditorOpen}
										on:selected={() => {
											if (richEditorOpen !== isQuickMenuOpen) {
												toggleQuickMenu()
												richEditorOpen = isQuickMenuOpen
											}
										}}
									>
										<ToggleButton
											small
											light
											value={false}
											icon={Code}
											tooltip="Edit the CSS directly"
										/>
										<ToggleButton
											small
											light
											value={true}
											icon={Paintbrush2}
											tooltip="Open the rich editor to style the component with a visual interface"
										/>
									</ToggleButtonGroup>
								{/if}
							</div>
						</div>

						<ClearableInput
							bind:value={value.style}
							type="textarea"
							disabled={isQuickMenuOpen}
							wrapperClass="h-full min-h-[72px]"
							inputClass="h-full !text-xs !rounded-none !p-2 !shadow-none !border-gray-200 dark:!border-gray-600 "
						/>
					</div>
					{#if quickStyleProperties?.length && isQuickMenuOpen}
						<div class="text-xs mb-1 font-medium">Rich editor</div>
						<div transition:slide|local={{ duration: 200 }} class="w-full">
							<QuickStyleMenu
								bind:value={value.style}
								properties={quickStyleProperties}
								{componentType}
								componentProperty={name}
							/>
						</div>
					{/if}
					{#if componentType && ccomponents?.[componentType]?.quickstyle?.[name]?.quickCss}
						<div class="flex flex-row gap-1 items-center mt-1 flex-wrap">
							{#each ccomponents?.[componentType]?.quickstyle?.[name].quickCss ?? [] as v}
								<Badge
									small
									baseClass="cursor-pointer"
									on:click={() => {
										value.style = value.style === '' ? `${v};` : `${value.style} ${v};`
									}}
								>
									{v}
								</Badge>
							{/each}
						</div>
					{/if}
				</div>
			{/if}

			{#if value.class !== undefined || forceClass}
				<!-- svelte-ignore a11y-label-has-associated-control -->
				<label class="block">
					<div class="text-xs font-medium text-tertiary mb-1">
						Tailwind classes
						<Tooltip light documentationLink="https://tailwindcss.com/">
							Use any tailwind classes to style your component
						</Tooltip>
					</div>
					<div class="relative">
						<SimpleEditor
							class="h-24 border !rounded-none"
							lang="tailwindcss"
							{tailwindClasses}
							bind:code={value.class}
							fixedOverflowWidgets={true}
							small
							automaticLayout
						/>
					</div>
					{#if componentType && ccomponents?.[componentType]?.quickstyle?.[name]?.quickTailwindClasses}
						<div class="flex flex-row gap-1 items-center mt-1 flex-wrap">
							{#each ccomponents?.[componentType]?.quickstyle?.[name]?.quickTailwindClasses ?? [] as cls}
								<Badge
									baseClass="cursor-pointer"
									small
									on:click={() => {
										value.class = value.class === '' ? cls : `${value.class} ${cls}`
										render++
									}}
								>
									{cls}
								</Badge>
							{/each}
						</div>
					{/if}
				</label>
			{/if}
			<div class="flex flex-row justify-between items-center">
				<div class="text-xs flex flex-row items-center justify-center">
					Use dynamic class
					<Tooltip light>
						Eval an expression that return a list of class as string to dynamically add classes to
						the component. The styling can then be dynamic using the global CSS Editor.
					</Tooltip>
				</div>
				<Toggle
					size="xs"
					bind:checked={dynamicClass}
					on:change={(e) => {
						if (e.detail && !value.evalClass) {
							value.evalClass = {
								type: 'evalv2',
								expr: '',
								connections: [],
								fieldType: 'text'
							}
						} else {
							value.evalClass = undefined
						}
					}}
				/>
			</div>
			{#if value?.evalClass && dynamicClass}
				<CssEval key={name} bind:evalClass={value.evalClass} />
			{/if}
		</div>
	{/if}
{/key}
