'use client'

import { useMemo, useRef, useState, type FormEvent, type KeyboardEvent } from 'react'
import { useRouter } from 'next/navigation'
import {
  FieldGroup,
  FieldLabel,
  LabelWithTooltip,
  PrimaryButton,
  SelectField,
  TextareaField,
  TextField,
} from '@/app/FormFields'
import type { KnowledgeEntryKind } from '@/db/schema'
import { isOnlyKnowledgeMarkdownSample, KNOWLEDGE_MARKDOWN_SAMPLE } from '@/lib/knowledge-markdown-sample'
import { useI18n } from '@/lib/i18n/client'
import { renderMarkdownPreview } from './MarkdownPreview'

type KnowledgeFormProps = {
  entry?: {
    id: string
    title: string
    slug: string
    kind: KnowledgeEntryKind
    tags: string[]
    bodyMarkdown: string
    /** When true, saves update the translation record rather than the canonical entry. */
    isTranslated?: boolean
    /** Required when isTranslated is true — the language to save the translation for. */
    translationLanguage?: string
  }
}

const KINDS: KnowledgeEntryKind[] = ['index', 'log', 'entity', 'concept', 'procedure']

export default function KnowledgeForm({ entry }: KnowledgeFormProps) {
  const { t } = useI18n()
  const router = useRouter()
  const [title, setTitle] = useState(entry?.title ?? '')
  const [slug, setSlug] = useState(entry?.slug ?? '')
  const [kind, setKind] = useState<KnowledgeEntryKind>(entry?.kind ?? 'concept')
  const [tags, setTags] = useState<string[]>(entry?.tags ?? [])
  const [tagInput, setTagInput] = useState('')
  const [bodyMarkdown, setBodyMarkdown] = useState(entry?.bodyMarkdown ?? KNOWLEDGE_MARKDOWN_SAMPLE)
  const [error, setError] = useState<string | null>(null)
  const [saving, setSaving] = useState(false)
  const tagInputRef = useRef<HTMLInputElement>(null)

  const preview = useMemo(() => {
    const trimmed = bodyMarkdown.trim()
    return trimmed ? renderMarkdownPreview(trimmed) : null
  }, [bodyMarkdown])

  async function submit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault()
    setError(null)

    if (!entry && isOnlyKnowledgeMarkdownSample(bodyMarkdown)) {
      setError(t('knowledge.form.sampleError'))
      return
    }

    setSaving(true)

    const isTranslationEdit = entry?.isTranslated && entry.translationLanguage
    const url = isTranslationEdit
      ? `/api/knowledge/${entry!.id}/translate`
      : entry
        ? `/api/knowledge/${entry.id}`
        : '/api/knowledge'
    const method = isTranslationEdit ? 'POST' : entry ? 'PUT' : 'POST'
    const body = isTranslationEdit
      ? JSON.stringify({ language: entry!.translationLanguage, title, bodyMarkdown })
      : JSON.stringify({ title, slug, kind, tags, bodyMarkdown })

    const response = await fetch(url, {
      method,
      headers: { 'content-type': 'application/json' },
      body,
    })

    const payload = await response.json().catch(() => null) as
      | { entry?: { id: string }; error?: string }
      | null

    setSaving(false)
    if (!response.ok) {
      setError((payload as { error?: string } | null)?.error ?? t('knowledge.form.saveError'))
      return
    }

    if (isTranslationEdit) {
      router.refresh()
      return
    }

    if (!payload?.entry?.id) {
      setError(t('knowledge.form.saveError'))
      return
    }

    router.push(`/knowledge?entry=${payload.entry.id}`)
    router.refresh()
  }

  function addTag() {
    const value = tagInput.toLowerCase().trim().replace(/\s+/g, '-')
    if (!value || tags.includes(value) || tags.length >= 10) {
      setTagInput('')
      return
    }
    setTags((current) => [...current, value])
    setTagInput('')
  }

  function removeTag(tag: string) {
    setTags((current) => current.filter((item) => item !== tag))
  }

  function handleTagKeyDown(event: KeyboardEvent<HTMLInputElement>) {
    if (event.key === 'Enter' || event.key === ',') {
      event.preventDefault()
      addTag()
    } else if (event.key === 'Backspace' && tagInput === '' && tags.length > 0) {
      removeTag(tags[tags.length - 1])
    }
  }

  const isTranslationEdit = entry?.isTranslated && entry.translationLanguage

  return (
    <form onSubmit={submit} className="grid gap-5 lg:grid-cols-[minmax(0,11fr)_minmax(18rem,5fr)]">
      <div className="space-y-4 rounded-lg border border-zinc-200 bg-white p-5 dark:border-zinc-800 dark:bg-zinc-900">
        {isTranslationEdit ? (
          <p className="rounded-md bg-blue-50 px-3 py-2 text-xs text-blue-800 dark:bg-blue-400/10 dark:text-blue-300">
            {t('knowledge.translation.canonicalNote')}
          </p>
        ) : null}
        <FieldGroup>
          <FieldLabel htmlFor="kb-title">{t('knowledge.form.fieldTitle')}</FieldLabel>
          <TextField
            id="kb-title"
            value={title}
            onChange={(event) => setTitle(event.target.value)}
            placeholder={t('knowledge.form.titlePlaceholder')}
            required
          />
        </FieldGroup>

        <div className="grid gap-4 md:grid-cols-[1fr_180px]">
          <FieldGroup>
            <LabelWithTooltip
              htmlFor="kb-slug"
              tooltipId="kb-slug-help"
              tooltipText={t('knowledge.form.slugTooltip')}
            >
              {t('knowledge.form.slug')}
            </LabelWithTooltip>
            <TextField
              id="kb-slug"
              value={slug}
              onChange={(event) => setSlug(event.target.value)}
              placeholder={t('knowledge.form.slugPlaceholder')}
              aria-describedby="kb-slug-help"
            />
          </FieldGroup>
          <FieldGroup>
            <LabelWithTooltip
              htmlFor="kb-kind"
              tooltipId="kb-kind-help"
              tooltipText={t('knowledge.form.typeTooltip')}
            >
              {t('knowledge.form.type')}
            </LabelWithTooltip>
            <SelectField
              id="kb-kind"
              value={kind}
              onChange={(event) => setKind(event.target.value as KnowledgeEntryKind)}
              aria-describedby="kb-kind-help"
            >
              {KINDS.map((item) => (
                <option key={item} value={item}>
                  {item}
                </option>
              ))}
            </SelectField>
          </FieldGroup>
        </div>

        <FieldGroup>
          <LabelWithTooltip
            htmlFor="kb-tags"
            tooltipId="kb-tags-help"
            tooltipText={t('knowledge.form.tagsTooltip')}
          >
            {t('knowledge.form.tags')}
          </LabelWithTooltip>
          <div
            className="flex min-h-11 cursor-text flex-wrap items-center gap-2 rounded-xl border border-zinc-300 bg-white px-3 py-2 shadow-sm transition focus-within:border-(--brand-green) focus-within:ring-4 focus-within:ring-[color-mix(in_srgb,var(--brand-green)_16%,transparent)] dark:border-zinc-700 dark:bg-zinc-950"
            onClick={() => tagInputRef.current?.focus()}
          >
            {tags.map((tag) => (
              <span
                key={tag}
                className="inline-flex items-center gap-1 rounded border border-sky-300 bg-sky-50 px-2 py-0.5 text-xs font-medium text-sky-700 dark:border-sky-700 dark:bg-sky-900/20 dark:text-sky-300"
              >
                {tag}
                <button
                  type="button"
                  onClick={(event) => {
                    event.stopPropagation()
                    removeTag(tag)
                  }}
                  className="leading-none text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-100"
                  aria-label={`Remove tag ${tag}`}
                >
                  ×
                </button>
              </span>
            ))}
            <input
              ref={tagInputRef}
              id="kb-tags"
              value={tagInput}
              onChange={(event) => setTagInput(event.target.value)}
              onKeyDown={handleTagKeyDown}
              onBlur={addTag}
              placeholder={tags.length === 0 ? t('knowledge.form.tagsPlaceholder') : ''}
              disabled={tags.length >= 10}
              className="min-w-30 flex-1 bg-transparent text-sm text-zinc-950 outline-none placeholder:text-zinc-500 dark:text-zinc-100 dark:placeholder:text-zinc-500"
              aria-describedby="kb-tags-help"
            />
          </div>
          <p className="text-xs text-zinc-500 dark:text-zinc-400">{t('knowledge.form.tagsHint')}</p>
        </FieldGroup>

        <FieldGroup>
          <LabelWithTooltip
            htmlFor="kb-markdown"
            tooltipId="kb-markdown-help"
            tooltipText={t('knowledge.form.markdownTooltip')}
          >
            {t('knowledge.form.markdown')}
          </LabelWithTooltip>
          <TextareaField
            id="kb-markdown"
            value={bodyMarkdown}
            onChange={(event) => setBodyMarkdown(event.target.value)}
            className="min-h-105 font-mono text-sm"
            required
            aria-describedby="kb-markdown-help"
          />
        </FieldGroup>

        {error ? <p className="text-sm text-red-700 dark:text-red-300">{error}</p> : null}

        <PrimaryButton
          type="submit"
          loading={saving}
        >
          {saving
            ? (isTranslationEdit ? t('knowledge.translation.savingTranslation') : t('knowledge.form.saving'))
            : isTranslationEdit
              ? t('knowledge.translation.saveTranslation')
              : entry
                ? t('knowledge.form.update')
                : t('knowledge.form.create')
          }
        </PrimaryButton>
      </div>

      <div>
        <h2 className="mb-3 text-sm font-semibold text-zinc-950 dark:text-white">{t('knowledge.form.preview')}</h2>
        <aside className="rounded-lg border border-zinc-200 bg-white p-5 dark:border-zinc-800 dark:bg-zinc-900">
          <div className="space-y-3">
            {preview ?? (
              <p className="text-sm leading-6 text-zinc-500 dark:text-zinc-400">
                {t('knowledge.form.previewEmpty')}
              </p>
            )}
          </div>
        </aside>
      </div>
    </form>
  )
}
