import React, {useEffect, useMemo, useRef, useState} from 'react'
import {Button, Card, Flex, Stack, Text, TextInput} from '@sanity/ui'
import {set, unset, StringInputProps, useClient, useFormValue} from 'sanity'

type WorkDoc = {
  _id: string
  title?: string
}

function computeTitle(workTitle: string | undefined, movement: string | undefined) {
  const wt = (workTitle || '').trim()
  const mv = (movement || '').trim()

  if (wt && mv) return `${wt}: ${mv}`
  if (wt) return wt
  if (mv) return mv
  return ''
}

export function TrackDisplayTitleInput(props: StringInputProps) {
  const {value, onChange, readOnly, elementProps} = props

  const workRef = useFormValue(['work', '_ref']) as string | undefined
  const movement = useFormValue(['movement']) as string | undefined

  const client = useClient({apiVersion: '2025-01-01'})
  const [workTitle, setWorkTitle] = useState<string>('')

  useEffect(() => {
    let cancelled = false

    async function run() {
      if (!workRef) {
        setWorkTitle('')
        return
      }

      const doc = await client.fetch<WorkDoc | null>(`*[_type == "work" && _id == $id][0]{title}`, {
        id: workRef,
      })

      if (!cancelled) setWorkTitle((doc?.title || '').trim())
    }

    run()
    return () => {
      cancelled = true
    }
  }, [client, workRef])

  const computed = useMemo(() => computeTitle(workTitle, movement), [workTitle, movement])

  const didAutofill = useRef(false)
  useEffect(() => {
    if (didAutofill.current) return
    if (!workRef) return
    if (value && String(value).trim()) return
    if (!computed) return
    if (readOnly) return

    didAutofill.current = true
    onChange(set(computed))
  }, [workRef, value, computed, readOnly, onChange])

  const hasStored = Boolean(value && String(value).trim())
  const inWorkMode = Boolean(workRef)

  if (inWorkMode) {
    return (
      <Card padding={3} radius={2} border>
        <Stack space={3}>
          <Flex direction="column" gap={2}>
            <Text size={1} weight="semibold">
              Display title (stored)
            </Text>
            <Text size={0} muted>
              Generated once from Work/Movement and saved. It will not change automatically if the
              Work changes.
            </Text>
          </Flex>

          <TextInput
            {...elementProps}
            value={(value as string) || ''}
            readOnly={true}
            placeholder={computed || 'Select a Work to generate a title'}
          />

          <Flex gap={2} wrap="wrap">
            <Button
              text={hasStored ? 'Overwrite from Work/Movement' : 'Generate from Work/Movement'}
              mode="default"
              disabled={readOnly || !computed}
              onClick={() => onChange(set(computed))}
            />
            <Button
              text="Clear"
              mode="ghost"
              disabled={readOnly || !hasStored}
              onClick={() => onChange(unset())}
            />
          </Flex>

          {!computed && (
            <Text size={0} muted>
              No computable title yet. Select a Work (and optionally add Movement).
            </Text>
          )}
        </Stack>
      </Card>
    )
  }

  return (
    <TextInput
      {...elementProps}
      value={(value as string) || ''}
      readOnly={readOnly}
      onChange={(e) => {
        const next = e.currentTarget.value
        onChange(next && next.trim() ? set(next) : unset())
      }}
    />
  )
}
