import type {
  BeastSnapshot,
  EntitySnapshot,
  HouseSnapshot,
  ResourceNodeSnapshot,
} from "../types";
import { TooltipLabel } from "./TooltipLabel";

type AgentPanelProps = {
  entity: EntitySnapshot | null;
  beast?: BeastSnapshot | null;
  resource?: ResourceNodeSnapshot | null;
  house?: HouseSnapshot | null;
  entities?: EntitySnapshot[];
  onSelectEntity?: (id: string) => void;
};

export function AgentPanel({
  entity,
  beast = null,
  resource = null,
  house = null,
  entities = [],
  onSelectEntity,
}: AgentPanelProps) {
  if (beast) {
    return <BeastPanel beast={beast} />;
  }
  if (resource) {
    return <ResourcePanel resource={resource} />;
  }
  if (house) {
    return <HousePanel house={house} entities={entities} onSelectEntity={onSelectEntity} />;
  }

  const selectedName = entity?.label ?? "No NPC";
  const selectedRole = entity
    ? [entity.country_id, entity.special_status ?? entity.role].filter(Boolean).join(" / ")
    : "world";

  return (
    <aside className="agentPanel" aria-label="Selected NPC">
      <div className="panelHeader">
        <TooltipLabel className="panelTitle" value={selectedName} />
        <TooltipLabel className="panelRole" value={selectedRole} />
      </div>
      {entity ? <AgentDetails entity={entity} /> : <EmptyAgentReadout />}
    </aside>
  );
}

function BeastPanel({ beast }: { beast: BeastSnapshot }) {
  const suffix = beast.id.replace(/^beast[_-]?/, "");
  const beastName = suffix ? `Beast ${suffix}` : "Beast";
  const healthLabel = `${beast.health} / ${beast.max_health} HP`;
  const positionLabel = `x ${beast.position.x.toFixed(1)} / z ${beast.position.z.toFixed(1)}`;

  return (
    <aside className="agentPanel" aria-label="Selected beast">
      <div className="panelHeader">
        <TooltipLabel className="panelTitle" value={beastName} />
        <TooltipLabel className="panelRole" value="beast" />
      </div>
      <div className="agentReadout">
        <TooltipLabel className="readoutCell healthCell" value={healthLabel} />
        <TooltipLabel className="readoutCell" value={beast.state} />
        <TooltipLabel
          className="readoutCell"
          value={beast.target_npc_id ? `hunting ${beast.target_npc_id}` : "no target"}
        />
        <TooltipLabel className="readoutCell" value={positionLabel} />
      </div>
    </aside>
  );
}

function ResourcePanel({ resource }: { resource: ResourceNodeSnapshot }) {
  const title = resource.type
    ? `${resource.type.charAt(0).toUpperCase()}${resource.type.slice(1)} node`
    : "Resource node";
  const amountLabel = resource.max_amount
    ? `${resource.amount} / ${resource.max_amount}`
    : `${resource.amount} left`;
  const positionLabel = `x ${resource.position.x.toFixed(1)} / z ${resource.position.z.toFixed(1)}`;

  return (
    <aside className="agentPanel" aria-label="Selected resource">
      <div className="panelHeader">
        <TooltipLabel className="panelTitle" value={title} />
        <TooltipLabel className="panelRole" value="resource" />
      </div>
      <div className="agentReadout">
        <TooltipLabel className="readoutCell" value={amountLabel} />
        <TooltipLabel className="readoutCell" value={resource.id} />
        <TooltipLabel className="readoutCell" value={positionLabel} />
      </div>
    </aside>
  );
}

type HousePanelProps = {
  house: HouseSnapshot;
  entities: EntitySnapshot[];
  onSelectEntity?: (id: string) => void;
};

function HousePanel({ house, entities, onSelectEntity }: HousePanelProps) {
  const isComplete = house.state === "completed";
  const suffix = house.id.replace(/^house[_-]?/, "");
  const title = suffix ? `Home ${suffix}` : "Home";
  const buildRatio = Math.min(1, house.build_progress / 10);
  const statusLabel = isComplete
    ? house.hp < house.max_hp
      ? "damaged"
      : "intact"
    : `building ${Math.round(buildRatio * 100)}%`;
  const positionLabel = `x ${house.position.x.toFixed(1)} / z ${house.position.z.toFixed(1)}`;

  return (
    <aside className="agentPanel" aria-label="Selected house">
      <div className="panelHeader">
        <TooltipLabel className="panelTitle" value={title} />
        <TooltipLabel className="panelRole" value={isComplete ? "home" : "construction"} />
      </div>
      <div className="agentReadout">
        <TooltipLabel className="readoutCell healthCell" value={`${house.hp} / ${house.max_hp} HP`} />
        <TooltipLabel className="readoutCell" value={statusLabel} />
        <TooltipLabel
          className="readoutCell"
          value={`inside ${house.occupant_ids.length}/${house.capacity}`}
        />
        <TooltipLabel className="readoutCell" value={positionLabel} />
      </div>
      <HouseResidentList
        label="Inside now"
        ids={house.occupant_ids}
        emptyLabel="nobody inside"
        entities={entities}
        onSelectEntity={onSelectEntity}
      />
      <HouseResidentList
        label="Owners"
        ids={house.owner_ids}
        emptyLabel="unclaimed"
        entities={entities}
        onSelectEntity={onSelectEntity}
      />
    </aside>
  );
}

type HouseResidentListProps = {
  label: string;
  ids: string[];
  emptyLabel: string;
  entities: EntitySnapshot[];
  onSelectEntity?: (id: string) => void;
};

function HouseResidentList({ label, ids, emptyLabel, entities, onSelectEntity }: HouseResidentListProps) {
  return (
    <div className="houseResidents" aria-label={label}>
      <span className="houseResidentsLabel">{label}</span>
      <div className="relationshipStrip houseResidentStrip">
        {ids.length === 0 ? (
          <span className="relationshipPill">{emptyLabel}</span>
        ) : (
          ids.map((id) => {
            const npc = entities.find((entity) => entity.id === id);
            return (
              <button
                key={id}
                type="button"
                className="relationshipPill houseResidentPill"
                onClick={() => onSelectEntity?.(id)}
                title={`Select ${npc?.label ?? id}`}
              >
                {npc?.label ?? id}
              </button>
            );
          })
        )}
      </div>
    </div>
  );
}

type AgentDetailsProps = {
  entity: EntitySnapshot;
};

function AgentDetails({ entity }: AgentDetailsProps) {
  return (
    <>
      <AgentReadout entity={entity} />
      <SurvivalReadout entity={entity} />
      <ThinkingBlock entity={entity} />
      <RelationshipList entity={entity} />
      <MemoryList entity={entity} />
    </>
  );
}

function SurvivalReadout({ entity }: { entity: EntitySnapshot }) {
  const { hunger, fear, safety, age, max_age, importance, goal, inventory } = entity.state;
  if (
    hunger === undefined &&
    fear === undefined &&
    safety === undefined &&
    age === undefined &&
    importance === undefined &&
    goal === undefined &&
    !inventory
  ) {
    return null;
  }

  const inventoryLabel = inventory
    ? `food ${inventory.food} / herbs ${inventory.herbs} / wood ${inventory.wood} / coins ${inventory.coins} / wpn ${inventory.weapon}`
    : "-";

  return (
    <div className="agentReadout">
      {hunger !== undefined ? (
        <TooltipLabel className="readoutCell" value={`Hunger ${hunger.toFixed(0)}`} />
      ) : null}
      {fear !== undefined ? (
        <TooltipLabel className="readoutCell" value={`Fear ${fear.toFixed(0)}`} />
      ) : null}
      {safety !== undefined ? (
        <TooltipLabel className="readoutCell" value={`Safety ${safety.toFixed(0)}`} />
      ) : null}
      {age !== undefined && max_age !== undefined ? (
        <TooltipLabel className="readoutCell" value={`Age ${age}/${max_age}`} />
      ) : null}
      {importance !== undefined ? (
        <TooltipLabel className="readoutCell" value={`Importance ${importance.toFixed(1)}`} />
      ) : null}
      {goal ? <TooltipLabel className="readoutCell" value={goal} /> : null}
      <TooltipLabel className="readoutCell" value={inventoryLabel} />
    </div>
  );
}

function AgentReadout({ entity }: { entity: EntitySnapshot }) {
  const selectedHealth = `${entity.state.health} / ${entity.state.max_health} HP`;
  const selectedAttackDamage = `DMG ${entity.state.attack_damage}`;
  const selectedPosition = `x ${entity.position.x.toFixed(1)} / z ${entity.position.z.toFixed(1)}`;

  return (
    <div className="agentReadout">
      <TooltipLabel className="readoutCell healthCell" value={selectedHealth} />
      <TooltipLabel className="readoutCell" value={selectedAttackDamage} />
      <TooltipLabel className="readoutCell" value={entity.state.intention} />
      <TooltipLabel className="readoutCell" value={selectedPosition} />
    </div>
  );
}

function ThinkingBlock({ entity }: { entity: EntitySnapshot }) {
  const reasoning = entity.state.last_reasoning;
  if (!reasoning || !reasoning.trim()) {
    return null;
  }
  const tick = entity.state.last_reasoning_tick;
  return (
    <div className="thinkingBlock" aria-label={`${entity.label} thinking`}>
      <TooltipLabel
        className="thinkingLabel"
        value={tick !== undefined && tick !== null ? `Thinking · tick ${tick}` : "Thinking"}
      />
      <p className="thinkingText">{reasoning}</p>
    </div>
  );
}

function RelationshipList({ entity }: { entity: EntitySnapshot }) {
  const relationships = Object.entries(entity.state.relationships ?? {})
    .sort((left, right) => Math.abs(right[1]) - Math.abs(left[1]) || left[0].localeCompare(right[0]))
    .slice(0, 3);

  if (relationships.length === 0) {
    return null;
  }

  return (
    <div className="relationshipStrip" aria-label={`${entity.label} relationships`}>
      {relationships.map(([id, trust]) => (
        <TooltipLabel
          key={id}
          className="relationshipPill"
          value={`${id} ${trust >= 0 ? "+" : ""}${trust.toFixed(2)}`}
        />
      ))}
    </div>
  );
}

function MemoryList({ entity }: { entity: EntitySnapshot }) {
  const recentEpisodes = entity.state.recent_episodes ?? [];

  return (
    <div className="memoryList" aria-label={`${entity.label} memories`}>
      {entity.state.memory_summary ? (
        <div className="memorySummary">
          <TooltipLabel className="memoryTick" value="Summary" />
          <p>{entity.state.memory_summary}</p>
        </div>
      ) : null}
      {recentEpisodes
        .slice()
        .reverse()
        .map((episode) => (
          <div className="memoryItem" key={`${episode.tick}-${episode.kind}-${episode.summary}`}>
            <TooltipLabel
              className="memoryTick"
              value={`Tick ${episode.tick} ${episode.kind}/${episode.perspective}`}
            />
            <p>{episode.summary}</p>
          </div>
        ))}
      {entity.state.memories
        .slice()
        .reverse()
        .map((memory) => (
          <div className="memoryItem" key={`${memory.tick}-${memory.text}`}>
            <TooltipLabel className="memoryTick" value={`Tick ${memory.tick}`} />
            <p>{memory.text}</p>
          </div>
        ))}
    </div>
  );
}

function EmptyAgentReadout() {
  return (
    <div className="agentReadout">
      <TooltipLabel className="readoutCell" value="waiting" />
    </div>
  );
}
