"use client";

import { useMemo, useState } from "react";

export type BuildProgressHubCategoryGroup = {
  id: string;
  label: string;
  categoryIds: string[];
};

export type BuildProgressHubProps = {
  slots: any[];
  selectedByCategory: Record<string, unknown>;
  categoryGroups: BuildProgressHubCategoryGroup[];
  isSlotSatisfiedFn: (slot: any, selectedByCategory: any) => boolean;

  requiredSlotIds?: Set<string>;
  upgradeSlotIds?: Set<string>;
};

// Defaults (pragmatic UX for new users)
export const DEFAULT_REQUIRED_SLOT_IDS = new Set<string>([
  "lower-receiver",
  "complete-lower",
  "upper-receiver",
  "complete-upper",

  "barrel",
  "bcg",
  "charging-handle",
  "handguard",
  "gas-block",
  "gas-tube",
  "muzzle-device",

  "trigger",
  "grip",
  "safety-selector",
  "buffer",
  "stock",
]);

export const DEFAULT_UPGRADE_SLOT_IDS = new Set<string>([
  "optic",
  "sights",
  "suppressor",
  "weapon-light",
  "foregrip",
  "bipod",
  "sling",
  "rail-accessory",
]);

function clamp01(n: number) {
  if (Number.isNaN(n)) return 0;
  return Math.max(0, Math.min(1, n));
}

function CircularProgress({
  value,
  size = 64,
  stroke = 8,
  label,
  sublabel,
}: {
  value: number; // 0..1
  size?: number;
  stroke?: number;
  label: string;
  sublabel?: string;
}) {
  const v = clamp01(value);
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const dash = c * v;

  return (
    <div className="relative" style={{ width: size, height: size }}>
      <svg width={size} height={size} className="block">
        <circle
          cx={size / 2}
          cy={size / 2}
          r={r}
          strokeWidth={stroke}
          className="text-zinc-800"
          stroke="currentColor"
          fill="transparent"
        />
        <circle
          cx={size / 2}
          cy={size / 2}
          r={r}
          strokeWidth={stroke}
          className="text-amber-400"
          stroke="currentColor"
          fill="transparent"
          strokeLinecap="round"
          strokeDasharray={`${dash} ${c - dash}`}
          transform={`rotate(-90 ${size / 2} ${size / 2})`}
        />
      </svg>

      <div className="absolute inset-0 flex flex-col items-center justify-center text-center">
        <div className="text-[0.65rem] font-semibold text-zinc-100 leading-none">
          {label}
        </div>
        {sublabel ? (
          <div className="mt-0.5 text-[0.6rem] text-zinc-400 leading-none">
            {sublabel}
          </div>
        ) : null}
      </div>
    </div>
  );
}

function slotGroupLabel(slotId: string, categoryGroups: BuildProgressHubCategoryGroup[]) {
  const g = categoryGroups.find((group) =>
    group.categoryIds.includes(slotId)
  );
  return g?.label ?? "Other";
}

function scrollToSlot(slotId: string, categoryGroups: BuildProgressHubCategoryGroup[]) {
  const el = document.getElementById(`slot-${slotId}`);
  if (el) {
    el.scrollIntoView({ behavior: "smooth", block: "start" });
    el.classList.add("ring-2", "ring-amber-400/40");
    window.setTimeout(() => {
      el.classList.remove("ring-2", "ring-amber-400/40");
    }, 900);
    return;
  }

  const groupId =
    categoryGroups.find((g) => g.categoryIds.includes(slotId))?.id ?? "";
  const gEl = groupId ? document.getElementById(`group-${groupId}`) : null;
  if (gEl) gEl.scrollIntoView({ behavior: "smooth", block: "start" });
}

export function BuildProgressHub({
  slots,
  selectedByCategory,
  categoryGroups,
  isSlotSatisfiedFn,
  requiredSlotIds,
  upgradeSlotIds,
}: BuildProgressHubProps) {
  const [open, setOpen] = useState(false);

  const requiredIds = requiredSlotIds ?? DEFAULT_REQUIRED_SLOT_IDS;
  const upgradeIds = upgradeSlotIds ?? DEFAULT_UPGRADE_SLOT_IDS;

  const enriched = useMemo(() => {
    return (slots ?? []).map((slot: any) => {
      const slotId = String(slot.id ?? slot.key ?? slot.slotId ?? "");
      const required = slot.required === true || requiredIds.has(slotId);
      const satisfied = isSlotSatisfiedFn(slot, selectedByCategory as any);

      return {
        id: slotId,
        label: String(slot.label ?? slotId),
        required,
        satisfied,
        groupLabel: slotGroupLabel(slotId, categoryGroups),
      };
    });
  }, [slots, selectedByCategory, categoryGroups, isSlotSatisfiedFn, requiredIds]);

  const required = enriched.filter((s) => s.required);
  const optional = enriched.filter((s) => !s.required);

  const upgrades = optional.filter((s) => upgradeIds.has(s.id));
  const accessories = optional.filter((s) => !upgradeIds.has(s.id));

  const reqDone = required.filter((s) => s.satisfied).length;
  const optDone = optional.filter((s) => s.satisfied).length;

  const reqPct = required.length ? reqDone / required.length : 0;
  const optPct = optional.length ? optDone / optional.length : 0;

  const remainingRequired = Math.max(0, required.length - reqDone);

  return (
    <div className="fixed bottom-4 right-4 z-40">
      <button
        type="button"
        onClick={() => setOpen((v) => !v)}
        className="group flex items-center gap-3 rounded-2xl border border-white/10 bg-zinc-950/80 px-3 py-3 shadow-xl backdrop-blur hover:bg-zinc-900/80"
        aria-label="Build progress"
        title="Build progress"
      >
        <CircularProgress
          value={reqPct}
          size={56}
          stroke={7}
          label={`${reqDone}/${required.length}`}
          sublabel="Required"
        />
        <div className="text-left">
          <div className="text-xs font-semibold text-zinc-100">
            Build Checklist
          </div>
          <div className="mt-0.5 text-[0.7rem] text-zinc-400">
            {remainingRequired === 0
              ? "Core complete ✅"
              : `${remainingRequired} required left`}
          </div>
          <div className="mt-1 text-[0.65rem] text-zinc-500">
            Tap to {open ? "hide" : "view"} details
          </div>
        </div>
      </button>

      {open && (
        <div className="mt-3 w-[22rem] max-w-[92vw] overflow-hidden rounded-2xl border border-white/10 bg-zinc-950/90 shadow-2xl backdrop-blur">
          <div className="flex items-center justify-between gap-3 border-b border-white/10 px-4 py-3">
            <div>
              <div className="text-xs font-semibold text-zinc-100">
                What you need (fast)
              </div>
              <div className="mt-0.5 text-[0.7rem] text-zinc-400">
                Required vs optional — click anything to jump.
              </div>
            </div>
            <button
              type="button"
              onClick={() => setOpen(false)}
              className="rounded-md border border-white/10 bg-white/5 px-2 py-1 text-xs text-zinc-200 hover:bg-white/10"
            >
              Close
            </button>
          </div>

          <div className="grid grid-cols-2 gap-0 border-b border-white/10">
            <div className="px-4 py-3">
              <div className="flex items-center justify-between">
                <div className="text-[0.7rem] font-semibold uppercase tracking-[0.14em] text-amber-300">
                  Required
                </div>
                <div className="text-[0.7rem] text-zinc-400">
                  {reqDone}/{required.length}
                </div>
              </div>
              <div className="mt-2">
                <CircularProgress
                  value={reqPct}
                  size={64}
                  stroke={8}
                  label={`${Math.round(reqPct * 100)}%`}
                  sublabel="Core"
                />
              </div>
            </div>

            <div className="px-4 py-3 border-l border-white/10">
              <div className="flex items-center justify-between">
                <div className="text-[0.7rem] font-semibold uppercase tracking-[0.14em] text-zinc-300">
                  Optional
                </div>
                <div className="text-[0.7rem] text-zinc-400">
                  {optDone}/{optional.length}
                </div>
              </div>
              <div className="mt-2">
                <CircularProgress
                  value={optPct}
                  size={64}
                  stroke={8}
                  label={`${Math.round(optPct * 100)}%`}
                  sublabel="Extras"
                />
              </div>
            </div>
          </div>

          <div className="max-h-[55vh] overflow-auto">
            <div className="px-4 py-3">
              <div className="text-[0.7rem] font-semibold uppercase tracking-[0.14em] text-amber-300">
                Required components
              </div>
              <div className="mt-2 space-y-1">
                {required.map((s) => (
                  <button
                    key={s.id}
                    type="button"
                    onClick={() => {
                      setOpen(false);
                      scrollToSlot(s.id, categoryGroups);
                    }}
                    className="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-left hover:bg-white/10"
                  >
                    <div className="flex items-center justify-between gap-3">
                      <div>
                        <div className="text-xs font-medium text-zinc-100">
                          {s.label}
                        </div>
                        <div className="mt-0.5 text-[0.65rem] text-zinc-500">
                          {s.groupLabel}
                        </div>
                      </div>
                      <span
                        className={`rounded-full px-2 py-0.5 text-[0.65rem] border ${
                          s.satisfied
                            ? "border-emerald-500/40 bg-emerald-500/10 text-emerald-200"
                            : "border-zinc-700 bg-zinc-900/40 text-zinc-300"
                        }`}
                      >
                        {s.satisfied ? "Added" : "Missing"}
                      </span>
                    </div>
                  </button>
                ))}
              </div>
            </div>

            <div className="px-4 pb-4">
              <div className="text-[0.7rem] font-semibold uppercase tracking-[0.14em] text-zinc-300">
                Optional components
              </div>

              <div className="mt-2 text-[0.65rem] font-semibold uppercase tracking-[0.14em] text-zinc-400">
                Upgrades
              </div>
              <div className="mt-2 space-y-1">
                {upgrades.map((s) => (
                  <button
                    key={`upg-${s.id}`}
                    type="button"
                    onClick={() => {
                      setOpen(false);
                      scrollToSlot(s.id, categoryGroups);
                    }}
                    className="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-left hover:bg-white/10"
                  >
                    <div className="flex items-center justify-between gap-3">
                      <div>
                        <div className="text-xs font-medium text-zinc-100">
                          {s.label}
                        </div>
                        <div className="mt-0.5 text-[0.65rem] text-zinc-500">
                          {s.groupLabel}
                        </div>
                      </div>
                      <span
                        className={`rounded-full px-2 py-0.5 text-[0.65rem] border ${
                          s.satisfied
                            ? "border-emerald-500/40 bg-emerald-500/10 text-emerald-200"
                            : "border-zinc-700 bg-zinc-900/40 text-zinc-300"
                        }`}
                      >
                        {s.satisfied ? "Added" : "Open"}
                      </span>
                    </div>
                  </button>
                ))}
              </div>

              <div className="mt-4 text-[0.65rem] font-semibold uppercase tracking-[0.14em] text-zinc-400">
                Accessories
              </div>
              <div className="mt-2 space-y-1">
                {accessories.map((s) => (
                  <button
                    key={`acc-${s.id}`}
                    type="button"
                    onClick={() => {
                      setOpen(false);
                      scrollToSlot(s.id, categoryGroups);
                    }}
                    className="w-full rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-left hover:bg-white/10"
                  >
                    <div className="flex items-center justify-between gap-3">
                      <div>
                        <div className="text-xs font-medium text-zinc-100">
                          {s.label}
                        </div>
                        <div className="mt-0.5 text-[0.65rem] text-zinc-500">
                          {s.groupLabel}
                        </div>
                      </div>
                      <span
                        className={`rounded-full px-2 py-0.5 text-[0.65rem] border ${
                          s.satisfied
                            ? "border-emerald-500/40 bg-emerald-500/10 text-emerald-200"
                            : "border-zinc-700 bg-zinc-900/40 text-zinc-300"
                        }`}
                      >
                        {s.satisfied ? "Added" : "Open"}
                      </span>
                    </div>
                  </button>
                ))}
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}