'use client'

import { useEffect, useState } from 'react'
import {
  FormActions,
  FormPanel,
  PrimaryButton,
} from '@/app/FormFields'
import type { SupportedLanguage } from '@/lib/user-language'
import {
  getTodayDateInputValue,
  LAST_PROJECT_KEY,
  SUCCESS_CRITERIA_MAX,
} from './SubmitForm.helpers'
import type { IntakeConfig, Project, SubmittedTicket, SubmitFormLabels } from './SubmitForm.types'
import PostSubmissionView from './PostSubmissionView'
import SubmitIssueFields from './SubmitIssueFields'

function getStoredProject(projects: Project[]): Project | null {
  if (typeof window === 'undefined') return null

  try {
    const last = window.localStorage.getItem(LAST_PROJECT_KEY)
    if (!last) return null

    const parsed = JSON.parse(last) as Project
    return projects.find((p) => p.id === parsed.id) ?? null
  } catch {
    return null
  }
}

export default function SubmitForm({
  promptText,
  maxChars,
  intakeConfig,
  initialProjects,
  waitingBody,
  needsInfoBody,
  completeBody,
  language,
  labels,
}: {
  promptText: string
  maxChars: number
  intakeConfig: IntakeConfig
  initialProjects: Project[]
  waitingBody: string
  needsInfoBody: string
  completeBody: string
  language: SupportedLanguage
  labels: SubmitFormLabels
}) {
  const projects = initialProjects
  const [projectId, setProjectId] = useState('')

  // Restore last-used project after hydration — must not run on server to avoid mismatch.
  // The setState-in-effect lint rule is suppressed: this is the correct React pattern for
  // initializing state from a browser-only source (localStorage) after SSR.
  useEffect(() => {
    const stored = getStoredProject(projects)
    // eslint-disable-next-line react-hooks/set-state-in-effect
    if (stored) setProjectId(stored.id)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])
  const [today] = useState(() => getTodayDateInputValue())

  const [department, setDepartment] = useState('')
  const [dateOfOccurrence, setDateOfOccurrence] = useState(today)
  const [issueCategory, setIssueCategory] = useState('')
  const [affectedSystem, setAffectedSystem] = useState('')
  const [userPriority, setUserPriority] = useState('')
  const [description, setDescription] = useState('')
  const [successCriteria, setSuccessCriteria] = useState('')
  const [actionRequested, setActionRequested] = useState('')

  const [submitted, setSubmitted] = useState(false)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [submittedTicket, setSubmittedTicket] = useState<SubmittedTicket | null>(null)

  const dateInFuture = Boolean(dateOfOccurrence && dateOfOccurrence > today)
  const descRemaining = maxChars - description.length
  const descOverLimit = descRemaining < 0
  const successRemaining = SUCCESS_CRITERIA_MAX - successCriteria.length
  const successOverLimit = successRemaining < 0

  const allFilled =
    projectId &&
    department &&
    dateOfOccurrence &&
    issueCategory &&
    affectedSystem &&
    userPriority &&
    description.trim() &&
    successCriteria.trim() &&
    actionRequested &&
    !dateInFuture &&
    !descOverLimit &&
    !successOverLimit

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    if (!allFilled) {
      setSubmitted(true)
      const fieldOrder: Array<{ id: string; invalid: boolean }> = [
        { id: 'project-id', invalid: !projectId },
        { id: 'department', invalid: !department },
        { id: 'date-of-occurrence', invalid: !dateOfOccurrence || dateInFuture },
        { id: 'issue-category', invalid: !issueCategory },
        { id: 'affected-system', invalid: !affectedSystem },
        { id: 'user-priority', invalid: !userPriority },
        { id: 'action-requested', invalid: !actionRequested },
        { id: 'problem-description', invalid: !description.trim() },
        { id: 'success-criteria', invalid: !successCriteria.trim() },
      ]
      const first = fieldOrder.find((f) => f.invalid)
      if (first) document.getElementById(first.id)?.focus()
      return
    }
    setLoading(true)
    setError(null)

    const res = await fetch('/api/tickets', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        submissionText: description,
        projectId,
        department,
        dateOfOccurrence,
        issueCategory,
        affectedSystem,
        userPriority: userPriority.toLowerCase(),
        successCriteria,
        actionRequested,
      }),
    })

    if (!res.ok) {
      const data = await res.json().catch(() => ({}))
      setError((data as { error?: string }).error ?? labels.error)
      setLoading(false)
      return
    }

    const { ticketId, referenceNumber } = await res.json()
    try {
      const selected = projects.find((p) => p.id === projectId)
      if (selected) localStorage.setItem(LAST_PROJECT_KEY, JSON.stringify(selected))
    } catch {}
    setSubmittedTicket({ id: ticketId, referenceNumber })
    setLoading(false)
  }

  if (submittedTicket) {
    return (
      <PostSubmissionView
        ticket={submittedTicket}
        waitingBody={waitingBody}
        needsInfoBody={needsInfoBody}
        completeBody={completeBody}
        labels={labels}
      />
    )
  }

  return (
    <FormPanel onSubmit={handleSubmit}>
      <SubmitIssueFields
        labels={labels}
        language={language}
        intakeConfig={intakeConfig}
        projects={projects}
        promptText={promptText}
        today={today}
        submitted={submitted}
        projectId={projectId}
        setProjectId={setProjectId}
        department={department}
        setDepartment={setDepartment}
        dateOfOccurrence={dateOfOccurrence}
        setDateOfOccurrence={setDateOfOccurrence}
        issueCategory={issueCategory}
        setIssueCategory={setIssueCategory}
        affectedSystem={affectedSystem}
        setAffectedSystem={setAffectedSystem}
        userPriority={userPriority}
        setUserPriority={setUserPriority}
        actionRequested={actionRequested}
        setActionRequested={setActionRequested}
        description={description}
        setDescription={setDescription}
        successCriteria={successCriteria}
        setSuccessCriteria={setSuccessCriteria}
        dateInFuture={dateInFuture}
        descOverLimit={descOverLimit}
        descRemaining={descRemaining}
        successOverLimit={successOverLimit}
        successRemaining={successRemaining}
      />

      {error && <p className="text-sm font-medium text-red-700 dark:text-red-300">{error}</p>}

      <FormActions>
        <PrimaryButton
          type="submit"
          loading={loading}
          className="w-full"
        >
          {loading ? labels.submitting : labels.submitIssue}
        </PrimaryButton>
      </FormActions>
    </FormPanel>
  )
}
