import { firstPursuitScoutSourceBattleId, firstPursuitScoutVisitId } from '../data/firstPursuitScoutMemory'; import { firstPursuitScoutVisitDefinition, getFirstPursuitScoutVisitChoice, type FirstPursuitScoutVisitChoice } from '../data/firstPursuitScoutVisit'; import { applyCampVisitReward, getCampaignState, setCampaignState, type CampaignState } from './campaignState'; type FirstPursuitScoutActionFailure = | 'invalid-campaign' | 'invalid-choice' | 'already-completed' | 'save-unavailable'; export type FirstPursuitScoutActionResult = | { ok: true; choice: FirstPursuitScoutVisitChoice; campaign: CampaignState; } | { ok: false; reason: FirstPursuitScoutActionFailure; }; export function completeFirstPursuitScoutVisit( choiceId: string ): FirstPursuitScoutActionResult { let campaign: CampaignState; try { campaign = getCampaignState(); } catch { return { ok: false, reason: 'save-unavailable' }; } const settlement = campaign.battleHistory[firstPursuitScoutSourceBattleId]; const report = campaign.firstBattleReport; if ( campaign.step !== 'first-camp' || campaign.latestBattleId !== firstPursuitScoutSourceBattleId || settlement?.outcome !== 'victory' || report?.battleId !== firstPursuitScoutSourceBattleId || report.outcome !== 'victory' ) { return { ok: false, reason: 'invalid-campaign' }; } const choice = getFirstPursuitScoutVisitChoice(choiceId); if (!choice) { return { ok: false, reason: 'invalid-choice' }; } if (campaign.completedCampVisits.includes(firstPursuitScoutVisitId)) { return { ok: false, reason: 'already-completed' }; } let updated: CampaignState | undefined; try { updated = applyCampVisitReward( firstPursuitScoutVisitId, { bondId: firstPursuitScoutVisitDefinition.bondId, bondExp: choice.bondExp, itemRewards: [...choice.itemRewards] }, choice.id ); } catch { try { setCampaignState(campaign); } catch { // setCampaignState restores the in-memory snapshot before persistence. } return { ok: false, reason: 'save-unavailable' }; } if (!updated) { return { ok: false, reason: 'save-unavailable' }; } return { ok: true, choice, campaign: updated }; }