'use client'

import { useState, useEffect } from 'react'
import { useParams, useRouter } from 'next/navigation'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { motion, AnimatePresence } from 'motion/react'
import { trpc } from '@/lib/trpc/client'
import { toast } from 'sonner'
import {
  Waves,
  AlertCircle,
  Loader2,
  CheckCircle,
  ArrowLeft,
  ArrowRight,
  Clock,
} from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Skeleton } from '@/components/ui/skeleton'
import {
  StepWelcome,
  StepContact,
  StepProject,
  StepTeam,
  StepAdditional,
  StepReview,
} from '@/components/forms/apply-steps'
import { CompetitionCategory, OceanIssue, TeamMemberRole } from '@prisma/client'
import { cn } from '@/lib/utils'

// Form validation schema
const teamMemberSchema = z.object({
  name: z.string().min(1, 'Name is required'),
  email: z.string().email('Invalid email address'),
  role: z.nativeEnum(TeamMemberRole).default('MEMBER'),
  title: z.string().optional(),
})

const applicationSchema = z.object({
  competitionCategory: z.nativeEnum(CompetitionCategory),
  contactName: z.string().min(2, 'Full name is required'),
  contactEmail: z.string().email('Invalid email address'),
  contactPhone: z.string().min(5, 'Phone number is required'),
  country: z.string().min(2, 'Country is required'),
  city: z.string().optional(),
  projectName: z.string().min(2, 'Project name is required').max(200),
  teamName: z.string().optional(),
  description: z.string().min(20, 'Description must be at least 20 characters'),
  oceanIssue: z.nativeEnum(OceanIssue),
  teamMembers: z.array(teamMemberSchema).optional(),
  institution: z.string().optional(),
  startupCreatedDate: z.string().optional(),
  wantsMentorship: z.boolean().default(false),
  referralSource: z.string().optional(),
  gdprConsent: z.boolean().refine((val) => val === true, {
    message: 'You must agree to the data processing terms',
  }),
})

type ApplicationFormData = z.infer<typeof applicationSchema>

const STEPS = [
  { id: 'welcome', title: 'Category', fields: ['competitionCategory'] },
  { id: 'contact', title: 'Contact', fields: ['contactName', 'contactEmail', 'contactPhone', 'country'] },
  { id: 'project', title: 'Project', fields: ['projectName', 'description', 'oceanIssue'] },
  { id: 'team', title: 'Team', fields: [] },
  { id: 'additional', title: 'Details', fields: [] },
  { id: 'review', title: 'Review', fields: ['gdprConsent'] },
]

export default function ApplyWizardPage() {
  const params = useParams()
  const router = useRouter()
  const slug = params.slug as string

  const [currentStep, setCurrentStep] = useState(0)
  const [direction, setDirection] = useState(0)
  const [submitted, setSubmitted] = useState(false)
  const [submissionMessage, setSubmissionMessage] = useState('')

  const { data: config, isLoading, error } = trpc.application.getConfig.useQuery(
    { roundSlug: slug },
    { retry: false }
  )

  const submitMutation = trpc.application.submit.useMutation({
    onSuccess: (result) => {
      setSubmitted(true)
      setSubmissionMessage(result.message)
    },
    onError: (error) => {
      toast.error(error.message)
    },
  })

  const form = useForm<ApplicationFormData>({
    resolver: zodResolver(applicationSchema),
    defaultValues: {
      competitionCategory: undefined,
      contactName: '',
      contactEmail: '',
      contactPhone: '',
      country: '',
      city: '',
      projectName: '',
      teamName: '',
      description: '',
      oceanIssue: undefined,
      teamMembers: [],
      institution: '',
      startupCreatedDate: '',
      wantsMentorship: false,
      referralSource: '',
      gdprConsent: false,
    },
    mode: 'onChange',
  })

  const { watch, trigger, handleSubmit } = form
  const competitionCategory = watch('competitionCategory')

  const isBusinessConcept = competitionCategory === 'BUSINESS_CONCEPT'
  const isStartup = competitionCategory === 'STARTUP'

  const validateCurrentStep = async () => {
    const currentFields = STEPS[currentStep].fields as (keyof ApplicationFormData)[]
    if (currentFields.length === 0) return true
    return await trigger(currentFields)
  }

  const nextStep = async () => {
    const isValid = await validateCurrentStep()
    if (isValid && currentStep < STEPS.length - 1) {
      setDirection(1)
      setCurrentStep((prev) => prev + 1)
    }
  }

  const prevStep = () => {
    if (currentStep > 0) {
      setDirection(-1)
      setCurrentStep((prev) => prev - 1)
    }
  }

  const onSubmit = async (data: ApplicationFormData) => {
    if (!config) return
    await submitMutation.mutateAsync({
      roundId: config.round.id,
      data,
    })
  }

  // Handle keyboard navigation
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Enter' && !e.shiftKey && currentStep < STEPS.length - 1) {
        e.preventDefault()
        nextStep()
      }
    }

    window.addEventListener('keydown', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [currentStep])

  // Loading state
  if (isLoading) {
    return (
      <div className="min-h-screen bg-gradient-to-br from-background to-muted/30 flex items-center justify-center p-4">
        <div className="w-full max-w-2xl space-y-6">
          <div className="flex items-center justify-center gap-3">
            <Loader2 className="h-8 w-8 animate-spin text-primary" />
            <span className="text-lg text-muted-foreground">Loading application...</span>
          </div>
        </div>
      </div>
    )
  }

  // Error state
  if (error) {
    return (
      <div className="min-h-screen bg-gradient-to-br from-background to-muted/30 flex items-center justify-center p-4">
        <div className="w-full max-w-md text-center">
          <AlertCircle className="mx-auto h-16 w-16 text-destructive mb-4" />
          <h1 className="text-2xl font-bold mb-2">Application Not Available</h1>
          <p className="text-muted-foreground mb-6">{error.message}</p>
          <Button variant="outline" onClick={() => router.push('/')}>
            Return Home
          </Button>
        </div>
      </div>
    )
  }

  // Applications closed state
  if (config && !config.round.isOpen) {
    return (
      <div className="min-h-screen bg-gradient-to-br from-background to-muted/30 flex items-center justify-center p-4">
        <div className="w-full max-w-md text-center">
          <Clock className="mx-auto h-16 w-16 text-muted-foreground mb-4" />
          <h1 className="text-2xl font-bold mb-2">Applications Closed</h1>
          <p className="text-muted-foreground mb-6">
            The application period for {config.program.name} {config.program.year} has ended.
            {config.round.submissionEndDate && (
              <span className="block mt-2">
                Submissions closed on{' '}
                {new Date(config.round.submissionEndDate).toLocaleDateString('en-US', {
                  dateStyle: 'long',
                })}
              </span>
            )}
          </p>
          <Button variant="outline" onClick={() => router.push('/')}>
            Return Home
          </Button>
        </div>
      </div>
    )
  }

  // Success state
  if (submitted) {
    return (
      <div className="min-h-screen bg-gradient-to-br from-background to-muted/30 flex items-center justify-center p-4">
        <motion.div
          initial={{ scale: 0.8, opacity: 0 }}
          animate={{ scale: 1, opacity: 1 }}
          className="w-full max-w-md text-center"
        >
          <motion.div
            initial={{ scale: 0 }}
            animate={{ scale: 1 }}
            transition={{ delay: 0.2, type: 'spring' }}
          >
            <CheckCircle className="mx-auto h-20 w-20 text-green-500 mb-6" />
          </motion.div>
          <h1 className="text-3xl font-bold mb-4">Application Submitted!</h1>
          <p className="text-muted-foreground mb-8">{submissionMessage}</p>
          <Button onClick={() => router.push('/')}>
            Return Home
          </Button>
        </motion.div>
      </div>
    )
  }

  if (!config) return null

  const progress = ((currentStep + 1) / STEPS.length) * 100

  const variants = {
    enter: (direction: number) => ({
      x: direction > 0 ? 50 : -50,
      opacity: 0,
    }),
    center: {
      x: 0,
      opacity: 1,
    },
    exit: (direction: number) => ({
      x: direction < 0 ? 50 : -50,
      opacity: 0,
    }),
  }

  return (
    <div className="min-h-screen bg-gradient-to-br from-background to-muted/30">
      {/* Header */}
      <header className="sticky top-0 z-50 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
        <div className="mx-auto max-w-4xl px-4 py-4">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-3">
              <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10">
                <Waves className="h-5 w-5 text-primary" />
              </div>
              <div>
                <h1 className="font-semibold">{config.program.name}</h1>
                <p className="text-xs text-muted-foreground">{config.program.year} Application</p>
              </div>
            </div>
            <div className="text-right">
              <span className="text-sm text-muted-foreground">
                Step {currentStep + 1} of {STEPS.length}
              </span>
            </div>
          </div>

          {/* Progress bar */}
          <div className="mt-4 h-1.5 w-full overflow-hidden rounded-full bg-muted">
            <motion.div
              className="h-full bg-gradient-to-r from-primary to-primary/70"
              initial={{ width: 0 }}
              animate={{ width: `${progress}%` }}
              transition={{ duration: 0.3 }}
            />
          </div>

          {/* Step indicators */}
          <div className="mt-3 flex justify-between">
            {STEPS.map((step, index) => (
              <button
                key={step.id}
                type="button"
                onClick={() => {
                  if (index < currentStep) {
                    setDirection(index < currentStep ? -1 : 1)
                    setCurrentStep(index)
                  }
                }}
                disabled={index > currentStep}
                className={cn(
                  'hidden text-xs font-medium transition-colors sm:block',
                  index === currentStep && 'text-primary',
                  index < currentStep && 'text-muted-foreground hover:text-foreground cursor-pointer',
                  index > currentStep && 'text-muted-foreground/50'
                )}
              >
                {step.title}
              </button>
            ))}
          </div>
        </div>
      </header>

      {/* Main content */}
      <main className="mx-auto max-w-4xl px-4 py-8">
        <form onSubmit={handleSubmit(onSubmit)}>
          <div className="relative min-h-[500px]">
            <AnimatePresence initial={false} custom={direction} mode="wait">
              <motion.div
                key={currentStep}
                custom={direction}
                variants={variants}
                initial="enter"
                animate="center"
                exit="exit"
                transition={{
                  x: { type: 'spring', stiffness: 300, damping: 30 },
                  opacity: { duration: 0.2 },
                }}
                className="w-full"
              >
                {currentStep === 0 && (
                  <StepWelcome
                    programName={config.program.name}
                    programYear={config.program.year}
                    value={competitionCategory}
                    onChange={(value) => form.setValue('competitionCategory', value)}
                  />
                )}
                {currentStep === 1 && <StepContact form={form} />}
                {currentStep === 2 && <StepProject form={form} />}
                {currentStep === 3 && <StepTeam form={form} />}
                {currentStep === 4 && (
                  <StepAdditional
                    form={form}
                    isBusinessConcept={isBusinessConcept}
                    isStartup={isStartup}
                  />
                )}
                {currentStep === 5 && (
                  <StepReview form={form} programName={config.program.name} />
                )}
              </motion.div>
            </AnimatePresence>
          </div>

          {/* Navigation buttons */}
          <div className="mt-8 flex items-center justify-between border-t pt-6">
            <Button
              type="button"
              variant="ghost"
              onClick={prevStep}
              disabled={currentStep === 0 || submitMutation.isPending}
              className={cn(currentStep === 0 && 'invisible')}
            >
              <ArrowLeft className="mr-2 h-4 w-4" />
              Back
            </Button>

            {currentStep < STEPS.length - 1 ? (
              <Button type="button" onClick={nextStep}>
                Continue
                <ArrowRight className="ml-2 h-4 w-4" />
              </Button>
            ) : (
              <Button type="submit" disabled={submitMutation.isPending}>
                {submitMutation.isPending ? (
                  <>
                    <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                    Submitting...
                  </>
                ) : (
                  <>
                    <CheckCircle className="mr-2 h-4 w-4" />
                    Submit Application
                  </>
                )}
              </Button>
            )}
          </div>
        </form>
      </main>

      {/* Footer with deadline info */}
      {config.round.submissionEndDate && (
        <footer className="fixed bottom-0 left-0 right-0 border-t bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 py-3">
          <div className="mx-auto max-w-4xl px-4 text-center text-sm text-muted-foreground">
            <Clock className="inline-block mr-1 h-4 w-4" />
            Applications due by{' '}
            {new Date(config.round.submissionEndDate).toLocaleDateString('en-US', {
              dateStyle: 'long',
            })}
          </div>
        </footer>
      )}
    </div>
  )
}
