'use client'

import { useState, useCallback, useRef, useEffect } from 'react'
import { useRouter, useSearchParams } from 'next/navigation'
import type { Route } from 'next'
import { trpc } from '@/lib/trpc/client'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
import { ArrowLeft, Loader2, Save, Rocket } from 'lucide-react'
import Link from 'next/link'

import { WizardSection } from '@/components/admin/pipeline/wizard-section'
import { BasicsSection } from '@/components/admin/pipeline/sections/basics-section'
import { IntakeSection } from '@/components/admin/pipeline/sections/intake-section'
import { MainTrackSection } from '@/components/admin/pipeline/sections/main-track-section'
import { FilteringSection } from '@/components/admin/pipeline/sections/filtering-section'
import { AssignmentSection } from '@/components/admin/pipeline/sections/assignment-section'
import { AwardsSection } from '@/components/admin/pipeline/sections/awards-section'
import { LiveFinalsSection } from '@/components/admin/pipeline/sections/live-finals-section'
import { NotificationsSection } from '@/components/admin/pipeline/sections/notifications-section'
import { ReviewSection } from '@/components/admin/pipeline/sections/review-section'

import { defaultWizardState, defaultIntakeConfig, defaultFilterConfig, defaultEvaluationConfig, defaultLiveConfig } from '@/lib/pipeline-defaults'
import { validateAll, validateBasics, validateTracks } from '@/lib/pipeline-validation'
import type { WizardState, IntakeConfig, FilterConfig, EvaluationConfig, LiveFinalConfig } from '@/types/pipeline-wizard'

export default function NewPipelinePage() {
  const router = useRouter()
  const searchParams = useSearchParams()
  const programId = searchParams.get('programId') ?? ''

  const [state, setState] = useState<WizardState>(() => defaultWizardState(programId))
  const [openSection, setOpenSection] = useState(0)
  const initialStateRef = useRef(JSON.stringify(state))

  // Dirty tracking — warn on navigate away
  useEffect(() => {
    const handleBeforeUnload = (e: BeforeUnloadEvent) => {
      if (JSON.stringify(state) !== initialStateRef.current) {
        e.preventDefault()
      }
    }
    window.addEventListener('beforeunload', handleBeforeUnload)
    return () => window.removeEventListener('beforeunload', handleBeforeUnload)
  }, [state])

  const updateState = useCallback((updates: Partial<WizardState>) => {
    setState((prev) => ({ ...prev, ...updates }))
  }, [])

  // Get stage configs from the main track
  const mainTrack = state.tracks.find((t) => t.kind === 'MAIN')
  const intakeStage = mainTrack?.stages.find((s) => s.stageType === 'INTAKE')
  const filterStage = mainTrack?.stages.find((s) => s.stageType === 'FILTER')
  const evalStage = mainTrack?.stages.find((s) => s.stageType === 'EVALUATION')
  const liveStage = mainTrack?.stages.find((s) => s.stageType === 'LIVE_FINAL')

  const intakeConfig = (intakeStage?.configJson ?? defaultIntakeConfig()) as unknown as IntakeConfig
  const filterConfig = (filterStage?.configJson ?? defaultFilterConfig()) as unknown as FilterConfig
  const evalConfig = (evalStage?.configJson ?? defaultEvaluationConfig()) as unknown as EvaluationConfig
  const liveConfig = (liveStage?.configJson ?? defaultLiveConfig()) as unknown as LiveFinalConfig

  const updateStageConfig = useCallback(
    (stageType: string, configJson: Record<string, unknown>) => {
      setState((prev) => ({
        ...prev,
        tracks: prev.tracks.map((track) => {
          if (track.kind !== 'MAIN') return track
          return {
            ...track,
            stages: track.stages.map((stage) =>
              stage.stageType === stageType ? { ...stage, configJson } : stage
            ),
          }
        }),
      }))
    },
    []
  )

  const updateMainTrackStages = useCallback(
    (stages: WizardState['tracks'][0]['stages']) => {
      setState((prev) => ({
        ...prev,
        tracks: prev.tracks.map((track) =>
          track.kind === 'MAIN' ? { ...track, stages } : track
        ),
      }))
    },
    []
  )

  // Validation
  const basicsValid = validateBasics(state).valid
  const tracksValid = validateTracks(state.tracks).valid
  const allValid = validateAll(state).valid

  // Mutations
  const createMutation = trpc.pipeline.createStructure.useMutation({
    onSuccess: (data) => {
      initialStateRef.current = JSON.stringify(state) // prevent dirty warning
      toast.success('Pipeline created successfully')
      router.push(`/admin/rounds/pipeline/${data.pipeline.id}` as Route)
    },
    onError: (err) => {
      toast.error(err.message)
    },
  })

  const publishMutation = trpc.pipeline.publish.useMutation({
    onSuccess: () => {
      toast.success('Pipeline published successfully')
    },
    onError: (err) => {
      toast.error(err.message)
    },
  })

  const handleSave = async (publish: boolean) => {
    const validation = validateAll(state)
    if (!validation.valid) {
      toast.error('Please fix validation errors before saving')
      // Open first section with errors
      if (!validation.sections.basics.valid) setOpenSection(0)
      else if (!validation.sections.tracks.valid) setOpenSection(2)
      return
    }

    const result = await createMutation.mutateAsync({
      programId: state.programId,
      name: state.name,
      slug: state.slug,
      settingsJson: {
        ...state.settingsJson,
        notificationConfig: state.notificationConfig,
        overridePolicy: state.overridePolicy,
      },
      tracks: state.tracks.map((t) => ({
        name: t.name,
        slug: t.slug,
        kind: t.kind,
        sortOrder: t.sortOrder,
        routingModeDefault: t.routingModeDefault,
        decisionMode: t.decisionMode,
        stages: t.stages.map((s) => ({
          name: s.name,
          slug: s.slug,
          stageType: s.stageType,
          sortOrder: s.sortOrder,
          configJson: s.configJson,
        })),
        awardConfig: t.awardConfig,
      })),
      autoTransitions: true,
    })

    if (publish && result.pipeline.id) {
      await publishMutation.mutateAsync({ id: result.pipeline.id })
    }
  }

  const isSaving = createMutation.isPending || publishMutation.isPending

  const sections = [
    {
      title: 'Basics',
      description: 'Pipeline name, slug, and program',
      isValid: basicsValid,
    },
    {
      title: 'Intake',
      description: 'Submission windows and file requirements',
      isValid: !!intakeStage,
    },
    {
      title: 'Main Track Stages',
      description: `${mainTrack?.stages.length ?? 0} stages configured`,
      isValid: tracksValid,
    },
    {
      title: 'Filtering',
      description: 'Gate rules and AI screening settings',
      isValid: !!filterStage,
    },
    {
      title: 'Assignment',
      description: 'Jury evaluation assignment strategy',
      isValid: !!evalStage,
    },
    {
      title: 'Awards',
      description: `${state.tracks.filter((t) => t.kind === 'AWARD').length} award tracks`,
      isValid: true, // Awards are optional
    },
    {
      title: 'Live Finals',
      description: 'Voting, cohorts, and reveal settings',
      isValid: !!liveStage,
    },
    {
      title: 'Notifications',
      description: 'Event notifications and override governance',
      isValid: true, // Always valid
    },
    {
      title: 'Review & Publish',
      description: 'Validation summary and publish controls',
      isValid: allValid,
    },
  ]

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <Link href="/admin/rounds/pipelines">
            <Button variant="ghost" size="icon">
              <ArrowLeft className="h-4 w-4" />
            </Button>
          </Link>
          <div>
            <h1 className="text-xl font-bold">Create Pipeline</h1>
            <p className="text-sm text-muted-foreground">
              Configure the full pipeline structure for project evaluation
            </p>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <Button
            type="button"
            variant="outline"
            disabled={isSaving || !allValid}
            onClick={() => handleSave(false)}
          >
            {isSaving ? <Loader2 className="h-4 w-4 mr-2 animate-spin" /> : <Save className="h-4 w-4 mr-2" />}
            Save Draft
          </Button>
          <Button
            type="button"
            disabled={isSaving || !allValid}
            onClick={() => handleSave(true)}
          >
            {isSaving ? <Loader2 className="h-4 w-4 mr-2 animate-spin" /> : <Rocket className="h-4 w-4 mr-2" />}
            Save & Publish
          </Button>
        </div>
      </div>

      {/* Wizard Sections */}
      <div className="space-y-3">
        {/* 0: Basics */}
        <WizardSection
          stepNumber={1}
          title={sections[0].title}
          description={sections[0].description}
          isOpen={openSection === 0}
          onToggle={() => setOpenSection(openSection === 0 ? -1 : 0)}
          isValid={sections[0].isValid}
        >
          <BasicsSection state={state} onChange={updateState} />
        </WizardSection>

        {/* 1: Intake */}
        <WizardSection
          stepNumber={2}
          title={sections[1].title}
          description={sections[1].description}
          isOpen={openSection === 1}
          onToggle={() => setOpenSection(openSection === 1 ? -1 : 1)}
          isValid={sections[1].isValid}
        >
          <IntakeSection
            config={intakeConfig}
            onChange={(c) =>
              updateStageConfig('INTAKE', c as unknown as Record<string, unknown>)
            }
          />
        </WizardSection>

        {/* 2: Main Track Stages */}
        <WizardSection
          stepNumber={3}
          title={sections[2].title}
          description={sections[2].description}
          isOpen={openSection === 2}
          onToggle={() => setOpenSection(openSection === 2 ? -1 : 2)}
          isValid={sections[2].isValid}
        >
          <MainTrackSection
            stages={mainTrack?.stages ?? []}
            onChange={updateMainTrackStages}
          />
        </WizardSection>

        {/* 3: Filtering */}
        <WizardSection
          stepNumber={4}
          title={sections[3].title}
          description={sections[3].description}
          isOpen={openSection === 3}
          onToggle={() => setOpenSection(openSection === 3 ? -1 : 3)}
          isValid={sections[3].isValid}
        >
          <FilteringSection
            config={filterConfig}
            onChange={(c) =>
              updateStageConfig('FILTER', c as unknown as Record<string, unknown>)
            }
          />
        </WizardSection>

        {/* 4: Assignment */}
        <WizardSection
          stepNumber={5}
          title={sections[4].title}
          description={sections[4].description}
          isOpen={openSection === 4}
          onToggle={() => setOpenSection(openSection === 4 ? -1 : 4)}
          isValid={sections[4].isValid}
        >
          <AssignmentSection
            config={evalConfig}
            onChange={(c) =>
              updateStageConfig('EVALUATION', c as unknown as Record<string, unknown>)
            }
          />
        </WizardSection>

        {/* 5: Awards */}
        <WizardSection
          stepNumber={6}
          title={sections[5].title}
          description={sections[5].description}
          isOpen={openSection === 5}
          onToggle={() => setOpenSection(openSection === 5 ? -1 : 5)}
          isValid={sections[5].isValid}
        >
          <AwardsSection tracks={state.tracks} onChange={(tracks) => updateState({ tracks })} />
        </WizardSection>

        {/* 6: Live Finals */}
        <WizardSection
          stepNumber={7}
          title={sections[6].title}
          description={sections[6].description}
          isOpen={openSection === 6}
          onToggle={() => setOpenSection(openSection === 6 ? -1 : 6)}
          isValid={sections[6].isValid}
        >
          <LiveFinalsSection
            config={liveConfig}
            onChange={(c) =>
              updateStageConfig('LIVE_FINAL', c as unknown as Record<string, unknown>)
            }
          />
        </WizardSection>

        {/* 7: Notifications */}
        <WizardSection
          stepNumber={8}
          title={sections[7].title}
          description={sections[7].description}
          isOpen={openSection === 7}
          onToggle={() => setOpenSection(openSection === 7 ? -1 : 7)}
          isValid={sections[7].isValid}
        >
          <NotificationsSection
            config={state.notificationConfig}
            onChange={(notificationConfig) => updateState({ notificationConfig })}
            overridePolicy={state.overridePolicy}
            onOverridePolicyChange={(overridePolicy) => updateState({ overridePolicy })}
          />
        </WizardSection>

        {/* 8: Review */}
        <WizardSection
          stepNumber={9}
          title={sections[8].title}
          description={sections[8].description}
          isOpen={openSection === 8}
          onToggle={() => setOpenSection(openSection === 8 ? -1 : 8)}
          isValid={sections[8].isValid}
        >
          <ReviewSection state={state} />
        </WizardSection>
      </div>
    </div>
  )
}
