import {
  TRAIL_DESCRIPTION_MAX,
  TRAIL_NAME_MAX,
  type TrailDetail,
} from '@crumbs/core/schemas'
import {Stack} from 'expo-router'
import {useState} from 'react'

import {PhotoField} from '@/components/composer/photo-field'
import {FormField} from '@/components/forms/form-field'
import {FormSubmit} from '@/components/forms/form-submit'
import * as TextField from '@/components/forms/text-field'
import {CancelButton} from '@/components/ui/cancel-button'
import {Layout} from '@/components/ui/layout'
import {useDiscardGuard} from '@/hooks/use-discard-guard'
import {
  useMediaAction,
  type MediaAction,
} from '@/hooks/use-media-action'
import {useSubmitAction} from '@/hooks/use-submit-action'
import {pickTrailCover} from '@/lib/trail-cover'

// a kept cover is left untouched; set uploads a new photo; remove clears it
export type TrailCoverAction = MediaAction

export type TrailFormFields = {
  name: string
  description: string
  cover: TrailCoverAction
}

export function TrailForm({
  trail,
  onSubmit,
  onCancel,
}: {
  trail: TrailDetail
  onSubmit: (fields: TrailFormFields) => Promise<void>
  onCancel: () => void
}) {
  const [name, setName] = useState(trail.name)
  const [description, setDescription] = useState(
    trail.description ?? '',
  )
  const cover = useMediaAction(trail.coverImageUrl)
  const {
    submitting,
    error: submitError,
    submit,
  } = useSubmitAction(onSubmit)

  const pickCover = async () => {
    const uri = await pickTrailCover()
    if (!uri) return
    cover.set(uri)
  }

  const valid = name.trim().length > 0

  const dirty =
    name !== trail.name ||
    description !== (trail.description ?? '') ||
    cover.action.action !== 'keep'
  useDiscardGuard(dirty && !submitting)

  const handleSubmit = () => {
    if (!valid) return
    void submit({
      name: name.trim(),
      description: description.trim(),
      cover: cover.action,
    })
  }

  return (
    <>
      <Stack.Screen
        options={{
          title: 'Edit trail',
          headerLeft: () => <CancelButton onPress={onCancel} />,
        }}
      />
      <Layout.ModalContent>
        <FormField label="Name">
          <TextField.Input
            label="Name"
            value={name}
            onChangeText={setName}
            placeholder="Name this trail"
            maxLength={TRAIL_NAME_MAX}
          />
        </FormField>

        <FormField label="Cover">
          <PhotoField
            uri={cover.uri}
            label="Trail cover"
            onPick={() => void pickCover()}
            onClear={cover.clear}
          />
        </FormField>

        <FormField label="Description">
          <TextField.Input
            label="Description"
            value={description}
            onChangeText={setDescription}
            placeholder="e.g. Best pastries in town"
            multiline
            maxLength={TRAIL_DESCRIPTION_MAX}
          />
        </FormField>

        <FormSubmit
          label="Save changes"
          submitting={submitting}
          error={submitError}
          disabled={!valid || submitting}
          onPress={handleSubmit}
        />
      </Layout.ModalContent>
    </>
  )
}
