<script lang="ts">
  import {onMount} from "svelte"
  import {writable} from "svelte/store"
  import {isMobile, preventDefault} from "@lib/html"
  import {fly} from "@lib/transition"
  import Paperclip from "@assets/icons/paperclip-2.svg?dataurl"
  import Icon from "@lib/components/Icon.svelte"
  import Button from "@lib/components/Button.svelte"
  import EditorContent from "@app/editor/EditorContent.svelte"
  import {publishComment, canEnforceNip70} from "@app/core/commands"
  import {PROTECTED} from "@app/core/state"
  import {makeEditor} from "@app/editor"
  import {DraftKey} from "@app/util/drafts"
  import {pushToast} from "@app/util/toast"

  type Values = {
    content?: string | object
  }

  const {url, event, onClose, onSubmit} = $props()
  const draftKey = new DraftKey<Values>(`reply:${event.id}`)
  const initialValues = draftKey.get()
  const shouldProtect = canEnforceNip70(url)
  const uploading = writable(false)
  const autofocus = !isMobile

  const selectFiles = () => editor.then(ed => ed.commands.selectFiles())

  const submit = async () => {
    if ($uploading) return

    const ed = await editor
    const content = ed.getText({blockSeparator: "\n"}).trim()
    const tags = ed.storage.nostr.getEditorTags()

    if (await shouldProtect) {
      tags.push(PROTECTED)
    }

    if (!content) {
      return pushToast({
        theme: "error",
        message: "Please provide a message for your reply.",
      })
    }

    draftKey.clear()
    onSubmit(publishComment({event, content, tags, relays: [url]}))
  }

  let form: HTMLElement
  let spacer: HTMLElement
  let content = $state(initialValues?.content ?? "")

  const onChange = (json: object) => {
    content = json
  }

  const editor = makeEditor({url, submit, uploading, content, onChange})

  $effect(() => {
    draftKey.set({content})
  })

  onMount(() => {
    setTimeout(() => {
      spacer.scrollIntoView({block: "end", behavior: "smooth"})
    })

    const observer = new ResizeObserver(() => {
      spacer!.style.minHeight = `${form!.offsetHeight}px`
    })

    observer.observe(form!)

    return () => {
      observer.unobserve(form!)
    }
  })
</script>

<div bind:this={spacer}></div>
<form
  in:fly
  bind:this={form}
  onsubmit={preventDefault(submit)}
  class="left-content bottom-sai right-sai ml-2 pl-2 fixed z-feature">
  <div class="card2 mx-2 my-2 bg-alt shadow-md">
    <div class="relative">
      <div class="note-editor grow overflow-hidden">
        <EditorContent {autofocus} {editor} />
      </div>
      <Button
        data-tip="Add an image"
        class="tooltip tooltip-left absolute bottom-1 right-2"
        onclick={selectFiles}>
        {#if $uploading}
          <span class="loading loading-spinner loading-xs"></span>
        {:else}
          <Icon icon={Paperclip} size={3} />
        {/if}
      </Button>
    </div>
    <div class="flex justify-between pt-3">
      <Button class="btn btn-link" onclick={onClose}>Cancel</Button>
      <Button type="submit" class="btn btn-primary">Post Reply</Button>
    </div>
  </div>
</form>
