import { useEffect, useMemo, useState } from 'react'
import api from '@/services/api'
import type { Milestone, Project, Task } from '@/types'

const TASK_TYPES = [
  { value: 'story', label: 'Story', subtypes: ['improvement', 'refactor'] },  // P9.6: 'feature' removed — must come from propose accept
  { value: 'issue', label: 'Issue', subtypes: ['infrastructure', 'performance', 'regression', 'security', 'user_experience', 'defect'] },
  { value: 'task', label: 'Task', subtypes: ['defect'] },
  { value: 'test', label: 'Test', subtypes: ['regression', 'security', 'smoke', 'stress'] },
  { value: 'maintenance', label: 'Maintenance', subtypes: ['deploy'] },  // P9.6: 'release' removed — controlled via milestone flow
  { value: 'research', label: 'Research', subtypes: [] },
  { value: 'review', label: 'Review', subtypes: ['code_review', 'decision_review', 'function_review'] },
  { value: 'resolution', label: 'Resolution', subtypes: [] },
]

type Props = {
  isOpen: boolean
  onClose: () => void
  onCreated?: (task: Task) => void | Promise<void>
  onSaved?: (task: Task) => void | Promise<void>
  initialProjectId?: number
  initialMilestoneId?: number
  lockProject?: boolean
  lockMilestone?: boolean
  task?: Task | null
}

type FormState = {
  title: string
  description: string
  project_id: number
  milestone_id: number
  task_type: string
  task_subtype: string
  priority: string
  tags: string
  reporter_id: number
}

const makeInitialForm = (projectId = 0, milestoneId = 0): FormState => ({
  title: '',
  description: '',
  project_id: projectId,
  milestone_id: milestoneId,
  task_type: 'task',
  task_subtype: '',
  priority: 'medium',
  tags: '',
  reporter_id: 1,
})

export default function CreateTaskModal({
  isOpen,
  onClose,
  onCreated,
  onSaved,
  initialProjectId,
  initialMilestoneId,
  lockProject = false,
  lockMilestone = false,
  task,
}: Props) {
  const [projects, setProjects] = useState<Project[]>([])
  const [milestones, setMilestones] = useState<Milestone[]>([])
  const [saving, setSaving] = useState(false)
  const [form, setForm] = useState<FormState>(makeInitialForm(initialProjectId, initialMilestoneId))

  const isEdit = Boolean(task)
  const currentType = useMemo(
    () => TASK_TYPES.find((t) => t.value === form.task_type) || TASK_TYPES[2],
    [form.task_type]
  )
  const subtypes = currentType.subtypes || []

  const loadMilestones = async (projectId: number, preferredMilestoneId?: number) => {
    if (!projectId) {
      setMilestones([])
      setForm((f) => ({ ...f, milestone_id: 0 }))
      return
    }

    const { data } = await api.get<Milestone[]>(`/milestones?project_id=${projectId}`)
    setMilestones(data)
    const hasPreferred = preferredMilestoneId && data.some((m) => m.id === preferredMilestoneId)
    const nextMilestoneId = hasPreferred ? preferredMilestoneId! : (data[0]?.id || 0)
    setForm((f) => ({ ...f, milestone_id: nextMilestoneId }))
  }

  useEffect(() => {
    if (!isOpen) return

    const init = async () => {
      const { data } = await api.get<Project[]>('/projects')
      setProjects(data)

      const chosenProjectId = task?.project_id || initialProjectId || data[0]?.id || 0
      const chosenMilestoneId = task?.milestone_id || initialMilestoneId || 0

      setForm(task ? {
        title: task.title,
        description: task.description || '',
        project_id: task.project_id,
        milestone_id: task.milestone_id || 0,
        task_type: task.task_type,
        task_subtype: task.task_subtype || '',
        priority: task.priority,
        tags: task.tags || '',
        reporter_id: task.reporter_id,
      } : makeInitialForm(chosenProjectId, chosenMilestoneId))

      await loadMilestones(chosenProjectId, chosenMilestoneId)
    }

    init().catch(console.error)
  }, [isOpen, initialProjectId, initialMilestoneId, task])

  const handleProjectChange = async (projectId: number) => {
    setForm((f) => ({ ...f, project_id: projectId, milestone_id: 0 }))
    await loadMilestones(projectId)
  }

  const handleTypeChange = (taskType: string) => {
    setForm((f) => ({ ...f, task_type: taskType, task_subtype: '' }))
  }

  const submit = async (e: React.FormEvent) => {
    e.preventDefault()
    if (!form.milestone_id) {
      alert('Please select a milestone')
      return
    }

    const payload: any = { ...form, tags: form.tags || null }
    if (!form.task_subtype) delete payload.task_subtype

    setSaving(true)
    try {
      const { data } = isEdit
        ? await api.patch<Task>(`/tasks/${task!.id}`, payload)
        : await api.post<Task>('/tasks', payload)
      await onCreated?.(data)
      await onSaved?.(data)
      onClose()
    } finally {
      setSaving(false)
    }
  }

  if (!isOpen) return null

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal task-create-modal" onClick={(e) => e.stopPropagation()}>
        <div className="modal-header">
          <h3>{isEdit ? 'Edit Task' : 'Create Task'}</h3>
          <button type="button" className="btn-secondary" onClick={onClose}>✕</button>
        </div>

        <form className="task-create-form" onSubmit={submit}>
          <label>
            Title
            <input
              data-testid="task-title-input"
              required
              value={form.title}
              onChange={(e) => setForm({ ...form, title: e.target.value })}
            />
          </label>

          <label>
            Description
            <textarea
              data-testid="task-description-input"
              value={form.description}
              onChange={(e) => setForm({ ...form, description: e.target.value })}
            />
          </label>

          <div className="task-create-grid">
            <label>
              Project
              <select
                data-testid="project-select"
                value={form.project_id}
                onChange={(e) => handleProjectChange(Number(e.target.value))}
                disabled={lockProject}
              >
                {projects.map((p) => (
                  <option key={p.id} value={p.id}>{p.name}</option>
                ))}
              </select>
            </label>

            <label>
              Milestone
              <select
                data-testid="milestone-select"
                value={form.milestone_id}
                onChange={(e) => setForm({ ...form, milestone_id: Number(e.target.value) })}
                disabled={lockMilestone}
              >
                {milestones.length === 0 && <option value={0}>No milestones available</option>}
                {milestones.map((m) => (
                  <option key={m.id} value={m.id}>{m.title}</option>
                ))}
              </select>
            </label>

            <label>
              Type
              <select
                data-testid="task-type-select"
                value={form.task_type}
                onChange={(e) => handleTypeChange(e.target.value)}
              >
                {TASK_TYPES.map((t) => (
                  <option key={t.value} value={t.value}>{t.label}</option>
                ))}
              </select>
            </label>

            <label>
              Priority
              <select
                value={form.priority}
                onChange={(e) => setForm({ ...form, priority: e.target.value })}
              >
                <option value="low">Low</option>
                <option value="medium">Medium</option>
                <option value="high">High</option>
                <option value="critical">Critical</option>
              </select>
            </label>
          </div>

          {subtypes.length > 0 && (
            <label>
              Subtype
              <select
                value={form.task_subtype}
                onChange={(e) => setForm({ ...form, task_subtype: e.target.value })}
              >
                <option value="">Select subtype</option>
                {subtypes.map((s) => (
                  <option key={s} value={s}>{s.replace(/_/g, ' ')}</option>
                ))}
              </select>
            </label>
          )}

          <label>
            Tags
            <input
              value={form.tags}
              onChange={(e) => setForm({ ...form, tags: e.target.value })}
              placeholder="Comma separated"
            />
          </label>

          <div className="modal-actions">
            <button data-testid="create-task-button" type="submit" className="btn-primary" disabled={saving}>
              {saving ? (isEdit ? 'Saving...' : 'Creating...') : (isEdit ? 'Save' : 'Create')}
            </button>
            <button type="button" className="btn-secondary" onClick={onClose} disabled={saving}>Cancel</button>
          </div>
        </form>
      </div>
    </div>
  )
}
