'use client'

import { useState, useEffect } from 'react'
import { useParams } from 'next/navigation'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { trpc } from '@/lib/trpc/client'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Textarea } from '@/components/ui/textarea'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import { Checkbox } from '@/components/ui/checkbox'
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
import { Skeleton } from '@/components/ui/skeleton'
import { toast } from 'sonner'
import { CheckCircle, AlertCircle, Loader2 } from 'lucide-react'

type FormField = {
  id: string
  fieldType: string
  name: string
  label: string
  description?: string | null
  placeholder?: string | null
  required: boolean
  minLength?: number | null
  maxLength?: number | null
  minValue?: number | null
  maxValue?: number | null
  optionsJson: Array<{ value: string; label: string }> | null
  conditionJson: { fieldId: string; operator: string; value?: string } | null
  width: string
}

export default function PublicFormPage() {
  const params = useParams()
  const slug = params.slug as string
  const [submitted, setSubmitted] = useState(false)
  const [confirmationMessage, setConfirmationMessage] = useState<string | null>(null)

  const { data: form, isLoading, error } = trpc.applicationForm.getBySlug.useQuery(
    { slug },
    { retry: false }
  )

  const submitMutation = trpc.applicationForm.submit.useMutation({
    onSuccess: (result) => {
      setSubmitted(true)
      setConfirmationMessage(result.confirmationMessage || null)
    },
    onError: (error) => {
      toast.error(error.message)
    },
  })

  const {
    register,
    handleSubmit,
    watch,
    formState: { errors, isSubmitting },
    setValue,
  } = useForm()

  const watchedValues = watch()

  const onSubmit = async (data: Record<string, unknown>) => {
    if (!form) return

    // Extract email and name if present
    const emailField = form.fields.find((f) => f.fieldType === 'EMAIL')
    const email = emailField ? (data[emailField.name] as string) : undefined

    // Find a name field (common patterns)
    const nameField = form.fields.find(
      (f) => f.name.toLowerCase().includes('name') && f.fieldType === 'TEXT'
    )
    const name = nameField ? (data[nameField.name] as string) : undefined

    await submitMutation.mutateAsync({
      formId: form.id,
      data,
      email,
      name,
    })
  }

  if (isLoading) {
    return (
      <div className="max-w-2xl mx-auto space-y-6">
        <Card>
          <CardHeader>
            <Skeleton className="h-8 w-64" />
            <Skeleton className="h-4 w-full" />
          </CardHeader>
          <CardContent className="space-y-4">
            {[1, 2, 3, 4].map((i) => (
              <div key={i} className="space-y-2">
                <Skeleton className="h-4 w-32" />
                <Skeleton className="h-10 w-full" />
              </div>
            ))}
          </CardContent>
        </Card>
      </div>
    )
  }

  if (error) {
    return (
      <div className="max-w-2xl mx-auto">
        <Card>
          <CardContent className="flex flex-col items-center justify-center py-12">
            <AlertCircle className="h-12 w-12 text-destructive mb-4" />
            <h2 className="text-xl font-semibold mb-2">Form Not Available</h2>
            <p className="text-muted-foreground text-center">
              {error.message}
            </p>
          </CardContent>
        </Card>
      </div>
    )
  }

  if (submitted) {
    return (
      <div className="max-w-2xl mx-auto">
        <Card>
          <CardContent className="flex flex-col items-center justify-center py-12">
            <CheckCircle className="h-12 w-12 text-green-500 mb-4" />
            <h2 className="text-xl font-semibold mb-2">Thank You!</h2>
            <p className="text-muted-foreground text-center">
              {confirmationMessage || 'Your submission has been received.'}
            </p>
          </CardContent>
        </Card>
      </div>
    )
  }

  if (!form) return null

  // Check if a field should be visible based on conditions
  const isFieldVisible = (field: FormField): boolean => {
    if (!field.conditionJson) return true

    const condition = field.conditionJson
    const dependentValue = watchedValues[form.fields.find((f) => f.id === condition.fieldId)?.name || '']

    switch (condition.operator) {
      case 'equals':
        return dependentValue === condition.value
      case 'not_equals':
        return dependentValue !== condition.value
      case 'not_empty':
        return !!dependentValue && dependentValue !== ''
      case 'contains':
        return typeof dependentValue === 'string' && dependentValue.includes(condition.value || '')
      default:
        return true
    }
  }

  const renderField = (field: FormField) => {
    if (!isFieldVisible(field)) return null

    const fieldError = errors[field.name]
    const errorMessage = fieldError?.message as string | undefined

    switch (field.fieldType) {
      case 'SECTION':
        return (
          <div key={field.id} className="col-span-full pt-6 pb-2">
            <h3 className="text-lg font-semibold">{field.label}</h3>
            {field.description && (
              <p className="text-sm text-muted-foreground">{field.description}</p>
            )}
          </div>
        )

      case 'INSTRUCTIONS':
        return (
          <div key={field.id} className="col-span-full">
            <div className="bg-muted p-4 rounded-lg">
              <p className="text-sm">{field.description || field.label}</p>
            </div>
          </div>
        )

      case 'TEXT':
      case 'EMAIL':
      case 'PHONE':
      case 'URL':
        return (
          <div key={field.id} className={field.width === 'half' ? 'col-span-1' : 'col-span-full'}>
            <Label htmlFor={field.name}>
              {field.label}
              {field.required && <span className="text-destructive ml-1">*</span>}
            </Label>
            {field.description && (
              <p className="text-xs text-muted-foreground mb-1">{field.description}</p>
            )}
            <Input
              id={field.name}
              type={field.fieldType === 'EMAIL' ? 'email' : field.fieldType === 'URL' ? 'url' : 'text'}
              placeholder={field.placeholder || undefined}
              {...register(field.name, {
                required: field.required ? `${field.label} is required` : false,
                minLength: field.minLength ? { value: field.minLength, message: `Minimum ${field.minLength} characters` } : undefined,
                maxLength: field.maxLength ? { value: field.maxLength, message: `Maximum ${field.maxLength} characters` } : undefined,
              })}
            />
            {errorMessage && <p className="text-sm text-destructive mt-1">{errorMessage}</p>}
          </div>
        )

      case 'NUMBER':
        return (
          <div key={field.id} className={field.width === 'half' ? 'col-span-1' : 'col-span-full'}>
            <Label htmlFor={field.name}>
              {field.label}
              {field.required && <span className="text-destructive ml-1">*</span>}
            </Label>
            {field.description && (
              <p className="text-xs text-muted-foreground mb-1">{field.description}</p>
            )}
            <Input
              id={field.name}
              type="number"
              placeholder={field.placeholder || undefined}
              {...register(field.name, {
                required: field.required ? `${field.label} is required` : false,
                valueAsNumber: true,
                min: field.minValue ? { value: field.minValue, message: `Minimum value is ${field.minValue}` } : undefined,
                max: field.maxValue ? { value: field.maxValue, message: `Maximum value is ${field.maxValue}` } : undefined,
              })}
            />
            {errorMessage && <p className="text-sm text-destructive mt-1">{errorMessage}</p>}
          </div>
        )

      case 'TEXTAREA':
        return (
          <div key={field.id} className="col-span-full">
            <Label htmlFor={field.name}>
              {field.label}
              {field.required && <span className="text-destructive ml-1">*</span>}
            </Label>
            {field.description && (
              <p className="text-xs text-muted-foreground mb-1">{field.description}</p>
            )}
            <Textarea
              id={field.name}
              placeholder={field.placeholder || undefined}
              rows={4}
              {...register(field.name, {
                required: field.required ? `${field.label} is required` : false,
                minLength: field.minLength ? { value: field.minLength, message: `Minimum ${field.minLength} characters` } : undefined,
                maxLength: field.maxLength ? { value: field.maxLength, message: `Maximum ${field.maxLength} characters` } : undefined,
              })}
            />
            {errorMessage && <p className="text-sm text-destructive mt-1">{errorMessage}</p>}
          </div>
        )

      case 'DATE':
      case 'DATETIME':
        return (
          <div key={field.id} className={field.width === 'half' ? 'col-span-1' : 'col-span-full'}>
            <Label htmlFor={field.name}>
              {field.label}
              {field.required && <span className="text-destructive ml-1">*</span>}
            </Label>
            {field.description && (
              <p className="text-xs text-muted-foreground mb-1">{field.description}</p>
            )}
            <Input
              id={field.name}
              type={field.fieldType === 'DATETIME' ? 'datetime-local' : 'date'}
              {...register(field.name, {
                required: field.required ? `${field.label} is required` : false,
              })}
            />
            {errorMessage && <p className="text-sm text-destructive mt-1">{errorMessage}</p>}
          </div>
        )

      case 'SELECT':
        return (
          <div key={field.id} className={field.width === 'half' ? 'col-span-1' : 'col-span-full'}>
            <Label htmlFor={field.name}>
              {field.label}
              {field.required && <span className="text-destructive ml-1">*</span>}
            </Label>
            {field.description && (
              <p className="text-xs text-muted-foreground mb-1">{field.description}</p>
            )}
            <Select
              onValueChange={(value) => setValue(field.name, value)}
            >
              <SelectTrigger>
                <SelectValue placeholder={field.placeholder || 'Select an option'} />
              </SelectTrigger>
              <SelectContent>
                {(field.optionsJson || []).map((option) => (
                  <SelectItem key={option.value} value={option.value}>
                    {option.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <input
              type="hidden"
              {...register(field.name, {
                required: field.required ? `${field.label} is required` : false,
              })}
            />
            {errorMessage && <p className="text-sm text-destructive mt-1">{errorMessage}</p>}
          </div>
        )

      case 'RADIO':
        return (
          <div key={field.id} className="col-span-full">
            <Label>
              {field.label}
              {field.required && <span className="text-destructive ml-1">*</span>}
            </Label>
            {field.description && (
              <p className="text-xs text-muted-foreground mb-1">{field.description}</p>
            )}
            <RadioGroup
              onValueChange={(value) => setValue(field.name, value)}
              className="mt-2"
            >
              {(field.optionsJson || []).map((option) => (
                <div key={option.value} className="flex items-center space-x-2">
                  <RadioGroupItem value={option.value} id={`${field.name}-${option.value}`} />
                  <Label htmlFor={`${field.name}-${option.value}`} className="font-normal">
                    {option.label}
                  </Label>
                </div>
              ))}
            </RadioGroup>
            <input
              type="hidden"
              {...register(field.name, {
                required: field.required ? `${field.label} is required` : false,
              })}
            />
            {errorMessage && <p className="text-sm text-destructive mt-1">{errorMessage}</p>}
          </div>
        )

      case 'CHECKBOX':
        return (
          <div key={field.id} className="col-span-full">
            <div className="flex items-center space-x-2">
              <Checkbox
                id={field.name}
                onCheckedChange={(checked) => setValue(field.name, checked)}
              />
              <Label htmlFor={field.name} className="font-normal">
                {field.label}
                {field.required && <span className="text-destructive ml-1">*</span>}
              </Label>
            </div>
            {field.description && (
              <p className="text-xs text-muted-foreground ml-6">{field.description}</p>
            )}
            <input
              type="hidden"
              {...register(field.name, {
                validate: field.required ? (value) => value === true || `${field.label} is required` : undefined,
              })}
            />
            {errorMessage && <p className="text-sm text-destructive mt-1">{errorMessage}</p>}
          </div>
        )

      default:
        return null
    }
  }

  return (
    <div className="max-w-2xl mx-auto">
      <Card>
        <CardHeader>
          <CardTitle>{form.name}</CardTitle>
          {form.description && (
            <CardDescription>{form.description}</CardDescription>
          )}
        </CardHeader>
        <CardContent>
          <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
            <div className="grid grid-cols-2 gap-4">
              {form.fields.map((field) => renderField(field as FormField))}
            </div>

            <Button
              type="submit"
              className="w-full"
              disabled={isSubmitting || submitMutation.isPending}
            >
              {(isSubmitting || submitMutation.isPending) && (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              )}
              Submit
            </Button>
          </form>
        </CardContent>
      </Card>
    </div>
  )
}
