import { useState } from "react";
import socket from "../socket.js";
import type { CombatState, Character } from "../types.js";
import styles from "./InitiativeTracker.module.css";

interface InitiativeTrackerProps {
  combat: CombatState;
  characters: Character[];
  isDM: boolean;
  currentUserId: number | null;
  campaignId: number;
}

export default function InitiativeTracker({
  combat,
  characters,
  isDM,
  currentUserId,
  campaignId,
}: InitiativeTrackerProps) {
  const [addEnemyName, setAddEnemyName] = useState("");
  const [addEnemyHp, setAddEnemyHp] = useState("");
  const [showAddEnemy, setShowAddEnemy] = useState(false);

  const partyChars = characters.filter((c) => combat.character_ids.includes(c.id));

  const myCharIds = partyChars
    .filter((c) => c.user_id === currentUserId)
    .map((c) => c.id);

  function emitRoll(characterId: number) {
    const char = characters.find((c) => c.id === characterId);
    if (!char) return;
    socket.emit("initiative:roll", {
      campaignId,
      combatId: combat.id,
      characterId,
      characterName: char.name,
      characterColor: char.color,
    });
  }

  function emitEnemyRoll() {
    socket.emit("initiative:enemy-roll", { campaignId, combatId: combat.id });
  }

  function emitBegin() {
    socket.emit("initiative:begin", { campaignId, combatId: combat.id });
  }

  function emitNext() {
    socket.emit("initiative:next", { campaignId, combatId: combat.id });
  }

  function emitEnd() {
    socket.emit("initiative:end", { campaignId, combatId: combat.id });
  }

  function emitUpdateEnemyHp(enemyId: string, hp_current: number) {
    socket.emit("initiative:update-enemy", {
      campaignId,
      combatId: combat.id,
      enemyId,
      hp_current,
    });
  }

  function emitRemoveEnemy(enemyId: string) {
    socket.emit("initiative:remove-enemy", { campaignId, combatId: combat.id, enemyId });
  }

  function emitAddEnemy() {
    const hp = parseInt(addEnemyHp, 10);
    if (!addEnemyName.trim() || isNaN(hp) || hp < 1) return;
    socket.emit("initiative:add-enemy", {
      campaignId,
      combatId: combat.id,
      name: addEnemyName.trim(),
      hp_max: hp,
    });
    setAddEnemyName("");
    setAddEnemyHp("");
    setShowAddEnemy(false);
  }

  return (
    <div className={styles.tracker}>
      <div className={styles.header}>
        <span className={styles.title}>
          {combat.label ? combat.label : "Initiative"}
        </span>
        <span className={styles.round}>Round {combat.round}</span>
      </div>

      {combat.phase === "rolling" ? (
        <RollingPhase
          combat={combat}
          partyChars={partyChars}
          myCharIds={myCharIds}
          isDM={isDM}
          onRoll={emitRoll}
          onEnemyRoll={emitEnemyRoll}
          onBegin={emitBegin}
          onEnd={emitEnd}
        />
      ) : (
        <ActivePhase
          combat={combat}
          partyChars={partyChars}
          isDM={isDM}
          showAddEnemy={showAddEnemy}
          addEnemyName={addEnemyName}
          addEnemyHp={addEnemyHp}
          onSetShowAddEnemy={setShowAddEnemy}
          onSetAddEnemyName={setAddEnemyName}
          onSetAddEnemyHp={setAddEnemyHp}
          onUpdateEnemyHp={emitUpdateEnemyHp}
          onRemoveEnemy={emitRemoveEnemy}
          onAddEnemy={emitAddEnemy}
          onNext={emitNext}
          onEnd={emitEnd}
        />
      )}
    </div>
  );
}

// ── Rolling phase ────────────────────────────────────────────────────────

interface RollingPhaseProps {
  combat: CombatState;
  partyChars: Character[];
  myCharIds: number[];
  isDM: boolean;
  onRoll: (charId: number) => void;
  onEnemyRoll: () => void;
  onBegin: () => void;
  onEnd: () => void;
}

function RollingPhase({
  combat,
  partyChars,
  myCharIds,
  isDM,
  onRoll,
  onEnemyRoll,
  onBegin,
  onEnd,
}: RollingPhaseProps) {
  return (
    <>
      <div className={styles.phaseLabel}>Rolling Initiative…</div>

      <div className={styles.section}>
        <div className={styles.sectionLabel}>Party</div>
        {partyChars.map((c) => {
          const rolled = combat.party_rolls[c.id];
          const canRoll = myCharIds.includes(c.id) && rolled === undefined;
          return (
            <div key={c.id} className={styles.rollRow}>
              <span
                className={styles.dot}
                style={{ background: c.color }}
              />
              <span className={styles.rollName}>{c.name}</span>
              {rolled !== undefined ? (
                <span className={styles.rollValue}>{rolled}</span>
              ) : canRoll ? (
                <button
                  className={styles.rollBtn}
                  onClick={() => onRoll(c.id)}
                >
                  Roll d20
                </button>
              ) : (
                <span className={styles.rollPending}>—</span>
              )}
            </div>
          );
        })}
      </div>

      <div className={styles.section}>
        <div className={styles.sectionLabel}>Enemies</div>
        <div className={styles.rollRow}>
          <span className={styles.rollName}>Monsters</span>
          {combat.enemy_roll !== null ? (
            <span className={styles.rollValue}>{combat.enemy_roll}</span>
          ) : isDM ? (
            <button className={styles.rollBtn} onClick={onEnemyRoll}>
              Roll d20
            </button>
          ) : (
            <span className={styles.rollPending}>—</span>
          )}
        </div>
      </div>

      {isDM && (
        <div className={styles.footer}>
          <button
            className={styles.primaryBtn}
            disabled={combat.enemy_roll === null}
            onClick={onBegin}
          >
            Begin Combat ▶
          </button>
          <button className={styles.outlineBtn} onClick={onEnd}>
            Cancel
          </button>
        </div>
      )}
    </>
  );
}

// ── Active phase ─────────────────────────────────────────────────────────

interface ActivePhaseProps {
  combat: CombatState;
  partyChars: Character[];
  isDM: boolean;
  showAddEnemy: boolean;
  addEnemyName: string;
  addEnemyHp: string;
  onSetShowAddEnemy: (v: boolean) => void;
  onSetAddEnemyName: (v: string) => void;
  onSetAddEnemyHp: (v: string) => void;
  onUpdateEnemyHp: (enemyId: string, hp: number) => void;
  onRemoveEnemy: (enemyId: string) => void;
  onAddEnemy: () => void;
  onNext: () => void;
  onEnd: () => void;
}

function ActivePhase({
  combat,
  partyChars,
  isDM,
  showAddEnemy,
  addEnemyName,
  addEnemyHp,
  onSetShowAddEnemy,
  onSetAddEnemyName,
  onSetAddEnemyHp,
  onUpdateEnemyHp,
  onRemoveEnemy,
  onAddEnemy,
  onNext,
  onEnd,
}: ActivePhaseProps) {
  const partyActive = combat.current_side === "party";

  return (
    <>
      <div className={`${styles.section} ${partyActive ? styles.activeSection : ""}`}>
        <div className={styles.sectionLabel}>
          Party
          {combat.party_roll !== null && (
            <span className={styles.rollSummary}>
              {" "}({combat.party_roll} vs {combat.enemy_roll ?? "?"})
            </span>
          )}
        </div>
        {partyChars.map((c) => (
          <div key={c.id} className={styles.combatantRow}>
            <span className={styles.dot} style={{ background: c.color }} />
            <span className={partyActive ? styles.activeName : styles.rollName}>
              {c.name}
            </span>
          </div>
        ))}
      </div>

      <div className={`${styles.section} ${!partyActive ? styles.activeSection : ""}`}>
        <div className={styles.sectionLabel}>Enemies</div>
        {combat.enemies.map((e) => (
          <div key={e.id} className={styles.combatantRow}>
            <span className={styles.enemyDot} />
            <span className={!partyActive ? styles.activeName : styles.rollName}>
              {e.name}
            </span>
            {isDM && e.hp_current !== undefined && e.hp_max !== undefined && (
              <span className={styles.enemyHp}>
                <input
                  type="number"
                  className={styles.hpInput}
                  value={e.hp_current}
                  min={0}
                  onChange={(ev) => onUpdateEnemyHp(e.id, Number(ev.target.value))}
                />
                <span className={styles.hpMax}>/{e.hp_max}</span>
              </span>
            )}
            {isDM && (
              <button
                className={styles.removeBtn}
                onClick={() => onRemoveEnemy(e.id)}
                title="Remove"
              >
                ✕
              </button>
            )}
          </div>
        ))}

        {isDM && showAddEnemy && (
          <div className={styles.addEnemyForm}>
            <input
              className={styles.addEnemyInput}
              placeholder="Name"
              value={addEnemyName}
              onChange={(e) => onSetAddEnemyName(e.target.value)}
            />
            <input
              className={styles.addEnemyInput}
              placeholder="HP"
              type="number"
              min={1}
              value={addEnemyHp}
              onChange={(e) => onSetAddEnemyHp(e.target.value)}
            />
            <button className={styles.primaryBtn} onClick={onAddEnemy}>
              Add
            </button>
            <button
              className={styles.outlineBtn}
              onClick={() => onSetShowAddEnemy(false)}
            >
              ✕
            </button>
          </div>
        )}
        {isDM && !showAddEnemy && (
          <button
            className={styles.addEnemyBtn}
            onClick={() => onSetShowAddEnemy(true)}
          >
            + Add Enemy
          </button>
        )}
      </div>

      {isDM && (
        <div className={styles.footer}>
          <button className={styles.primaryBtn} onClick={onNext}>
            Next Turn ▶
          </button>
          <button className={styles.outlineBtn} onClick={onEnd}>
            End
          </button>
        </div>
      )}
    </>
  );
}
