"use client";

import { useState, useEffect } from "react";
import { useParams, useRouter } from "next/navigation";
import Link from "next/link";
import { formatSetsSummary } from "@/lib/formatSets";
import {
  ChevronLeft,
  Loader,
  Pencil,
  Trash2,
  Check,
  X,
  Dumbbell,
  TrendingUp,
  Calendar,
} from "lucide-react";
import { Exercise as PrismaExercise } from "@prisma/client";

// Extended type until Prisma client is regenerated with new fields
type Exercise = PrismaExercise & {
  inputFields?: string;
  defaultWeightUnit?: string | null;
};

const EXERCISE_TYPES = [
  "barbell",
  "dumbbell",
  "machine",
  "cable",
  "bodyweight",
  "cardio",
  "kettlebell",
  "other",
];

const MUSCLE_GROUPS = [
  "chest",
  "back",
  "shoulders",
  "quads",
  "hamstrings",
  "glutes",
  "biceps",
  "triceps",
  "forearms",
  "core",
  "calves",
  "full body",
  "cardio",
];

const INPUT_FIELD_OPTIONS = [
  { value: "sets", label: "Sets" },
  { value: "reps", label: "Reps" },
  { value: "weight", label: "Weight" },
  { value: "duration", label: "Duration" },
  { value: "distance", label: "Distance" },
  { value: "calories", label: "Calories" },
  { value: "watts", label: "Avg. watts" },
  { value: "notes", label: "Notes" },
];

interface WorkoutHistory {
  workout: { id: string; date: string; name: string | null };
  sets: Array<{
    id: string;
    setNumber: number;
    reps: number | null;
    weight: number | null;
    weightUnit: string;
    rpe: number | null;
    durationSeconds: number | null;
    distance: number | null;
    calories: number | null;
    notes: string | null;
  }>;
}

export default function ExerciseDetailPage() {
  const params = useParams();
  const router = useRouter();
  const exerciseId = params.id as string;

  const [exercise, setExercise] = useState<Exercise | null>(null);
  const [history, setHistory] = useState<WorkoutHistory[]>([]);
  const [loading, setLoading] = useState(true);
  const [editing, setEditing] = useState(false);
  const [saving, setSaving] = useState(false);
  const [deleting, setDeleting] = useState(false);

  // Edit form state
  const [editName, setEditName] = useState("");
  const [editType, setEditType] = useState("");
  const [editMuscleGroups, setEditMuscleGroups] = useState<string[]>([]);
  const [editInputFields, setEditInputFields] = useState<string[]>([]);
  const [editDefaultUnit, setEditDefaultUnit] = useState<string | null>(null);

  // Custom "+" add state
  const [addingType, setAddingType] = useState(false);
  const [newTypeText, setNewTypeText] = useState("");
  const [addingMuscle, setAddingMuscle] = useState(false);
  const [newMuscleText, setNewMuscleText] = useState("");
  const [addingField, setAddingField] = useState(false);
  const [newFieldText, setNewFieldText] = useState("");
  const [customTypes, setCustomTypes] = useState<string[]>([]);
  const [customMuscles, setCustomMuscles] = useState<string[]>([]);
  const [customFields, setCustomFields] = useState<{ value: string; label: string }[]>([]);

  useEffect(() => {
    fetchExercise();
  }, [exerciseId]);

  const fetchExercise = async () => {
    try {
      const res = await fetch(`/api/exercises/${exerciseId}`);
      if (!res.ok) throw new Error("Not found");
      const data = await res.json();
      setExercise(data.exercise);
      setHistory(data.history || []);

      // Populate edit form
      setEditName(data.exercise.name);
      setEditType(data.exercise.type);
      const mg = JSON.parse(data.exercise.muscleGroups || "[]") as string[];
      setEditMuscleGroups(mg);
      const ifs = JSON.parse(data.exercise.inputFields || '["sets","reps","weight"]') as string[];
      setEditInputFields(ifs);
      setEditDefaultUnit(data.exercise.defaultWeightUnit);

      // Detect custom values not in default lists
      const knownTypes = EXERCISE_TYPES;
      if (!knownTypes.includes(data.exercise.type)) {
        setCustomTypes((prev) => prev.includes(data.exercise.type) ? prev : [...prev, data.exercise.type]);
      }
      const knownMuscles = MUSCLE_GROUPS;
      mg.forEach((m: string) => {
        if (!knownMuscles.includes(m)) {
          setCustomMuscles((prev) => prev.includes(m) ? prev : [...prev, m]);
        }
      });
      const knownFields = INPUT_FIELD_OPTIONS.map((f) => f.value);
      ifs.forEach((f: string) => {
        if (!knownFields.includes(f)) {
          setCustomFields((prev) =>
            prev.some((cf) => cf.value === f)
              ? prev
              : [...prev, { value: f, label: f.charAt(0).toUpperCase() + f.slice(1) }]
          );
        }
      });
    } catch (err) {
      console.error(err);
    } finally {
      setLoading(false);
    }
  };

  const handleSave = async () => {
    setSaving(true);
    try {
      const res = await fetch(`/api/exercises/${exerciseId}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          name: editName,
          type: editType,
          muscleGroups: editMuscleGroups,
          inputFields: editInputFields,
          defaultWeightUnit: editDefaultUnit,
        }),
      });
      if (!res.ok) throw new Error("Failed to save");
      const updated = await res.json();
      setExercise(updated);
      setEditing(false);
    } catch (err) {
      console.error(err);
      alert("Failed to save changes");
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async () => {
    if (!confirm("Delete this exercise and all its history?")) return;
    setDeleting(true);
    try {
      const res = await fetch(`/api/exercises/${exerciseId}`, {
        method: "DELETE",
      });
      if (!res.ok) throw new Error("Failed to delete");
      router.push("/main/exercises");
    } catch (err) {
      console.error(err);
      alert("Failed to delete exercise");
      setDeleting(false);
    }
  };

  const toggleMuscleGroup = (group: string) => {
    setEditMuscleGroups((prev) =>
      prev.includes(group) ? prev.filter((g) => g !== group) : [...prev, group]
    );
  };

  const toggleInputField = (field: string) => {
    setEditInputFields((prev) =>
      prev.includes(field)
        ? prev.filter((f) => f !== field)
        : [...prev, field]
    );
  };

  if (loading) {
    return (
      <div className="min-h-screen bg-[#0A0A0A] flex items-center justify-center">
        <Loader className="w-8 h-8 animate-spin text-zinc-500" />
      </div>
    );
  }

  if (!exercise) {
    return (
      <div className="min-h-screen bg-[#0A0A0A] p-6">
        <Link
          href="/main/exercises"
          className="text-zinc-400 hover:text-white flex items-center gap-1 mb-4"
        >
          <ChevronLeft className="w-5 h-5" />
          Back
        </Link>
        <p className="text-zinc-500">Exercise not found</p>
      </div>
    );
  }

  const muscleGroups = JSON.parse(exercise.muscleGroups || "[]") as string[];
  const inputFields = JSON.parse(
    exercise.inputFields || '["sets","reps","weight"]'
  ) as string[];

  return (
    <div className="min-h-screen bg-[#0A0A0A]">
      {/* Header */}
      <div className="border-b border-zinc-800 px-4 py-4">
        <div className="max-w-2xl mx-auto flex items-center gap-4">
          <Link
            href="/main/exercises"
            className="p-2 hover:bg-zinc-900 rounded-lg text-zinc-400 hover:text-white"
          >
            <ChevronLeft className="w-6 h-6" />
          </Link>
          <h1 className="text-xl font-bold text-white flex-1 truncate">
            {exercise.name}
          </h1>
          {!editing && (
            <div className="flex items-center gap-2">
              <button
                onClick={() => setEditing(true)}
                className="p-2 hover:bg-zinc-900 rounded-lg text-zinc-400 hover:text-white"
              >
                <Pencil className="w-5 h-5" />
              </button>
              <button
                onClick={handleDelete}
                disabled={deleting}
                className="p-2 hover:bg-zinc-900 rounded-lg text-red-500 hover:text-red-400 disabled:opacity-50"
              >
                <Trash2 className="w-5 h-5" />
              </button>
            </div>
          )}
        </div>
      </div>

      <div className="max-w-2xl mx-auto px-4 py-6 space-y-6">
        {/* Edit Mode */}
        {editing ? (
          <div className="bg-zinc-900 border border-zinc-800 rounded-lg p-6 space-y-5">
            <div>
              <label className="block text-xs font-medium text-zinc-400 uppercase tracking-wider mb-2">
                Name
              </label>
              <input
                value={editName}
                onChange={(e) => setEditName(e.target.value)}
                className="w-full px-4 py-3 bg-zinc-800 border border-zinc-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-white/20"
              />
            </div>

            <div>
              <label className="block text-xs font-medium text-zinc-400 uppercase tracking-wider mb-2">
                Equipment
              </label>
              <div className="flex flex-wrap gap-2">
                {[...EXERCISE_TYPES, ...customTypes].map((type) => (
                  <button
                    key={type}
                    onClick={() => setEditType(type)}
                    className={`px-3 py-1.5 rounded-lg text-sm font-medium transition ${
                      editType === type
                        ? "bg-white text-black"
                        : "bg-zinc-800 text-zinc-400 hover:text-white"
                    }`}
                  >
                    {type.charAt(0).toUpperCase() + type.slice(1)}
                  </button>
                ))}
                {addingType ? (
                  <form
                    onSubmit={(e) => {
                      e.preventDefault();
                      const val = newTypeText.trim().toLowerCase();
                      if (val && !EXERCISE_TYPES.includes(val) && !customTypes.includes(val)) {
                        setCustomTypes((p) => [...p, val]);
                        setEditType(val);
                      }
                      setNewTypeText("");
                      setAddingType(false);
                    }}
                    className="flex items-center gap-1"
                  >
                    <input
                      autoFocus
                      value={newTypeText}
                      onChange={(e) => setNewTypeText(e.target.value)}
                      onBlur={() => {
                        const val = newTypeText.trim().toLowerCase();
                        if (val && !EXERCISE_TYPES.includes(val) && !customTypes.includes(val)) {
                          setCustomTypes((p) => [...p, val]);
                          setEditType(val);
                        }
                        setNewTypeText("");
                        setAddingType(false);
                      }}
                      placeholder="New type"
                      className="w-24 px-2 py-1.5 bg-zinc-800 border border-zinc-600 rounded-lg text-sm text-white focus:outline-none focus:ring-1 focus:ring-white/30"
                    />
                  </form>
                ) : (
                  <button
                    type="button"
                    onClick={() => setAddingType(true)}
                    className="px-2.5 py-1.5 rounded-lg text-sm font-medium bg-zinc-800 text-zinc-500 hover:text-white border border-dashed border-zinc-600 transition"
                  >
                    +
                  </button>
                )}
              </div>
            </div>

            <div>
              <label className="block text-xs font-medium text-zinc-400 uppercase tracking-wider mb-2">
                Muscle Groups
              </label>
              <div className="flex flex-wrap gap-2">
                {[...MUSCLE_GROUPS, ...customMuscles].map((group) => (
                  <button
                    key={group}
                    onClick={() => toggleMuscleGroup(group)}
                    className={`px-3 py-1.5 rounded-lg text-sm font-medium transition ${
                      editMuscleGroups.includes(group)
                        ? "bg-white text-black"
                        : "bg-zinc-800 text-zinc-400 hover:text-white"
                    }`}
                  >
                    {group.charAt(0).toUpperCase() + group.slice(1)}
                  </button>
                ))}
                {addingMuscle ? (
                  <form
                    onSubmit={(e) => {
                      e.preventDefault();
                      const val = newMuscleText.trim().toLowerCase();
                      if (val && !MUSCLE_GROUPS.includes(val) && !customMuscles.includes(val)) {
                        setCustomMuscles((p) => [...p, val]);
                      }
                      if (val && !editMuscleGroups.includes(val)) {
                        setEditMuscleGroups((p) => [...p, val]);
                      }
                      setNewMuscleText("");
                      setAddingMuscle(false);
                    }}
                    className="flex items-center gap-1"
                  >
                    <input
                      autoFocus
                      value={newMuscleText}
                      onChange={(e) => setNewMuscleText(e.target.value)}
                      onBlur={() => {
                        const val = newMuscleText.trim().toLowerCase();
                        if (val && !MUSCLE_GROUPS.includes(val) && !customMuscles.includes(val)) {
                          setCustomMuscles((p) => [...p, val]);
                        }
                        if (val && !editMuscleGroups.includes(val)) {
                          setEditMuscleGroups((p) => [...p, val]);
                        }
                        setNewMuscleText("");
                        setAddingMuscle(false);
                      }}
                      placeholder="New group"
                      className="w-24 px-2 py-1.5 bg-zinc-800 border border-zinc-600 rounded-lg text-sm text-white focus:outline-none focus:ring-1 focus:ring-white/30"
                    />
                  </form>
                ) : (
                  <button
                    type="button"
                    onClick={() => setAddingMuscle(true)}
                    className="px-2.5 py-1.5 rounded-lg text-sm font-medium bg-zinc-800 text-zinc-500 hover:text-white border border-dashed border-zinc-600 transition"
                  >
                    +
                  </button>
                )}
              </div>
            </div>

            <div>
              <label className="block text-xs font-medium text-zinc-400 uppercase tracking-wider mb-2">
                Input Fields
              </label>
              <p className="text-xs text-zinc-600 mb-2">
                Choose which fields are relevant when logging this exercise
              </p>
              <div className="flex flex-wrap gap-2">
                {[...INPUT_FIELD_OPTIONS, ...customFields].map((field) => (
                  <button
                    key={field.value}
                    onClick={() => toggleInputField(field.value)}
                    className={`px-3 py-1.5 rounded-lg text-sm font-medium transition ${
                      editInputFields.includes(field.value)
                        ? "bg-white text-black"
                        : "bg-zinc-800 text-zinc-400 hover:text-white"
                    }`}
                  >
                    {field.label}
                  </button>
                ))}
                {addingField ? (
                  <form
                    onSubmit={(e) => {
                      e.preventDefault();
                      const val = newFieldText.trim().toLowerCase();
                      if (
                        val &&
                        !INPUT_FIELD_OPTIONS.some((f) => f.value === val) &&
                        !customFields.some((f) => f.value === val)
                      ) {
                        setCustomFields((p) => [
                          ...p,
                          { value: val, label: val.charAt(0).toUpperCase() + val.slice(1) },
                        ]);
                      }
                      if (val && !editInputFields.includes(val)) {
                        setEditInputFields((p) => [...p, val]);
                      }
                      setNewFieldText("");
                      setAddingField(false);
                    }}
                    className="flex items-center gap-1"
                  >
                    <input
                      autoFocus
                      value={newFieldText}
                      onChange={(e) => setNewFieldText(e.target.value)}
                      onBlur={() => {
                        const val = newFieldText.trim().toLowerCase();
                        if (
                          val &&
                          !INPUT_FIELD_OPTIONS.some((f) => f.value === val) &&
                          !customFields.some((f) => f.value === val)
                        ) {
                          setCustomFields((p) => [
                            ...p,
                            { value: val, label: val.charAt(0).toUpperCase() + val.slice(1) },
                          ]);
                        }
                        if (val && !editInputFields.includes(val)) {
                          setEditInputFields((p) => [...p, val]);
                        }
                        setNewFieldText("");
                        setAddingField(false);
                      }}
                      placeholder="New field"
                      className="w-24 px-2 py-1.5 bg-zinc-800 border border-zinc-600 rounded-lg text-sm text-white focus:outline-none focus:ring-1 focus:ring-white/30"
                    />
                  </form>
                ) : (
                  <button
                    type="button"
                    onClick={() => setAddingField(true)}
                    className="px-2.5 py-1.5 rounded-lg text-sm font-medium bg-zinc-800 text-zinc-500 hover:text-white border border-dashed border-zinc-600 transition"
                  >
                    +
                  </button>
                )}
              </div>
            </div>

            <div>
              <label className="block text-xs font-medium text-zinc-400 uppercase tracking-wider mb-2">
                Default Weight Unit
              </label>
              <div className="flex gap-2">
                {[
                  { value: null, label: "User Default" },
                  { value: "lbs", label: "Pounds" },
                  { value: "kg", label: "Kilograms" },
                ].map((opt) => (
                  <button
                    key={opt.label}
                    onClick={() => setEditDefaultUnit(opt.value)}
                    className={`px-3 py-1.5 rounded-lg text-sm font-medium transition ${
                      editDefaultUnit === opt.value
                        ? "bg-white text-black"
                        : "bg-zinc-800 text-zinc-400 hover:text-white"
                    }`}
                  >
                    {opt.label}
                  </button>
                ))}
              </div>
            </div>

            <div className="flex gap-3 pt-2">
              <button
                onClick={handleSave}
                disabled={saving}
                className="flex-1 py-3 bg-white text-black font-bold rounded-lg hover:bg-zinc-200 disabled:opacity-50 flex items-center justify-center gap-2"
              >
                {saving ? (
                  <Loader className="w-5 h-5 animate-spin" />
                ) : (
                  <Check className="w-5 h-5" />
                )}
                Save
              </button>
              <button
                onClick={() => setEditing(false)}
                className="flex-1 py-3 bg-zinc-800 text-white font-medium rounded-lg hover:bg-zinc-700 flex items-center justify-center gap-2"
              >
                <X className="w-5 h-5" />
                Cancel
              </button>
            </div>
          </div>
        ) : (
          /* View Mode */
          <div className="bg-zinc-900 border border-zinc-800 rounded-lg p-6">
            <div className="flex items-start gap-4 mb-4">
              <div className="bg-zinc-800 p-3 rounded-lg">
                <Dumbbell className="w-6 h-6 text-zinc-400" />
              </div>
              <div className="flex-1">
                <h2 className="text-xl font-bold text-white">
                  {exercise.name}
                </h2>
                <span className="inline-block mt-1 px-2 py-0.5 bg-zinc-800 text-zinc-300 rounded text-xs font-medium">
                  {exercise.type.charAt(0).toUpperCase() +
                    exercise.type.slice(1)}
                </span>
              </div>
            </div>

            {muscleGroups.length > 0 && (
              <div className="flex flex-wrap gap-2 mb-4">
                {muscleGroups.map((group) => (
                  <span
                    key={group}
                    className="px-2 py-1 bg-zinc-800 text-zinc-400 rounded text-xs"
                  >
                    {group.charAt(0).toUpperCase() + group.slice(1)}
                  </span>
                ))}
              </div>
            )}

            <div className="border-t border-zinc-800 pt-4 mt-4">
              <p className="text-xs text-zinc-500 uppercase tracking-wider mb-2">
                Tracked Fields
              </p>
              <div className="flex flex-wrap gap-2">
                {inputFields.map((field) => (
                  <span
                    key={field}
                    className="px-2 py-1 bg-zinc-800 text-zinc-300 rounded text-xs font-medium"
                  >
                    {field.charAt(0).toUpperCase() + field.slice(1)}
                  </span>
                ))}
              </div>
            </div>

            {exercise.defaultWeightUnit && (
              <p className="text-xs text-zinc-500 mt-3">
                Default unit:{" "}
                <span className="text-zinc-300">
                  {exercise.defaultWeightUnit}
                </span>
              </p>
            )}
          </div>
        )}

        {/* History */}
        <div>
          <h3 className="text-lg font-bold text-white mb-4 flex items-center gap-2">
            <Calendar className="w-5 h-5 text-zinc-400" />
            History
          </h3>

          {history.length === 0 ? (
            <div className="bg-zinc-900 border border-zinc-800 rounded-lg p-8 text-center">
              <TrendingUp className="w-10 h-10 text-zinc-700 mx-auto mb-3" />
              <p className="text-zinc-500">No history yet</p>
              <p className="text-zinc-600 text-sm mt-1">
                Start logging this exercise to see your progress
              </p>
            </div>
          ) : (
            <div className="space-y-1">
              {history.map((entry) => {
                const summary = formatSetsSummary(
                  entry.sets.map((s: any) => ({ weight: s.weight, reps: s.reps, weightUnit: s.weightUnit }))
                );
                const dateStr = new Date(entry.workout.date).toLocaleDateString(
                  "en-US",
                  { month: "short", day: "numeric" }
                );
                return (
                  <Link
                    key={entry.workout.id}
                    href={`/main/workouts/${entry.workout.id}`}
                    className="flex items-baseline gap-2 px-3 py-1.5 rounded-md hover:bg-zinc-800/60 transition"
                  >
                    <span className="text-xs text-zinc-500 flex-shrink-0 tabular-nums">
                      {dateStr}
                    </span>
                    <span className="text-xs text-zinc-600 flex-shrink-0">·</span>
                    <span className="text-xs text-zinc-500 flex-shrink-0">
                      {entry.sets.length} {entry.sets.length === 1 ? "set" : "sets"}
                    </span>
                    {summary && (
                      <>
                        <span className="text-xs text-zinc-600 flex-shrink-0">·</span>
                        <span className="text-sm text-zinc-300 truncate">
                          {summary}
                        </span>
                      </>
                    )}
                  </Link>
                );
              })}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
