"use client"

import * as React from "react"
import { useRouter } from "next/navigation"
import { Loader2, Save, X } from "lucide-react"

import { cn } from "@/lib/utils"
import { supabase } from "@/lib/supabase"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Select } from "@/components/ui/select"
import { Switch } from "@/components/ui/switch"
import { TagInput } from "@/components/tag-input"
import { ExerciseList, Exercise } from "@/components/exercise-list"
import { MediaUpload } from "@/components/media-upload"
import { moveFilesFromTempToWorkout } from "@/lib/storage"
import { toast } from "sonner"
import type { Database } from "@/lib/supabase"

type Workout = Database["public"]["Tables"]["workouts"]["Row"]

interface WorkoutFormProps {
  initialData?: Workout
  mode?: "create" | "edit"
}

const CATEGORY_OPTIONS = [
  { value: "full-body", label: "Full Body" },
  { value: "core", label: "Core" },
  { value: "upper-body", label: "Upper Body" },
  { value: "lower-body", label: "Lower Body" },
  { value: "cardio", label: "Cardio" },
]

const LEVEL_OPTIONS = [
  { value: "Beginner", label: "Beginner" },
  { value: "Intermediate", label: "Intermediate" },
  { value: "Advanced", label: "Advanced" },
]

const DURATION_OPTIONS = [
  { value: "4", label: "4 minutes" },
  { value: "8", label: "8 minutes" },
  { value: "12", label: "12 minutes" },
  { value: "20", label: "20 minutes" },
]

const MUSIC_VIBE_OPTIONS = [
  { value: "electronic", label: "Electronic" },
  { value: "hip-hop", label: "Hip Hop" },
  { value: "pop", label: "Pop" },
  { value: "rock", label: "Rock" },
  { value: "chill", label: "Chill" },
]

export default function WorkoutForm({ initialData, mode = "create" }: WorkoutFormProps) {
  const router = useRouter()
  const [isLoading, setIsLoading] = React.useState(false)
  const [errors, setErrors] = React.useState<Record<string, string>>({})
  const [trainers, setTrainers] = React.useState<{ id: string; name: string }[]>([])
  const [isLoadingTrainers, setIsLoadingTrainers] = React.useState(true)

  // Form state
  const [title, setTitle] = React.useState(initialData?.title || "")
  const [trainerId, setTrainerId] = React.useState(initialData?.trainer_id || "")
  const [category, setCategory] = React.useState(initialData?.category || "full-body")
  const [level, setLevel] = React.useState(initialData?.level || "Beginner")
  const [isFeatured, setIsFeatured] = React.useState(initialData?.is_featured || false)

  const [duration, setDuration] = React.useState(String(initialData?.duration || "4"))
  const [rounds, setRounds] = React.useState(String(initialData?.rounds || "8"))
  const [prepTime, setPrepTime] = React.useState(String(initialData?.prep_time || "10"))
  const [workTime, setWorkTime] = React.useState(String(initialData?.work_time || "20"))
  const [restTime, setRestTime] = React.useState(String(initialData?.rest_time || "10"))
  const [calories, setCalories] = React.useState(String(initialData?.calories || "45"))

  const [exercises, setExercises] = React.useState<Exercise[]>(
    initialData?.exercises?.length
      ? initialData.exercises
      : [{ name: "", duration: 20 }]
  )
  const [equipment, setEquipment] = React.useState<string[]>(initialData?.equipment || [])

  const [musicVibe, setMusicVibe] = React.useState(initialData?.music_vibe || "electronic")
  const [thumbnailUrl, setThumbnailUrl] = React.useState(initialData?.thumbnail_url || "")
  const [videoUrl, setVideoUrl] = React.useState(initialData?.video_url || "")

  // Load trainers
  React.useEffect(() => {
    const loadTrainers = async () => {
      try {
        const { data, error } = await supabase
          .from("trainers")
          .select("id, name")
          .order("name")

        if (error) throw error
        setTrainers(data || [])
      } catch (err) {
        console.error("Failed to load trainers:", err)
      } finally {
        setIsLoadingTrainers(false)
      }
    }

    loadTrainers()
  }, [])

  const trainerOptions = trainers.map((t) => ({ value: t.id, label: t.name }))

  const validate = () => {
    const newErrors: Record<string, string> = {}

    if (!title.trim()) newErrors.title = "Title is required"
    if (!trainerId) newErrors.trainer_id = "Trainer is required"
    if (!category) newErrors.category = "Category is required"
    if (!level) newErrors.level = "Level is required"
    if (!duration) newErrors.duration = "Duration is required"
    if (!rounds) newErrors.rounds = "Rounds is required"
    if (!prepTime) newErrors.prep_time = "Prep time is required"
    if (!workTime) newErrors.work_time = "Work time is required"
    if (!restTime) newErrors.rest_time = "Rest time is required"
    if (!calories) newErrors.calories = "Calories is required"
    if (!musicVibe) newErrors.music_vibe = "Music vibe is required"
    if (exercises.some((e) => !e.name.trim())) {
      newErrors.exercises = "All exercises must have a name"
    }

    setErrors(newErrors)
    return Object.keys(newErrors).length === 0
  }

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()

    if (!validate()) {
      return
    }

    setIsLoading(true)

    try {
      const workoutData = {
        title: title.trim(),
        trainer_id: trainerId,
        category: category as Workout["category"],
        level: level as Workout["level"],
        duration: parseInt(duration),
        rounds: parseInt(rounds),
        prep_time: parseInt(prepTime),
        work_time: parseInt(workTime),
        rest_time: parseInt(restTime),
        calories: parseInt(calories),
        equipment,
        exercises,
        music_vibe: musicVibe as Workout["music_vibe"],
        thumbnail_url: thumbnailUrl.trim() || null,
        video_url: videoUrl.trim() || null,
        is_featured: isFeatured,
      }

      let result
      if (mode === "edit" && initialData) {
        result = await (supabase.from("workouts") as any)
          .update(workoutData)
          .eq("id", initialData.id)
          .select()
          .single()
      } else {
        result = await (supabase.from("workouts") as any)
          .insert(workoutData)
          .select()
          .single()
      }

      if (result.error) throw result.error

      // If creating new workout and files were uploaded to temp folder, move them
      if (mode === "create" && result.data) {
        const moveResult = await moveFilesFromTempToWorkout(
          "temp",
          result.data.id,
          thumbnailUrl,
          videoUrl
        )

        // Update workout with new URLs if files were moved
        if (moveResult.thumbnail || moveResult.video) {
          const updateData: Partial<Workout> = {}
          if (moveResult.thumbnail) {
            updateData.thumbnail_url = moveResult.thumbnail.newUrl
          }
          if (moveResult.video) {
            updateData.video_url = moveResult.video.newUrl
          }

          if (Object.keys(updateData).length > 0) {
            await (supabase.from("workouts") as any)
              .update(updateData)
              .eq("id", result.data.id)
          }
        }

        // Show warnings if there were errors
        if (moveResult.errors.length > 0) {
          console.warn("Some files could not be moved:", moveResult.errors)
          // Optionally show a toast notification here
        }
      }

      toast.success(mode === "edit" ? "Workout updated" : "Workout created", {
        description: `"${title}" has been ${mode === "edit" ? "updated" : "created"} successfully.`
      })
      
      router.push(`/workouts/${result.data.id}`)
    } catch (err) {
      console.error("Failed to save workout:", err)
      toast.error("Failed to save workout. Please try again.")
    } finally {
      setIsLoading(false)
    }
  }

  const handleCancel = () => {
    if (mode === "edit" && initialData) {
      router.push(`/workouts/${initialData.id}`)
    } else {
      router.push("/workouts")
    }
  }

  return (
    <form onSubmit={handleSubmit} className="space-y-6">
      <Tabs defaultValue="basics" className="w-full">
        <TabsList className="grid w-full grid-cols-4 bg-neutral-900">
          <TabsTrigger value="basics" className="data-[state=active]:bg-neutral-800">
            Basics
          </TabsTrigger>
          <TabsTrigger value="timing" className="data-[state=active]:bg-neutral-800">
            Timing
          </TabsTrigger>
          <TabsTrigger value="content" className="data-[state=active]:bg-neutral-800">
            Content
          </TabsTrigger>
          <TabsTrigger value="media" className="data-[state=active]:bg-neutral-800">
            Media
          </TabsTrigger>
        </TabsList>

        {/* Tab 1: Basics */}
        <TabsContent value="basics" className="space-y-4">
          <div className="grid gap-4">
            <div className="space-y-2">
              <Label htmlFor="title">Workout Title *</Label>
              <Input
                id="title"
                value={title}
                onChange={(e) => setTitle(e.target.value)}
                placeholder="e.g., Full Body Ignite"
                className={cn(errors.title && "border-red-500")}
              />
              {errors.title && <p className="text-xs text-red-500">{errors.title}</p>}
            </div>

            <div className="space-y-2">
              <Label htmlFor="trainer">Trainer *</Label>
              {isLoadingTrainers ? (
                <div className="h-10 rounded-md border border-neutral-700 bg-neutral-900 px-3 py-2 text-sm text-neutral-500">
                  Loading trainers...
                </div>
              ) : (
                <>
                  <Select
                    id="trainer"
                    value={trainerId}
                    onValueChange={(value) => setTrainerId(value)}
                    options={trainerOptions}
                    placeholder="Select a trainer"
                  />
                  {errors.trainer_id && (
                    <p className="text-xs text-red-500">{errors.trainer_id}</p>
                  )}
                </>
              )}
            </div>

            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label htmlFor="category">Category *</Label>
                <Select
                  id="category"
                  value={category}
                  onValueChange={(value) => setCategory(value as typeof category)}
                  options={CATEGORY_OPTIONS}
                />
                {errors.category && <p className="text-xs text-red-500">{errors.category}</p>}
              </div>

              <div className="space-y-2">
                <Label htmlFor="level">Level *</Label>
                <Select
                  id="level"
                  value={level}
                  onValueChange={(value) => setLevel(value as typeof level)}
                  options={LEVEL_OPTIONS}
                />
                {errors.level && <p className="text-xs text-red-500">{errors.level}</p>}
              </div>
            </div>

            <div className="flex items-center justify-between rounded-lg border border-neutral-800 bg-neutral-900/50 p-4">
              <div className="space-y-0.5">
                <Label htmlFor="featured" className="text-base">
                  Featured Workout
                </Label>
                <p className="text-sm text-neutral-500">
                  Show this workout in the featured section
                </p>
              </div>
              <Switch id="featured" checked={isFeatured} onCheckedChange={setIsFeatured} />
            </div>
          </div>
        </TabsContent>

        {/* Tab 2: Timing */}
        <TabsContent value="timing" className="space-y-4">
          <div className="grid gap-4">
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label htmlFor="duration">Duration (minutes) *</Label>
                <Select
                  id="duration"
                  value={duration}
                  onValueChange={(value) => setDuration(value)}
                  options={DURATION_OPTIONS}
                />
                {errors.duration && <p className="text-xs text-red-500">{errors.duration}</p>}
              </div>

              <div className="space-y-2">
                <Label htmlFor="rounds">Total Rounds *</Label>
                <Input
                  id="rounds"
                  type="number"
                  value={rounds}
                  onChange={(e) => setRounds(e.target.value)}
                  min={1}
                  className={cn(errors.rounds && "border-red-500")}
                />
                {errors.rounds && <p className="text-xs text-red-500">{errors.rounds}</p>}
              </div>
            </div>

            <div className="grid grid-cols-3 gap-4">
              <div className="space-y-2">
                <Label htmlFor="prepTime">Prep Time (sec) *</Label>
                <Input
                  id="prepTime"
                  type="number"
                  value={prepTime}
                  onChange={(e) => setPrepTime(e.target.value)}
                  min={0}
                  className={cn(errors.prep_time && "border-red-500")}
                />
                {errors.prep_time && <p className="text-xs text-red-500">{errors.prep_time}</p>}
              </div>

              <div className="space-y-2">
                <Label htmlFor="workTime">Work Time (sec) *</Label>
                <Input
                  id="workTime"
                  type="number"
                  value={workTime}
                  onChange={(e) => setWorkTime(e.target.value)}
                  min={1}
                  className={cn(errors.work_time && "border-red-500")}
                />
                {errors.work_time && <p className="text-xs text-red-500">{errors.work_time}</p>}
              </div>

              <div className="space-y-2">
                <Label htmlFor="restTime">Rest Time (sec) *</Label>
                <Input
                  id="restTime"
                  type="number"
                  value={restTime}
                  onChange={(e) => setRestTime(e.target.value)}
                  min={0}
                  className={cn(errors.rest_time && "border-red-500")}
                />
                {errors.rest_time && <p className="text-xs text-red-500">{errors.rest_time}</p>}
              </div>
            </div>

            <div className="space-y-2">
              <Label htmlFor="calories">Estimated Calories *</Label>
              <Input
                id="calories"
                type="number"
                value={calories}
                onChange={(e) => setCalories(e.target.value)}
                min={0}
                placeholder="e.g., 45"
                className={cn(errors.calories && "border-red-500")}
              />
              {errors.calories && <p className="text-xs text-red-500">{errors.calories}</p>}
            </div>
          </div>
        </TabsContent>

        {/* Tab 3: Content */}
        <TabsContent value="content" className="space-y-4">
          <div className="space-y-4">
            <div className="space-y-2">
              <Label>Exercises *</Label>
              <p className="text-sm text-neutral-500">
                Add all exercises in order. Drag to reorder.
              </p>
              <ExerciseList
                value={exercises}
                onChange={setExercises}
                workTimeDefault={parseInt(workTime) || 20}
              />
              {errors.exercises && <p className="text-xs text-red-500">{errors.exercises}</p>}
            </div>

            <div className="space-y-2">
              <Label htmlFor="equipment">Equipment</Label>
              <p className="text-sm text-neutral-500">
                List all equipment needed (or leave empty for bodyweight)
              </p>
              <TagInput
                id="equipment"
                value={equipment}
                onChange={setEquipment}
                placeholder="Type equipment and press Enter..."
              />
            </div>
          </div>
        </TabsContent>

        {/* Tab 4: Media */}
        <TabsContent value="media" className="space-y-6">
          <div className="grid gap-6">
            <div className="space-y-2">
              <Label htmlFor="musicVibe">Music Vibe *</Label>
              <Select
                id="musicVibe"
                value={musicVibe}
                onValueChange={(value) => setMusicVibe(value as typeof musicVibe)}
                options={MUSIC_VIBE_OPTIONS}
              />
              {errors.music_vibe && <p className="text-xs text-red-500">{errors.music_vibe}</p>}
            </div>

            <div className="space-y-2">
              <Label>Thumbnail</Label>
              <MediaUpload
                type="thumbnail"
                workoutId={mode === "edit" && initialData ? initialData.id : undefined}
                value={thumbnailUrl}
                onChange={setThumbnailUrl}
                disabled={isLoading}
              />
              <p className="text-xs text-neutral-500">
                Upload a thumbnail image for this workout
              </p>
            </div>

            <div className="space-y-2">
              <Label>Video</Label>
              <MediaUpload
                type="video"
                workoutId={mode === "edit" && initialData ? initialData.id : undefined}
                value={videoUrl}
                onChange={setVideoUrl}
                disabled={isLoading}
              />
              <p className="text-xs text-neutral-500">
                Upload the workout video
              </p>
            </div>
          </div>
        </TabsContent>
      </Tabs>

      {/* Actions */}
      <div className="flex justify-end gap-3 pt-4 border-t border-neutral-800">
        <Button
          type="button"
          variant="outline"
          onClick={handleCancel}
          disabled={isLoading}
          className="border-neutral-700 text-neutral-400 hover:bg-neutral-800 hover:text-white"
        >
          <X className="mr-2 h-4 w-4" />
          Cancel
        </Button>
        <Button
          type="submit"
          disabled={isLoading}
          className="bg-orange-500 hover:bg-orange-600"
        >
          {isLoading ? (
            <>
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              Saving...
            </>
          ) : (
            <>
              <Save className="mr-2 h-4 w-4" />
              {mode === "edit" ? "Update Workout" : "Create Workout"}
            </>
          )}
        </Button>
      </div>
    </form>
  )
}
