import React, { useMemo, useState } from "react";
import { motion } from "framer-motion";
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 { Checkbox } from "@/components/ui/checkbox";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Separator } from "@/components/ui/separator";
import { AlertCircle, CheckCircle2, Dumbbell, FileDown, ShieldAlert } from "lucide-react";

type EquipmentKey = "gym" | "bands" | "freeWeights" | "bodyWeight";
type FmsKey =
  | "deepSquat"
  | "hurdleStep"
  | "inlineLunge"
  | "shoulderMobility"
  | "activeStraightLegRaise"
  | "trunkStabilityPushUp"
  | "rotaryStability";
type ContraKey =
  | "highBloodPressure"
  | "cardiacHistory"
  | "lowBackPain"
  | "shoulderPain"
  | "kneePain"
  | "anklePain"
  | "pregnant"
  | "postSurgery"
  | "otherMedical";
type JointKey =
  | "footAnkle"
  | "knee"
  | "hip"
  | "lumbar"
  | "thoracic"
  | "cervical"
  | "shoulder"
  | "elbowWrist";

type Intake = {
  clientName: string;
  trainerName: string;
  age: string;
  sex: string;
  weightKg: string;
  heightCm: string;
  bodyFat: string;
  goal: string;
  trainingAge: string;
  frequencyPerWeek: string;
  sessionDurationMin: string;
  healthHistory: string;
  currentMedications: string;
  injuryNotes: string;
  equipment: Record<EquipmentKey, boolean>;
  contraindications: Record<ContraKey, boolean>;
  kineticChain: Record<JointKey, string>;
  fms: Record<FmsKey, number>;
  clearingTests: {
    shoulderPainWithClearing: boolean;
    extensionPainWithClearing: boolean;
    flexionPainWithClearing: boolean;
    rotaryPainWithClearing: boolean;
  };
};

type SubmissionPayload = {
  intake: Intake;
  rules: {
    training_less_than_3_days_is_total_body: boolean;
    include_all_7_patterns: boolean;
    include_primary_and_assistance_exercises: boolean;
    pdf_only_output: boolean;
    deload_every_6_to_8_weeks: boolean;
    progress_supported_to_integrated_then_more_closed_chain_when_tolerated: boolean;
  };
};

const APP_CONFIG = {
  appName: "Program Designer",
  organizationName: "The Fitclub Academy",
  apiBaseUrl: "/api/generate-program-pdf",
  pdfFilenamePrefix: "training-program",
};

const equipmentLabels: Record<EquipmentKey, string> = {
  gym: "Gym Machines",
  bands: "Resistance Bands",
  freeWeights: "Free Weights",
  bodyWeight: "Body Weight",
};

const contraLabels: Record<ContraKey, string> = {
  highBloodPressure: "High Blood Pressure",
  cardiacHistory: "Cardiac History",
  lowBackPain: "Low Back Pain",
  shoulderPain: "Shoulder Pain",
  kneePain: "Knee Pain",
  anklePain: "Ankle Pain",
  pregnant: "Pregnancy",
  postSurgery: "Post Surgery",
  otherMedical: "Other Medical Concern",
};

const jointLabels: Record<JointKey, string> = {
  footAnkle: "Foot / Ankle",
  knee: "Knee",
  hip: "Hip",
  lumbar: "Lumbar Spine",
  thoracic: "Thoracic Spine",
  cervical: "Cervical Spine",
  shoulder: "Shoulder",
  elbowWrist: "Elbow / Wrist",
};

const fmsFields: { key: FmsKey; label: string }[] = [
  { key: "deepSquat", label: "Deep Squat" },
  { key: "hurdleStep", label: "Hurdle Step" },
  { key: "inlineLunge", label: "Inline Lunge" },
  { key: "shoulderMobility", label: "Shoulder Mobility" },
  { key: "activeStraightLegRaise", label: "ASLR" },
  { key: "trunkStabilityPushUp", label: "Trunk Stability Push-Up" },
  { key: "rotaryStability", label: "Rotary Stability" },
];

const defaultIntake: Intake = {
  clientName: "",
  trainerName: "",
  age: "",
  sex: "",
  weightKg: "",
  heightCm: "",
  bodyFat: "",
  goal: "General fitness and movement quality",
  trainingAge: "beginner",
  frequencyPerWeek: "3",
  sessionDurationMin: "60",
  healthHistory: "",
  currentMedications: "",
  injuryNotes: "",
  equipment: { gym: true, bands: true, freeWeights: true, bodyWeight: true },
  contraindications: {
    highBloodPressure: false,
    cardiacHistory: false,
    lowBackPain: false,
    shoulderPain: false,
    kneePain: false,
    anklePain: false,
    pregnant: false,
    postSurgery: false,
    otherMedical: false,
  },
  kineticChain: {
    footAnkle: "",
    knee: "",
    hip: "",
    lumbar: "",
    thoracic: "",
    cervical: "",
    shoulder: "",
    elbowWrist: "",
  },
  fms: {
    deepSquat: 1,
    hurdleStep: 1,
    inlineLunge: 1,
    shoulderMobility: 1,
    activeStraightLegRaise: 1,
    trunkStabilityPushUp: 1,
    rotaryStability: 1,
  },
  clearingTests: {
    shoulderPainWithClearing: false,
    extensionPainWithClearing: false,
    flexionPainWithClearing: false,
    rotaryPainWithClearing: false,
  },
};

function num(value: string, fallback = 0) {
  const parsed = Number(value);
  return Number.isFinite(parsed) ? parsed : fallback;
}

function fmsTotal(intake: Intake) {
  return Object.values(intake.fms).reduce((sum, value) => sum + value, 0);
}

function bmi(intake: Intake) {
  const w = num(intake.weightKg);
  const h = num(intake.heightCm) / 100;
  if (!w || !h) return null;
  return +(w / (h * h)).toFixed(1);
}

function riskMessages(intake: Intake) {
  const flags: string[] = [];
  if (intake.clearingTests.shoulderPainWithClearing) flags.push("Shoulder clearing test pain recorded.");
  if (intake.clearingTests.extensionPainWithClearing) flags.push("Extension clearing test pain recorded.");
  if (intake.clearingTests.flexionPainWithClearing) flags.push("Flexion clearing test pain recorded.");
  if (intake.clearingTests.rotaryPainWithClearing) flags.push("Rotary clearing test pain recorded.");
  if (intake.contraindications.highBloodPressure) flags.push("High blood pressure flagged.");
  if (intake.contraindications.cardiacHistory) flags.push("Cardiac history flagged.");
  if (intake.contraindications.postSurgery) flags.push("Post-surgical history flagged.");
  return flags;
}

function buildPayload(intake: Intake): SubmissionPayload {
  return {
    intake,
    rules: {
      training_less_than_3_days_is_total_body: true,
      include_all_7_patterns: true,
      include_primary_and_assistance_exercises: true,
      pdf_only_output: true,
      deload_every_6_to_8_weeks: true,
      progress_supported_to_integrated_then_more_closed_chain_when_tolerated: true,
    },
  };
}

async function requestProgramPdf(payload: SubmissionPayload) {
  const response = await fetch(APP_CONFIG.apiBaseUrl, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload),
  });

  if (!response.ok) {
    throw new Error("PDF generation failed");
  }

  const blob = await response.blob();
  const contentType = response.headers.get("content-type") || "";
  if (!contentType.includes("pdf")) {
    throw new Error("Server did not return a PDF file");
  }

  return blob;
}

function downloadBlob(blob: Blob, filename: string) {
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement("a");
  anchor.href = url;
  anchor.download = filename;
  document.body.appendChild(anchor);
  anchor.click();
  anchor.remove();
  URL.revokeObjectURL(url);
}

function buildFilename(intake: Intake) {
  const safeName = (intake.clientName || "client")
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "");
  return `${APP_CONFIG.pdfFilenamePrefix}-${safeName || "client"}.pdf`;
}

function SectionHeader({ title, description }: { title: string; description: string }) {
  return (
    <div className="space-y-1">
      <h3 className="text-lg font-semibold">{title}</h3>
      <p className="text-sm text-muted-foreground">{description}</p>
    </div>
  );
}

export default function TrainingProgramDesignerEmbed() {
  const [intake, setIntake] = useState<Intake>(defaultIntake);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [status, setStatus] = useState<"idle" | "success" | "error">("idle");
  const [message, setMessage] = useState("");

  const currentBmi = useMemo(() => bmi(intake), [intake]);
  const currentFmsTotal = useMemo(() => fmsTotal(intake), [intake]);
  const currentRiskMessages = useMemo(() => riskMessages(intake), [intake]);

  function setField<K extends keyof Intake>(key: K, value: Intake[K]) {
    setIntake((prev) => ({ ...prev, [key]: value }));
  }

  function setEquipment(key: EquipmentKey, value: boolean) {
    setIntake((prev) => ({ ...prev, equipment: { ...prev.equipment, [key]: value } }));
  }

  function setContra(key: ContraKey, value: boolean) {
    setIntake((prev) => ({ ...prev, contraindications: { ...prev.contraindications, [key]: value } }));
  }

  function setFms(key: FmsKey, value: number) {
    setIntake((prev) => ({ ...prev, fms: { ...prev.fms, [key]: value } }));
  }

  function setJoint(key: JointKey, value: string) {
    setIntake((prev) => ({ ...prev, kineticChain: { ...prev.kineticChain, [key]: value } }));
  }

  function setClearing<K extends keyof Intake["clearingTests"]>(key: K, value: boolean) {
    setIntake((prev) => ({ ...prev, clearingTests: { ...prev.clearingTests, [key]: value } }));
  }

  async function handleGenerate() {
    setIsSubmitting(true);
    setStatus("idle");
    setMessage("");

    try {
      const payload = buildPayload(intake);
      const pdfBlob = await requestProgramPdf(payload);
      downloadBlob(pdfBlob, buildFilename(intake));
      setStatus("success");
      setMessage("Your PDF program has been generated.");
    } catch (error) {
      setStatus("error");
      setMessage(error instanceof Error ? error.message : "Unable to generate the PDF program.");
    } finally {
      setIsSubmitting(false);
    }
  }

  return (
    <div className="min-h-screen bg-background p-4 md:p-6">
      <div className="mx-auto max-w-5xl">
        <motion.div initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }}>
          <Card className="rounded-3xl shadow-sm">
            <CardHeader className="space-y-4">
              <div className="flex items-start gap-3">
                <div className="rounded-2xl border p-3">
                  <Dumbbell className="h-6 w-6" />
                </div>
                <div>
                  <CardTitle className="text-2xl">{APP_CONFIG.appName}</CardTitle>
                  <CardDescription>
                    Complete the form below and generate the client program PDF.
                  </CardDescription>
                </div>
              </div>

              <div className="grid gap-3 sm:grid-cols-3">
                <div className="rounded-2xl border p-4">
                  <div className="text-xs uppercase tracking-wide text-muted-foreground">BMI</div>
                  <div className="mt-1 text-2xl font-semibold">{currentBmi ?? "—"}</div>
                </div>
                <div className="rounded-2xl border p-4">
                  <div className="text-xs uppercase tracking-wide text-muted-foreground">FMS Total</div>
                  <div className="mt-1 text-2xl font-semibold">{currentFmsTotal}</div>
                </div>
                <div className="rounded-2xl border p-4">
                  <div className="text-xs uppercase tracking-wide text-muted-foreground">Training Split Rule</div>
                  <div className="mt-1 text-sm font-semibold">
                    {num(intake.frequencyPerWeek, 3) < 3 ? "Total body sessions" : "Frequency-based split"}
                  </div>
                </div>
              </div>
            </CardHeader>

            <CardContent className="space-y-8">
              <div className="space-y-4">
                <SectionHeader
                  title="Client Details"
                  description="Basic client information and training setup."
                />
                <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
                  <div className="space-y-2"><Label>Client Name</Label><Input value={intake.clientName} onChange={(e) => setField("clientName", e.target.value)} /></div>
                  <div className="space-y-2"><Label>Trainer Name</Label><Input value={intake.trainerName} onChange={(e) => setField("trainerName", e.target.value)} /></div>
                  <div className="space-y-2"><Label>Age</Label><Input value={intake.age} onChange={(e) => setField("age", e.target.value)} /></div>
                  <div className="space-y-2"><Label>Sex</Label><Input value={intake.sex} onChange={(e) => setField("sex", e.target.value)} /></div>
                  <div className="space-y-2"><Label>Weight (kg)</Label><Input value={intake.weightKg} onChange={(e) => setField("weightKg", e.target.value)} /></div>
                  <div className="space-y-2"><Label>Height (cm)</Label><Input value={intake.heightCm} onChange={(e) => setField("heightCm", e.target.value)} /></div>
                  <div className="space-y-2"><Label>Body Fat %</Label><Input value={intake.bodyFat} onChange={(e) => setField("bodyFat", e.target.value)} /></div>
                  <div className="space-y-2">
                    <Label>Training Age</Label>
                    <Select value={intake.trainingAge} onValueChange={(value) => setField("trainingAge", value)}>
                      <SelectTrigger><SelectValue /></SelectTrigger>
                      <SelectContent>
                        <SelectItem value="beginner">Beginner</SelectItem>
                        <SelectItem value="intermediate">Intermediate</SelectItem>
                        <SelectItem value="advanced">Advanced</SelectItem>
                      </SelectContent>
                    </Select>
                  </div>
                  <div className="space-y-2"><Label>Training Days / Week</Label><Input value={intake.frequencyPerWeek} onChange={(e) => setField("frequencyPerWeek", e.target.value)} /></div>
                  <div className="space-y-2"><Label>Session Duration (min)</Label><Input value={intake.sessionDurationMin} onChange={(e) => setField("sessionDurationMin", e.target.value)} /></div>
                  <div className="space-y-2 md:col-span-2"><Label>Primary Goal</Label><Input value={intake.goal} onChange={(e) => setField("goal", e.target.value)} /></div>
                </div>
              </div>

              <Separator />

              <div className="space-y-4">
                <SectionHeader
                  title="Health and Injury History"
                  description="Use these notes to account for medical history, symptoms, and local tissue concerns."
                />
                <div className="grid gap-4 xl:grid-cols-3">
                  <div className="space-y-2"><Label>Health History</Label><Textarea rows={6} value={intake.healthHistory} onChange={(e) => setField("healthHistory", e.target.value)} /></div>
                  <div className="space-y-2"><Label>Current Medications</Label><Textarea rows={6} value={intake.currentMedications} onChange={(e) => setField("currentMedications", e.target.value)} /></div>
                  <div className="space-y-2"><Label>General Injury Notes</Label><Textarea rows={6} value={intake.injuryNotes} onChange={(e) => setField("injuryNotes", e.target.value)} /></div>
                </div>
              </div>

              <Separator />

              <div className="space-y-4">
                <SectionHeader
                  title="Available Equipment"
                  description="Only selected equipment should be used in the final program PDF."
                />
                <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
                  {(Object.keys(equipmentLabels) as EquipmentKey[]).map((key) => (
                    <label key={key} className="flex items-start gap-3 rounded-2xl border p-4">
                      <Checkbox checked={intake.equipment[key]} onCheckedChange={(checked) => setEquipment(key, Boolean(checked))} />
                      <div className="font-medium">{equipmentLabels[key]}</div>
                    </label>
                  ))}
                </div>
              </div>

              <Separator />

              <div className="space-y-4">
                <SectionHeader
                  title="FMS and Clearing Tests"
                  description="Movement quality and pain findings should constrain exercise selection and progression."
                />
                <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
                  {fmsFields.map(({ key, label }) => (
                    <div key={key} className="space-y-2 rounded-2xl border p-4">
                      <Label>{label}</Label>
                      <Select value={String(intake.fms[key])} onValueChange={(value) => setFms(key, Number(value))}>
                        <SelectTrigger><SelectValue /></SelectTrigger>
                        <SelectContent>
                          <SelectItem value="0">0</SelectItem>
                          <SelectItem value="1">1</SelectItem>
                          <SelectItem value="2">2</SelectItem>
                          <SelectItem value="3">3</SelectItem>
                        </SelectContent>
                      </Select>
                    </div>
                  ))}
                </div>

                <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
                  <label className="flex items-start gap-3 rounded-2xl border p-4"><Checkbox checked={intake.clearingTests.shoulderPainWithClearing} onCheckedChange={(checked) => setClearing("shoulderPainWithClearing", Boolean(checked))} /><span className="text-sm">Shoulder clearing test pain</span></label>
                  <label className="flex items-start gap-3 rounded-2xl border p-4"><Checkbox checked={intake.clearingTests.extensionPainWithClearing} onCheckedChange={(checked) => setClearing("extensionPainWithClearing", Boolean(checked))} /><span className="text-sm">Extension clearing test pain</span></label>
                  <label className="flex items-start gap-3 rounded-2xl border p-4"><Checkbox checked={intake.clearingTests.flexionPainWithClearing} onCheckedChange={(checked) => setClearing("flexionPainWithClearing", Boolean(checked))} /><span className="text-sm">Flexion clearing test pain</span></label>
                  <label className="flex items-start gap-3 rounded-2xl border p-4"><Checkbox checked={intake.clearingTests.rotaryPainWithClearing} onCheckedChange={(checked) => setClearing("rotaryPainWithClearing", Boolean(checked))} /><span className="text-sm">Rotary clearing test pain</span></label>
                </div>
              </div>

              <Separator />

              <div className="space-y-4">
                <SectionHeader
                  title="Contraindications and Kinetic Chain Checkpoints"
                  description="Flag contraindications and note site-specific issues."
                />
                <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3">
                  {(Object.keys(contraLabels) as ContraKey[]).map((key) => (
                    <label key={key} className="flex items-start gap-3 rounded-2xl border p-4">
                      <Checkbox checked={intake.contraindications[key]} onCheckedChange={(checked) => setContra(key, Boolean(checked))} />
                      <div className="font-medium">{contraLabels[key]}</div>
                    </label>
                  ))}
                </div>

                <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
                  {(Object.keys(jointLabels) as JointKey[]).map((key) => (
                    <div key={key} className="space-y-2 rounded-2xl border p-4">
                      <Label>{jointLabels[key]}</Label>
                      <Textarea rows={4} value={intake.kineticChain[key]} onChange={(e) => setJoint(key, e.target.value)} />
                    </div>
                  ))}
                </div>
              </div>

              <Separator />

              <div className="rounded-2xl border p-4">
                <div className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
                  <div>
                    <div className="text-sm font-medium">Readiness Summary</div>
                    <p className="text-sm text-muted-foreground">
                      {currentRiskMessages.length
                        ? `${currentRiskMessages.length} caution flag${currentRiskMessages.length === 1 ? "" : "s"} recorded.`
                        : "No major caution flags currently selected."}
                    </p>
                  </div>
                  <Button onClick={handleGenerate} disabled={isSubmitting} className="rounded-2xl px-6">
                    <FileDown className="mr-2 h-4 w-4" />
                    {isSubmitting ? "Generating PDF..." : "Generate PDF"}
                  </Button>
                </div>
              </div>

              {status !== "idle" && (
                <div
                  className={`rounded-2xl border p-4 text-sm ${
                    status === "success"
                      ? "border-emerald-200 bg-emerald-50 text-emerald-800"
                      : "border-red-200 bg-red-50 text-red-800"
                  }`}
                >
                  <div className="flex items-start gap-2">
                    {status === "success" ? <CheckCircle2 className="mt-0.5 h-4 w-4" /> : <AlertCircle className="mt-0.5 h-4 w-4" />}
                    <span>{message}</span>
                  </div>
                </div>
              )}

              {currentRiskMessages.length > 0 && (
                <div className="rounded-2xl border border-amber-200 bg-amber-50 p-4 text-sm text-amber-900">
                  <div className="mb-2 flex items-center gap-2 font-medium">
                    <ShieldAlert className="h-4 w-4" /> Caution Flags
                  </div>
                  <ul className="list-disc space-y-1 pl-5">
                    {currentRiskMessages.map((item) => (
                      <li key={item}>{item}</li>
                    ))}
                  </ul>
                </div>
              )}
            </CardContent>
          </Card>
        </motion.div>
      </div>
    </div>
  );
}
