import type { ExploreCollectResponse } from "@elysium/types";
import { useState } from "react";
import { useGame } from "../../context/GameContext.js";
import { EXPLORATION_AREAS } from "../../data/explorations.js";
import { ZoneSelector } from "./ZoneSelector.js";

const formatDuration = (seconds: number): string => {
  if (seconds >= 86400) {
    const days = Math.floor(seconds / 86400);
    const hours = Math.floor((seconds % 86400) / 3600);
    return hours > 0 ? `${days}d ${hours}h` : `${days}d`;
  }
  if (seconds >= 3600) return `${Math.floor(seconds / 3600)}h ${Math.floor((seconds % 3600) / 60)}m`;
  if (seconds >= 60) return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
  return `${seconds}s`;
};

const timeRemaining = (startedAt: number, durationSeconds: number): number => {
  const elapsed = (Date.now() - startedAt) / 1000;
  return Math.max(0, durationSeconds - elapsed);
};

interface CollectResult {
  areaId: string;
  response: ExploreCollectResponse;
}

export const ExplorationPanel = (): React.JSX.Element => {
  const { state, startExploration, collectExploration, formatNumber } = useGame();
  const [activeZoneId, setActiveZoneId] = useState("verdant_vale");
  const [pendingAreaId, setPendingAreaId] = useState<string | null>(null);
  const [lastResult, setLastResult] = useState<CollectResult | null>(null);

  if (!state) return <section className="panel"><p>Loading...</p></section>;

  const zones = state.zones ?? [];
  const explorationState = state.exploration;

  const zoneAreas = EXPLORATION_AREAS.filter((a) => a.zoneId === activeZoneId);

  const hasActiveExploration =
    explorationState?.areas.some((a) => a.status === "in_progress") ?? false;

  const handleStart = async (areaId: string): Promise<void> => {
    setPendingAreaId(areaId);
    try {
      await startExploration(areaId);
    } finally {
      setPendingAreaId(null);
    }
  };

  const handleCollect = async (areaId: string): Promise<void> => {
    setPendingAreaId(areaId);
    try {
      const result = await collectExploration(areaId);
      setLastResult({ areaId, response: result });
    } finally {
      setPendingAreaId(null);
    }
  };

  return (
    <section className="panel exploration-panel">
      <div className="panel-header">
        <h2>🗺️ Exploration</h2>
      </div>

      {lastResult && (
        <div className="exploration-result">
          <button
            className="exploration-result-close"
            onClick={() => { setLastResult(null); }}
            type="button"
          >
            ✕
          </button>
          {lastResult.response.foundNothing ? (
            <p className="exploration-nothing">{lastResult.response.nothingMessage}</p>
          ) : (
            <>
              {lastResult.response.event && (
                <p className="exploration-event-text">{lastResult.response.event.text}</p>
              )}
              <div className="exploration-rewards">
                {(lastResult.response.event?.goldChange ?? 0) !== 0 && (
                  <span className={`reward-tag ${(lastResult.response.event?.goldChange ?? 0) > 0 ? "" : "negative"}`}>
                    🪙 {(lastResult.response.event?.goldChange ?? 0) > 0 ? "+" : ""}{formatNumber(lastResult.response.event?.goldChange ?? 0)} gold
                  </span>
                )}
                {(lastResult.response.event?.essenceChange ?? 0) > 0 && (
                  <span className="reward-tag">
                    ✨ +{formatNumber(lastResult.response.event?.essenceChange ?? 0)} essence
                  </span>
                )}
                {lastResult.response.event?.materialGained && (
                  <span className="reward-tag material-tag">
                    📦 +{lastResult.response.event.materialGained.quantity} {lastResult.response.event.materialGained.materialId.replace(/_/g, " ")} (event)
                  </span>
                )}
                {lastResult.response.materialsFound.map((m) => (
                  <span key={m.materialId} className="reward-tag material-tag">
                    📦 +{m.quantity} {m.materialId.replace(/_/g, " ")}
                  </span>
                ))}
              </div>
            </>
          )}
        </div>
      )}

      <ZoneSelector
        activeZoneId={activeZoneId}
        zones={zones}
        onSelectZone={(id) => { setActiveZoneId(id); setLastResult(null); }}
      />

      <div className="exploration-list">
        {zoneAreas.map((area) => {
          const areaState = explorationState?.areas.find((a) => a.id === area.id);
          const status = areaState?.status ?? "locked";
          const startedAt = areaState?.startedAt ?? 0;
          const isReady = status === "in_progress" && timeRemaining(startedAt, area.durationSeconds) <= 0;
          const isPending = pendingAreaId === area.id;

          return (
            <div key={area.id} className={`exploration-card exploration-${status}`}>
              <div className="exploration-info">
                <h3>
                  {area.name}
                  {areaState?.completedOnce && <span className="exploration-discovered"> 📖</span>}
                </h3>
                <p>{area.description}</p>
                <span className="exploration-duration">⏱️ {formatDuration(area.durationSeconds)}</span>
              </div>
              <div className="exploration-action">
                {status === "locked" && (
                  <span className="quest-badge locked">🔒 Locked</span>
                )}
                {status === "available" && (
                  <button
                    className="start-quest-button"
                    disabled={isPending || hasActiveExploration}
                    onClick={() => { void handleStart(area.id); }}
                    title={hasActiveExploration ? "An exploration is already in progress" : undefined}
                    type="button"
                  >
                    {isPending ? "Departing..." : `Explore (${formatDuration(area.durationSeconds)})`}
                  </button>
                )}
                {status === "in_progress" && !isReady && (
                  <span className="quest-badge active">
                    ⏳ {formatDuration(Math.ceil(timeRemaining(startedAt, area.durationSeconds)))} remaining
                  </span>
                )}
                {(status === "in_progress" && isReady) && (
                  <button
                    className="collect-button"
                    disabled={isPending}
                    onClick={() => { void handleCollect(area.id); }}
                    type="button"
                  >
                    {isPending ? "Collecting..." : "📦 Collect Results"}
                  </button>
                )}
              </div>
            </div>
          );
        })}
        {zoneAreas.length === 0 && (
          <p className="empty-zone">No exploration areas in this zone.</p>
        )}
      </div>
    </section>
  );
};
