"use client";

import { useMemo } from "react";
import { Skill, SKILL_ABILITY } from "@/types/content";
import type { Effect } from "@/types/core";
import { useCreator } from "../CreatorContext";
import { getAbilityModifier } from "@/lib/dndHelpers";

const SKILLS = Object.keys(SKILL_ABILITY) as Skill[];

interface SkillChoice {
  featureId: string;
  featureName: string;
  count: number;
  from: Skill[];
}

interface ExpertiseChoice {
  featureId: string;
  featureName: string;
  count: number;
  skillPool: Skill[] | "characterSkills";
  toolPool: string[];
}

export default function SkillsStep() {
  const { draft, update, classes, backgrounds, species, features } = useCreator();

  const selectedClass = useMemo(
    () => classes.find((c) => c.id === draft.classes[0]?.classId),
    [classes, draft.classes]
  );
  const selectedBackground = useMemo(
    () => backgrounds.find((b) => b.id === draft.backgroundId),
    [backgrounds, draft.backgroundId]
  );
  const selectedSpecies = useMemo(
    () => species.find((s) => s.id === draft.speciesId),
    [species, draft.speciesId]
  );
  const level = draft.classes[0]?.level ?? 1;

  const attachedFeatureIds = useMemo(() => {
    const ids: string[] = [];
    ids.push(...(selectedSpecies?.featureIds ?? []));
    ids.push(...(selectedBackground?.featureIds ?? []));
    for (const lf of selectedClass?.levelFeatures ?? []) {
      if (lf.level <= level) ids.push(...lf.featureIds);
    }
    return ids;
  }, [selectedSpecies, selectedBackground, selectedClass, level]);

  const skillChoices: SkillChoice[] = useMemo(() => {
    const out: SkillChoice[] = [];
    for (const fid of attachedFeatureIds) {
      const f = features[fid];
      if (!f) continue;
      for (const eff of f.effects ?? []) {
        if (eff.target.kind === "skillProficiencyChoice") {
          out.push({
            featureId: f.id,
            featureName: f.name,
            count: eff.target.count,
            from: eff.target.from,
          });
        }
      }
    }
    return out;
  }, [attachedFeatureIds, features]);

  const expertiseChoices: ExpertiseChoice[] = useMemo(() => {
    const out: ExpertiseChoice[] = [];
    for (const fid of attachedFeatureIds) {
      const f = features[fid];
      if (!f) continue;
      for (const eff of f.effects ?? []) {
        if (eff.target.kind === "expertiseChoice") {
          out.push({
            featureId: f.id,
            featureName: f.name,
            count: eff.target.count,
            skillPool: eff.target.skillPool,
            toolPool: eff.target.toolPool,
          });
        }
      }
    }
    return out;
  }, [attachedFeatureIds, features]);

  const classSkillOptions = selectedClass?.skillProficiencyOptions?.from ?? [];
  const classSkillCount = selectedClass?.skillProficiencyOptions?.count ?? 0;
  const backgroundSkills: Skill[] = selectedBackground?.skillProficiencies ?? [];

  const featureChosenSkills: Skill[] = useMemo(
    () =>
      skillChoices.flatMap((c) => (draft.featureChoices[c.featureId] ?? []) as Skill[]),
    [skillChoices, draft.featureChoices]
  );

  const chosen = draft.skillProficiencies;
  const chosenFromClass = chosen.filter(
    (s) => classSkillOptions.includes(s) && !backgroundSkills.includes(s)
  );

  const toggleClassSkill = (s: Skill) => {
    if (backgroundSkills.includes(s) || featureChosenSkills.includes(s)) return;
    if (!classSkillOptions.includes(s)) return;
    if (chosen.includes(s)) {
      update({ skillProficiencies: chosen.filter((x) => x !== s) });
    } else {
      if (chosenFromClass.length >= classSkillCount) return;
      update({ skillProficiencies: [...chosen, s] });
    }
  };

  const toggleFeatureChoice = (choice: SkillChoice, s: Skill) => {
    const current = (draft.featureChoices[choice.featureId] ?? []) as Skill[];
    let next: Skill[];
    if (current.includes(s)) {
      next = current.filter((x) => x !== s);
    } else {
      if (current.length >= choice.count) return;
      next = [...current, s];
    }
    update({
      featureChoices: { ...draft.featureChoices, [choice.featureId]: next },
    });
  };

  const isEffectivelyChosen = (s: Skill) =>
    chosen.includes(s) || backgroundSkills.includes(s) || featureChosenSkills.includes(s);

  const allCharacterSkills: Skill[] = useMemo(
    () => Array.from(new Set([...chosen, ...backgroundSkills, ...featureChosenSkills])),
    [chosen, backgroundSkills, featureChosenSkills]
  );

  const toggleExpertise = (choice: ExpertiseChoice, key: string) => {
    const current = (draft.featureChoices[choice.featureId] ?? []) as string[];
    let next: string[];
    if (current.includes(key)) {
      next = current.filter((x) => x !== key);
    } else {
      if (current.length >= choice.count) return;
      next = [...current, key];
    }
    update({
      featureChoices: { ...draft.featureChoices, [choice.featureId]: next },
    });
  };

  return (
    <div className="space-y-6">
      <div>
        <h2 className="text-2xl font-bold text-neutral-100">Skill Proficiencies</h2>
        <p className="text-sm text-neutral-400 mt-1">
          Class allows {classSkillCount} choice(s). Background + features grant more.
        </p>
        <p className="text-xs text-neutral-500 mt-1">
          Class chosen: {chosenFromClass.length}/{classSkillCount}
        </p>
      </div>

      {skillChoices.map((choice) => {
        const picked = (draft.featureChoices[choice.featureId] ?? []) as Skill[];
        return (
          <div key={choice.featureId} className="p-4 border border-amber-500/40 bg-amber-500/5 rounded">
            <div className="text-sm font-semibold text-amber-300 mb-1">
              {choice.featureName} — pick {choice.count}
              <span className="ml-2 text-xs text-neutral-500">({picked.length}/{choice.count})</span>
            </div>
            <div className="flex flex-wrap gap-2 mt-2">
              {choice.from.map((s) => {
                const on = picked.includes(s);
                const conflictOther =
                  !on && (chosen.includes(s) || backgroundSkills.includes(s) || featureChosenSkills.includes(s));
                const disabled = conflictOther || (!on && picked.length >= choice.count);
                return (
                  <button
                    key={s}
                    type="button"
                    onClick={() => toggleFeatureChoice(choice, s)}
                    disabled={disabled}
                    className={`px-2 py-1 text-xs rounded border capitalize transition ${
                      on
                        ? "bg-amber-500/30 border-amber-400"
                        : "border-neutral-700 hover:border-neutral-500"
                    } ${disabled ? "opacity-40 cursor-not-allowed" : ""}`}
                  >
                    {s}
                  </button>
                );
              })}
            </div>
          </div>
        );
      })}

      {expertiseChoices.map((choice) => {
        const picked = (draft.featureChoices[choice.featureId] ?? []) as string[];
        const skillOptions: Skill[] =
          choice.skillPool === "characterSkills" ? allCharacterSkills : (choice.skillPool as Skill[]);
        return (
          <div key={choice.featureId} className="p-4 border border-purple-500/40 bg-purple-500/5 rounded">
            <div className="text-sm font-semibold text-purple-300 mb-1">
              {choice.featureName} — Expertise, pick {choice.count}
              <span className="ml-2 text-xs text-neutral-500">({picked.length}/{choice.count})</span>
            </div>
            {choice.skillPool === "characterSkills" && skillOptions.length === 0 && (
              <p className="text-xs text-amber-400 mt-1">Pick skill proficiencies below first.</p>
            )}
            <div className="mt-2 space-y-2">
              {skillOptions.length > 0 && (
                <div>
                  <div className="text-xs text-neutral-500 mb-1">Skills</div>
                  <div className="flex flex-wrap gap-2">
                    {skillOptions.map((s) => {
                      const key = `skill:${s}`;
                      const on = picked.includes(key);
                      const disabled = !on && picked.length >= choice.count;
                      return (
                        <button
                          key={key}
                          type="button"
                          onClick={() => toggleExpertise(choice, key)}
                          disabled={disabled}
                          className={`px-2 py-1 text-xs rounded border capitalize transition ${
                            on ? "bg-purple-500/30 border-purple-400" : "border-neutral-700 hover:border-neutral-500"
                          } ${disabled ? "opacity-40 cursor-not-allowed" : ""}`}
                        >
                          {s}
                        </button>
                      );
                    })}
                  </div>
                </div>
              )}
              {choice.toolPool.length > 0 && (
                <div>
                  <div className="text-xs text-neutral-500 mb-1">Tools</div>
                  <div className="flex flex-wrap gap-2">
                    {choice.toolPool.map((tool) => {
                      const key = `tool:${tool}`;
                      const on = picked.includes(key);
                      const disabled = !on && picked.length >= choice.count;
                      return (
                        <button
                          key={key}
                          type="button"
                          onClick={() => toggleExpertise(choice, key)}
                          disabled={disabled}
                          className={`px-2 py-1 text-xs rounded border transition ${
                            on ? "bg-purple-500/30 border-purple-400" : "border-neutral-700 hover:border-neutral-500"
                          } ${disabled ? "opacity-40 cursor-not-allowed" : ""}`}
                        >
                          {tool}
                        </button>
                      );
                    })}
                  </div>
                </div>
              )}
            </div>
          </div>
        );
      })}

      <div>
        <div className="text-sm text-neutral-400 mb-2">
          Class starting skills — pick {classSkillCount} from the class pool ({chosenFromClass.length}/{classSkillCount}). Non-pool skills shown for reference.
        </div>
        <div className="grid grid-cols-2 md:grid-cols-3 gap-2">
          {SKILLS.map((s) => {
            const fromBg = backgroundSkills.includes(s);
            const fromFeature = featureChosenSkills.includes(s);
            const inClassPool = classSkillOptions.includes(s);
            const active = isEffectivelyChosen(s);
            const disabled = fromBg || fromFeature || !inClassPool;
            const mod = getAbilityModifier(draft.abilities[SKILL_ABILITY[s]]);
            return (
              <button
                key={s}
                onClick={() => toggleClassSkill(s)}
                disabled={disabled}
                className={`text-left p-3 rounded border text-sm transition ${
                  active
                    ? "bg-amber-500/10 border-amber-500"
                    : "border-neutral-700 hover:border-neutral-500"
                } ${disabled ? "opacity-80 cursor-not-allowed" : ""}`}
              >
                <div className="flex items-center justify-between">
                  <span className="font-medium capitalize">{s.replace(/([A-Z])/g, " $1")}</span>
                  <span className="text-xs text-neutral-500">{SKILL_ABILITY[s].slice(0, 3)}</span>
                </div>
                <div className="text-xs text-neutral-400 mt-1">
                  base {mod >= 0 ? `+${mod}` : mod}
                  {fromBg && <span className="ml-2 text-amber-400">background</span>}
                  {fromFeature && <span className="ml-2 text-amber-400">feature</span>}
                  {!fromBg && !fromFeature && inClassPool && <span className="ml-2 text-blue-400">class option</span>}
                </div>
              </button>
            );
          })}
        </div>
      </div>
    </div>
  );
}
