"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 { Textarea } from "@/components/ui/textarea"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Select } from "@/components/ui/select"
import { Switch } from "@/components/ui/switch"
import TabataEditor, { TabataData } from "@/components/tabata-editor"
import { toast } from "sonner"
import type { Database } from "@/lib/supabase"

type WorkoutProgram = Database["public"]["Tables"]["workout_programs"]["Row"]
type ProgramTabata = Database["public"]["Tables"]["program_tabatas"]["Row"]

interface ProgramFormProps {
  initialData?: WorkoutProgram & { tabatas?: ProgramTabata[] }
  mode?: "create" | "edit"
}

const BODY_ZONE_OPTIONS = [
  { value: "upper-body", label: "Upper Body" },
  { value: "lower-body", label: "Lower Body" },
  { value: "full-body", label: "Full Body" },
]

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

export default function ProgramForm({ initialData, mode = "create" }: ProgramFormProps) {
  const router = useRouter()
  const [isLoading, setIsLoading] = React.useState(false)
  const [errors, setErrors] = React.useState<Record<string, string>>({})

  // Basics state
  const [title, setTitle] = React.useState(initialData?.title || "")
  const [description, setDescription] = React.useState(initialData?.description || "")
  const [bodyZone, setBodyZone] = React.useState(initialData?.body_zone || "full-body")
  const [level, setLevel] = React.useState(initialData?.level || "Beginner")
  const [isFree, setIsFree] = React.useState(initialData?.is_free || false)
  const [estimatedCalories, setEstimatedCalories] = React.useState(
    String(initialData?.estimated_calories || "")
  )
  const [icon, setIcon] = React.useState(initialData?.icon || "")
  const [accentColor, setAccentColor] = React.useState(initialData?.accent_color || "")
  const [sortOrder, setSortOrder] = React.useState(
    String(initialData?.sort_order ?? "0")
  )

  // Tabatas state
  const [tabatas, setTabatas] = React.useState<TabataData[]>(() => {
    if (initialData?.tabatas && initialData.tabatas.length > 0) {
      return initialData.tabatas
        .sort((a, b) => a.position - b.position)
        .map((t) => ({
          position: t.position,
          exercise_1_name: t.exercise_1_name || "",
          exercise_1_name_en: t.exercise_1_name_en || "",
          exercise_1_tip: t.exercise_1_tip || "",
          exercise_1_tip_en: t.exercise_1_tip_en || "",
          exercise_1_modification: t.exercise_1_modification || "",
          exercise_1_modification_en: t.exercise_1_modification_en || "",
          exercise_1_progression: t.exercise_1_progression || "",
          exercise_1_progression_en: t.exercise_1_progression_en || "",
          exercise_2_name: t.exercise_2_name || "",
          exercise_2_name_en: t.exercise_2_name_en || "",
          exercise_2_tip: t.exercise_2_tip || "",
          exercise_2_tip_en: t.exercise_2_tip_en || "",
          exercise_2_modification: t.exercise_2_modification || "",
          exercise_2_modification_en: t.exercise_2_modification_en || "",
          exercise_2_progression: t.exercise_2_progression || "",
          exercise_2_progression_en: t.exercise_2_progression_en || "",
          rounds: t.rounds || 8,
          work_time: t.work_time || 20,
          rest_time: t.rest_time || 10,
        }))
    }
    return [
      { position: 1, exercise_1_name: "", exercise_1_name_en: "", exercise_1_tip: "", exercise_1_tip_en: "", exercise_1_modification: "", exercise_1_modification_en: "", exercise_1_progression: "", exercise_1_progression_en: "", exercise_2_name: "", exercise_2_name_en: "", exercise_2_tip: "", exercise_2_tip_en: "", exercise_2_modification: "", exercise_2_modification_en: "", exercise_2_progression: "", exercise_2_progression_en: "", rounds: 8, work_time: 20, rest_time: 10 },
      { position: 2, exercise_1_name: "", exercise_1_name_en: "", exercise_1_tip: "", exercise_1_tip_en: "", exercise_1_modification: "", exercise_1_modification_en: "", exercise_1_progression: "", exercise_1_progression_en: "", exercise_2_name: "", exercise_2_name_en: "", exercise_2_tip: "", exercise_2_tip_en: "", exercise_2_modification: "", exercise_2_modification_en: "", exercise_2_progression: "", exercise_2_progression_en: "", rounds: 8, work_time: 20, rest_time: 10 },
      { position: 3, exercise_1_name: "", exercise_1_name_en: "", exercise_1_tip: "", exercise_1_tip_en: "", exercise_1_modification: "", exercise_1_modification_en: "", exercise_1_progression: "", exercise_1_progression_en: "", exercise_2_name: "", exercise_2_name_en: "", exercise_2_tip: "", exercise_2_tip_en: "", exercise_2_modification: "", exercise_2_modification_en: "", exercise_2_progression: "", exercise_2_progression_en: "", rounds: 8, work_time: 20, rest_time: 10 },
    ]
  })

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

    if (!title.trim()) newErrors.title = "Title is required"

    tabatas.forEach((tabata, i) => {
      if (!tabata.exercise_1_name.trim()) {
        newErrors[`tabata_${i + 1}_ex1`] = `Tabata ${i + 1}: Exercise 1 name is required`
      }
      if (!tabata.exercise_2_name.trim()) {
        newErrors[`tabata_${i + 1}_ex2`] = `Tabata ${i + 1}: Exercise 2 name is required`
      }
    })

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

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

    if (!validate()) {
      return
    }

    setIsLoading(true)

    try {
      // Calculate total estimated duration from tabatas
      const totalSeconds = tabatas.reduce(
        (sum, t) => sum + t.rounds * (t.work_time + t.rest_time),
        0
      )
      const estimatedDuration = Math.ceil(totalSeconds / 60)

      const programData = {
        title: title.trim(),
        description: description.trim(),
        body_zone: bodyZone as WorkoutProgram["body_zone"],
        level: level as WorkoutProgram["level"],
        is_free: isFree,
        estimated_duration: estimatedDuration,
        estimated_calories: parseInt(estimatedCalories) || 0,
        icon: icon.trim() || null,
        accent_color: accentColor.trim() || null,
        sort_order: parseInt(sortOrder) || 0,
      }

      let programId: string

      if (mode === "edit" && initialData) {
        const result = await (supabase.from("workout_programs") as any)
          .update(programData)
          .eq("id", initialData.id)
          .select()
          .single()

        if (result.error) throw result.error
        programId = initialData.id
      } else {
        const result = await (supabase.from("workout_programs") as any)
          .insert(programData)
          .select()
          .single()

        if (result.error) throw result.error
        programId = result.data.id
      }

      // Upsert tabatas
      for (const tabata of tabatas) {
        const tabataPayload = {
          program_id: programId,
          position: tabata.position,
          exercise_1_name: tabata.exercise_1_name.trim(),
          exercise_1_name_en: tabata.exercise_1_name_en.trim() || null,
          exercise_1_tip: tabata.exercise_1_tip.trim() || null,
          exercise_1_tip_en: tabata.exercise_1_tip_en.trim() || null,
          exercise_1_modification: tabata.exercise_1_modification.trim() || null,
          exercise_1_modification_en: tabata.exercise_1_modification_en.trim() || null,
          exercise_1_progression: tabata.exercise_1_progression.trim() || null,
          exercise_1_progression_en: tabata.exercise_1_progression_en.trim() || null,
          exercise_2_name: tabata.exercise_2_name.trim(),
          exercise_2_name_en: tabata.exercise_2_name_en.trim() || null,
          exercise_2_tip: tabata.exercise_2_tip.trim() || null,
          exercise_2_tip_en: tabata.exercise_2_tip_en.trim() || null,
          exercise_2_modification: tabata.exercise_2_modification.trim() || null,
          exercise_2_modification_en: tabata.exercise_2_modification_en.trim() || null,
          exercise_2_progression: tabata.exercise_2_progression.trim() || null,
          exercise_2_progression_en: tabata.exercise_2_progression_en.trim() || null,
          rounds: tabata.rounds,
          work_time: tabata.work_time,
          rest_time: tabata.rest_time,
        }

        // In edit mode, check if tabata exists for this position
        if (mode === "edit") {
          const existing = initialData?.tabatas?.find((t) => t.position === tabata.position)
          if (existing) {
            const { error } = await (supabase.from("program_tabatas") as any)
              .update(tabataPayload)
              .eq("id", existing.id)
            if (error) throw error
          } else {
            const { error } = await (supabase.from("program_tabatas") as any)
              .insert(tabataPayload)
            if (error) throw error
          }
        } else {
          const { error } = await (supabase.from("program_tabatas") as any)
            .insert(tabataPayload)
          if (error) throw error
        }
      }

      toast.success(mode === "edit" ? "Program updated" : "Program created", {
        description: `"${title}" has been ${mode === "edit" ? "updated" : "created"} successfully.`
      })

      router.push(`/programs/${programId}`)
    } catch (err) {
      console.error("Failed to save program:", err)
      toast.error("Failed to save program. Please try again.")
    } finally {
      setIsLoading(false)
    }
  }

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

  const handleTabataChange = (position: number, data: TabataData) => {
    setTabatas((prev) =>
      prev.map((t) => (t.position === position ? { ...data, position } : t))
    )
  }

  return (
    <form onSubmit={handleSubmit} className="space-y-6">
      <Tabs defaultValue="basics" className="w-full">
        <TabsList className="grid w-full grid-cols-2 bg-neutral-900">
          <TabsTrigger value="basics" className="data-[state=active]:bg-neutral-800">
            Basics
          </TabsTrigger>
          <TabsTrigger value="tabatas" className="data-[state=active]:bg-neutral-800">
            Tabatas
          </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">Program Title *</Label>
              <Input
                id="title"
                value={title}
                onChange={(e) => setTitle(e.target.value)}
                placeholder="e.g., Full Body Blast"
                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="description">Description</Label>
              <Textarea
                id="description"
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                placeholder="Describe this program..."
                rows={3}
              />
            </div>

            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label htmlFor="bodyZone">Body Zone *</Label>
                <Select
                  id="bodyZone"
                  value={bodyZone}
                  onValueChange={(value) => setBodyZone(value as typeof bodyZone)}
                  options={BODY_ZONE_OPTIONS}
                />
              </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}
                />
              </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="isFree" className="text-base">
                  Free Program
                </Label>
                <p className="text-sm text-neutral-500">
                  Make this program available to free users
                </p>
              </div>
              <Switch id="isFree" checked={isFree} onCheckedChange={setIsFree} />
            </div>

            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label htmlFor="estimatedCalories">Estimated Calories</Label>
                <Input
                  id="estimatedCalories"
                  type="number"
                  value={estimatedCalories}
                  onChange={(e) => setEstimatedCalories(e.target.value)}
                  min={0}
                  placeholder="e.g., 120"
                />
              </div>

              <div className="space-y-2">
                <Label htmlFor="sortOrder">Sort Order</Label>
                <Input
                  id="sortOrder"
                  type="number"
                  value={sortOrder}
                  onChange={(e) => setSortOrder(e.target.value)}
                  min={0}
                  placeholder="0"
                />
              </div>
            </div>

            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label htmlFor="icon">Icon Name</Label>
                <Input
                  id="icon"
                  value={icon}
                  onChange={(e) => setIcon(e.target.value)}
                  placeholder="e.g., flame, dumbbell"
                />
              </div>

              <div className="space-y-2">
                <Label htmlFor="accentColor">Accent Color</Label>
                <div className="flex gap-2">
                  <Input
                    id="accentColor"
                    value={accentColor}
                    onChange={(e) => setAccentColor(e.target.value)}
                    placeholder="#FF6B35"
                    className="flex-1"
                  />
                  {accentColor && (
                    <div
                      className="h-10 w-10 rounded-md border border-neutral-700 flex-shrink-0"
                      style={{ backgroundColor: accentColor }}
                    />
                  )}
                </div>
              </div>
            </div>
          </div>
        </TabsContent>

        {/* Tab 2: Tabatas */}
        <TabsContent value="tabatas" className="space-y-4">
          <div className="space-y-1 mb-4">
            <p className="text-sm text-neutral-500">
              Each program has 3 tabatas (exercise pairs). Every tabata alternates between two exercises for the specified number of rounds.
            </p>
          </div>

          {errors.tabata_1_ex1 && (
            <p className="text-xs text-red-500 bg-red-500/10 px-3 py-2 rounded-md">
              {errors.tabata_1_ex1}
            </p>
          )}
          {errors.tabata_1_ex2 && (
            <p className="text-xs text-red-500 bg-red-500/10 px-3 py-2 rounded-md">
              {errors.tabata_1_ex2}
            </p>
          )}

          {([1, 2, 3] as const).map((pos) => {
            const tabata = tabatas.find((t) => t.position === pos) || null
            return (
              <TabataEditor
                key={pos}
                tabata={tabata}
                position={pos}
                onChange={(data) => handleTabataChange(pos, data)}
              />
            )
          })}
        </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 Program" : "Create Program"}
            </>
          )}
        </Button>
      </div>
    </form>
  )
}
