<?php
declare(strict_types=1);
require_once __DIR__ . '/_util.php';

$body = json_decode(file_get_contents('php://input') ?: '', true);
if (!$body) json_response(["error" => "Invalid JSON body"], 400);

$champId = safe_string($body['championId'] ?? '');
$questId = safe_string($body['questId'] ?? '');
$questType = safe_string($body['questType'] ?? 'daily'); // daily | random | bounty

if ($champId === '' || $questId === '') json_response(["error" => "Missing championId or questId"], 400);

$allowedChamps = ["mon","tue","wed","thu","fri","sat","sun"];
if (!in_array($champId, $allowedChamps, true)) json_response(["error"=>"Invalid championId"], 400);

$worldPath = data_path('world.json');
$world = read_json($worldPath);
if (!$world) json_response(["error"=>"Missing world.json"], 500);

$champPath = data_path("champions/$champId.json");
$champ = read_json($champPath);
if (!$champ) json_response(["error"=>"Missing champion file"], 500);

// Load quest catalogs
$dailies = read_json(data_path('quests/dailies.json')) ?? [];
$goals   = read_json(data_path('quests/goals.json')) ?? [];
$randomPool = read_json(data_path('quests/random_pool.json')) ?? [];

function index_by_id(array $arr): array {
  $m = [];
  foreach ($arr as $q) if (is_array($q) && isset($q['id'])) $m[$q['id']] = $q;
  return $m;
}
$dailyMap = index_by_id($dailies);
$goalMap = index_by_id($goals);
$randomMap = index_by_id($randomPool);

$date = today_ymd();
$now = iso_now();

$quest = null;

if ($questType === 'bounty') {
  $quest = $goalMap[$questId] ?? null;
  if (!$quest) json_response(["error"=>"Unknown bounty questId"], 404);

  // Ensure bounty state exists
  if (!isset($world['questState']['bounties'][$questId])) {
    $world['questState']['bounties'][$questId] = ["addedAt"=>$date, "claimed"=>false, "claimedBy"=>null, "claimedAt"=>null];
  }

  if (!empty($world['questState']['bounties'][$questId]['claimed'])) {
    json_response(["error"=>"Bounty already claimed", "claimedBy"=>$world['questState']['bounties'][$questId]['claimedBy']], 409);
  }

} elseif ($questType === 'random') {
  $quest = $randomMap[$questId] ?? null;
  if (!$quest) json_response(["error"=>"Unknown random questId"], 404);

  $todayIds = $world['dailyPicks']['byDate'][$date][$champId] ?? [];
  if (!in_array($questId, $todayIds, true)) {
    json_response(["error"=>"Random quest is not in today's picks"], 409);
  }

} else {
  $quest = $dailyMap[$questId] ?? null;
  if (!$quest) json_response(["error"=>"Unknown daily questId"], 404);
}

// Once-per-day protection (per champion)
$champ['history'] = $champ['history'] ?? [];
foreach ($champ['history'] as $h) {
  if (($h['questId'] ?? '') === $questId && strpos(($h['at'] ?? ''), $date) === 0) {
    json_response(["error"=>"Quest already completed today"], 409);
  }
}

// Rewards
$xp = (int)($quest['xp'] ?? 0);
$gold = (int)($quest['gold'] ?? 0);
$tags = ensure_array($quest['tagsOnComplete'] ?? []);

// Bounty overdue multiplier + claim + medal
if ($questType === 'bounty') {
  $state =& $world['questState']['bounties'][$questId];
  $addedAt = $state['addedAt'] ?? $date;

  $threshold = (int)($world['rules']['bounty']['overdueDaysThreshold'] ?? 14);
  $mult = (float)($world['rules']['bounty']['xpMultiplier'] ?? 2.5);

  $daysOverdue = (int)floor((strtotime($date) - strtotime($addedAt)) / 86400);
  if ($daysOverdue >= $threshold) {
    $xp = (int)round($xp * $mult);
  }

  $state['claimed'] = true;
  $state['claimedBy'] = $champId;
  $state['claimedAt'] = $now;

  if (isset($quest['medal']) && is_array($quest['medal'])) {
    $champ['medals'] = $champ['medals'] ?? [];
    $champ['medals'][] = [
      "id" => $quest['medal']['id'] ?? $questId,
      "name" => $quest['medal']['name'] ?? ($quest['title'] ?? $questId),
      "img" => $quest['medal']['img'] ?? "",
      "earnedAt" => $now,
      "note" => "Claimed bounty: " . ($quest['title'] ?? $questId)
    ];
  }
}

// Apply XP/Gold
$champ['xp'] = (int)($champ['xp'] ?? 0) + $xp;
$champ['gold'] = (int)($champ['gold'] ?? 0) + $gold;

// Record history
$champ['history'][] = [
  "questId" => $questId,
  "questType" => $questType,
  "title" => $quest['title'] ?? $questId,
  "xpGained" => $xp,
  "goldGained" => $gold,
  "at" => $now
];

// Tag ledger + combos
$world['dailyTagLedger']['byDate'][$date][$champId] = $world['dailyTagLedger']['byDate'][$date][$champId] ?? ["tags"=>[], "awardedCombos"=>[], "awardedMilestones"=>[]];
$ledger =& $world['dailyTagLedger']['byDate'][$date][$champId];

foreach ($tags as $t) {
  if (!in_array($t, $ledger['tags'], true)) $ledger['tags'][] = $t;
}

$awarded = $ledger['awardedCombos'] ?? [];
foreach (($world['combos'] ?? []) as $combo) {
  if (!is_array($combo)) continue;
  $comboId = $combo['id'] ?? '';
  if ($comboId === '') continue;

  $oncePerDay = !empty($combo['oncePerDay']);
  if ($oncePerDay && in_array($comboId, $awarded, true)) continue;

  $req = ensure_array($combo['requiresTags'] ?? []);
  $ok = true;
  foreach ($req as $rt) {
    if (!in_array($rt, $ledger['tags'], true)) { $ok = false; break; }
  }

  if ($ok) {
    $bonusXp = (int)($combo['bonusXp'] ?? 0);
    $bonusGold = (int)($combo['bonusGold'] ?? 0);
    $champ['xp'] += $bonusXp;
    $champ['gold'] += $bonusGold;

    $ledger['awardedCombos'][] = $comboId;

    if (isset($combo['medal']) && is_array($combo['medal'])) {
      $champ['medals'] = $champ['medals'] ?? [];
      $champ['medals'][] = [
        "id" => $combo['medal']['id'] ?? $comboId,
        "name" => $combo['medal']['name'] ?? ($combo['name'] ?? $comboId),
        "img" => $combo['medal']['img'] ?? "",
        "earnedAt" => $now,
        "note" => "Combo earned: " . ($combo['name'] ?? $comboId)
      ];
    }
  }
}

// Save
$world['lastSavedAt'] = $now;
write_json_atomic($worldPath, $world);
write_json_atomic($champPath, $champ);

json_response([
  "ok" => true,
  "champion" => $champ,
  "world" => $world,
  "completed" => [
    "questId" => $questId,
    "questType" => $questType,
    "xp" => $xp,
    "gold" => $gold,
    "tagsAdded" => $tags
  ]
]);