import { useState, useRef, useEffect } from "react";
import type { Character, GameItem } from "../types";
import { calculateAC } from "../utils/derived-ac";
import { getTalentHpBonus } from "../utils/talent-effects";
import AcDisplay from "./AcDisplay";
import InlineNumber from "./InlineNumber";
import SelectDropdown from "./SelectDropdown";
import TorchTimer from "./TorchTimer";
import StatsPanel from "./StatsPanel";
import InfoPanel from "./InfoPanel";
import GearPanel from "./GearPanel";
import styles from "./CharacterSheet.module.css";

const AVATAR_STYLES = [
  "micah",
  "adventurer",
  "adventurer-neutral",
  "lorelei",
  "lorelei-neutral",
  "pixel-art",
  "thumbs",
  "personas",
  "big-smile",
];

function getAvatarUrl(character: Character): string {
  const style = (character.overrides?.avatar_style as string) || "micah";
  const seed = encodeURIComponent(character.name || "hero");
  return `https://api.dicebear.com/9.x/${style}/svg?seed=${seed}`;
}

interface CharacterSheetProps {
  character: Character;
  mode: "view" | "edit";
  campaignId: number;
  critKeys?: Set<string>;
  onUpdate: (id: number, data: Partial<Character>) => void;
  onStatChange: (characterId: number, statName: string, value: number) => void;
  onAddGearFromItem: (characterId: number, item: GameItem) => void;
  onAddGearCustom: (
    characterId: number,
    data: { name: string; type: string; slot_count: number },
  ) => void;
  onRemoveGear: (characterId: number, gearId: number) => void;
  onAddTalent: (
    characterId: number,
    data: {
      name: string;
      description: string;
      effect?: Record<string, unknown>;
      game_talent_id?: number | null;
    },
  ) => void;
  onRemoveTalent: (characterId: number, talentId: number) => void;
  onDelete: (id: number) => void;
}

export default function CharacterSheet({
  character,
  mode,
  campaignId,
  critKeys,
  onUpdate,
  onStatChange,
  onAddGearFromItem,
  onAddGearCustom,
  onRemoveGear,
  onAddTalent,
  onRemoveTalent,
  onDelete,
}: CharacterSheetProps) {
  const [confirmDelete, setConfirmDelete] = useState(false);
  const debounceRef = useRef<ReturnType<typeof setTimeout>>();
  const acBreakdown = calculateAC(character);
  const hpBonus = getTalentHpBonus(character);
  const effectiveHpMax = character.hp_max + hpBonus;
  const xpThreshold = character.level * 10;

  useEffect(() => {
    return () => {
      if (debounceRef.current) clearTimeout(debounceRef.current);
    };
  }, []);

  function handleNameField(field: string, value: string) {
    if (debounceRef.current) clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(() => {
      onUpdate(character.id, { [field]: value });
    }, 400);
  }

  function handleAcOverride(value: number | null) {
    const overrides = { ...(character.overrides || {}) };
    if (value === null) {
      delete overrides.ac;
    } else {
      overrides.ac = value;
    }
    onUpdate(character.id, { overrides } as Partial<Character>);
  }

  return (
    <>
      {/* HEADER BANNER */}
      <div
        className={styles.banner}
        style={{ borderLeft: `3px solid ${character.color}` }}
      >
        <img className={styles.avatar} src={getAvatarUrl(character)} alt="" />
        <div className={styles.identity}>
          {mode === "edit" ? (
            <div>
              <div className={styles.colorRow}>
                <input
                  className={styles.nameInput}
                  defaultValue={character.name}
                  onChange={(e) => handleNameField("name", e.target.value)}
                />
                <input
                  type="color"
                  className={styles.colorPicker}
                  value={character.color || "#888888"}
                  onChange={(e) =>
                    onUpdate(character.id, { color: e.target.value })
                  }
                  title="Character color"
                />
              </div>
              <div className={styles.colorRow}>
                <input
                  className={styles.titleInput}
                  defaultValue={character.title}
                  placeholder="title..."
                  onChange={(e) => handleNameField("title", e.target.value)}
                />
                <SelectDropdown
                  value={
                    (character.overrides?.avatar_style as string) || "micah"
                  }
                  options={AVATAR_STYLES}
                  onChange={(v) => {
                    const overrides = {
                      ...(character.overrides || {}),
                      avatar_style: v,
                    };
                    onUpdate(character.id, {
                      overrides,
                    } as Partial<Character>);
                  }}
                />
              </div>
            </div>
          ) : (
            <div className={styles.name}>
              {character.name}
              {character.title && (
                <span className={styles.title}> {character.title}</span>
              )}
            </div>
          )}
          <div className={styles.subtitle}>
            Level {character.level} {character.ancestry} {character.class}
          </div>
        </div>
        <div className={styles.vitals}>
          {/* HP — click to edit */}
          <div className={styles.vital}>
            <div className={styles.hpValues}>
              <span className={styles.vitalLabel}>HP</span>
              <InlineNumber
                value={character.hp_current}
                onChange={(hp) => onUpdate(character.id, { hp_current: hp })}
                className={`${styles.vitalValue} ${styles.hp}`}
              />
              <span className={styles.hpSlash}>/</span>
              {mode === "edit" ? (
                <>
                  <InlineNumber
                    value={character.hp_max}
                    onChange={(hp) => onUpdate(character.id, { hp_max: hp })}
                    className={styles.hpMax}
                    min={0}
                  />
                  {hpBonus > 0 && (
                    <span className={styles.hpBonus}>(+{hpBonus})</span>
                  )}
                </>
              ) : (
                <span className={styles.hpMax}>
                  {effectiveHpMax}
                  {hpBonus > 0 && (
                    <span className={styles.hpBonus}> (+{hpBonus})</span>
                  )}
                </span>
              )}
            </div>
          </div>

          {/* AC — display only in view, override in edit */}
          <div className={styles.vital}>
            <AcDisplay
              breakdown={acBreakdown}
              onOverride={handleAcOverride}
              mode={mode}
            />
          </div>

          {/* XP — click to edit */}
          <div className={styles.vital}>
            <div className={styles.hpValues}>
              <span className={styles.vitalLabel}>XP</span>
              <InlineNumber
                value={character.xp}
                onChange={(xp) => onUpdate(character.id, { xp })}
                className={`${styles.vitalValue} ${styles.xpCurrent}`}
                min={0}
              />
              <span className={styles.xpThreshold}>/ {xpThreshold}</span>
            </div>
          </div>

          {/* Luck token — always toggleable */}
          <div className={styles.vital}>
            <button
              className={styles.luckBtn}
              onClick={() =>
                onUpdate(character.id, {
                  luck_token: character.luck_token ? 0 : 1,
                })
              }
              title={
                character.luck_token
                  ? "Luck token available"
                  : "Luck token spent"
              }
            >
              {character.luck_token ? "\u2605" : "\u2606"}
            </button>
          </div>

          {/* Torch timer */}
          <div className={styles.vital}>
            <TorchTimer
              torchLitAt={character.torch_lit_at}
              onToggle={() => {
                const isLit = character.torch_lit_at !== null;
                onUpdate(character.id, {
                  torch_lit_at: isLit ? null : new Date().toISOString(),
                } as Partial<Character>);
              }}
            />
          </div>
        </div>
      </div>

      {/* THREE PANELS */}
      <div className={styles.panels}>
        <StatsPanel
          character={character}
          mode={mode}
          campaignId={campaignId}
          critKeys={critKeys}
          onStatChange={onStatChange}
        />
        <InfoPanel
          character={character}
          mode={mode}
          onUpdate={onUpdate}
          onAddTalent={onAddTalent}
          onRemoveTalent={onRemoveTalent}
        />
        <GearPanel
          character={character}
          mode={mode}
          onAddGearFromItem={onAddGearFromItem}
          onAddGearCustom={onAddGearCustom}
          onRemoveGear={onRemoveGear}
          onCurrencyChange={(charId, field, value) =>
            onUpdate(charId, { [field]: value })
          }
        />
      </div>

      {/* DELETE — edit mode only */}
      {mode === "edit" && (
        <div className={styles.deleteSection}>
          {confirmDelete ? (
            <div>
              <span>Delete {character.name}? </span>
              <button
                className={styles.deleteBtn}
                onClick={() => onDelete(character.id)}
              >
                Yes, delete
              </button>{" "}
              <button
                className={styles.deleteBtn}
                onClick={() => setConfirmDelete(false)}
              >
                Cancel
              </button>
            </div>
          ) : (
            <button
              className={styles.deleteBtn}
              onClick={() => setConfirmDelete(true)}
            >
              Delete Character
            </button>
          )}
        </div>
      )}
    </>
  );
}
