import { WORLDMAP_TYPES, type OasisType, type RegionType } from "./types";
import { assert, getUnitSource } from "./utils";
import type { VillageState } from "./village";


export function resolveMission(V: VillageState, region: RegionType) {
    assert(region.type === WORLDMAP_TYPES.OASIS);

    const mission = region.state.mission;
    if (!mission) {
        return;
    }

    switch (mission.type) {
        case 'pillage':
            if (region.type === WORLDMAP_TYPES.OASIS) {
                resolvePillageOasis(V, region);
            }
            break;
        case 'clear':
            if (region.type === WORLDMAP_TYPES.OASIS) {
                resolveClearOasis(V, region);
            }
            break;
        default:
            throw new Error(`Unknown mission type: "${ mission.type }"`);
    }

    if (mission.repeat) {
        mission.remainingTime = 1 * 10 * 1000;
    }
    else {
        delete region.state.mission;
    }
}


function resolveClearOasis(V: VillageState, region: OasisType) {
    const mission = region.state.mission;
    if (!mission) {
        return;
    }

    const ratio = mission.unitCount / region.strength;
    const lostRatio = 1 / (ratio * ratio);
    const lostUnits = Math.min(
        Math.round(mission.unitCount * lostRatio),
        mission.unitCount
    );

    mission.unitCount -= lostUnits;
    V.units.soldier -= lostUnits;

    if (ratio >= 1) {
        region.state.cleared = true;
    }

    const unit = getUnitSource('soldier');
    const maxResources = region.distance * region.distance * 100;

    V.resources[region.resource] += Math.min(
        mission.unitCount * unit.behavior.caryingCapacity,
        maxResources
    );
}


function resolvePillageOasis(V: VillageState, region: OasisType) {
    const mission = region.state.mission;
    if (!mission) {
        return;
    }

    const unit = getUnitSource('soldier');
    const maxResources = region.distance * region.distance * 100;

    V.resources[region.resource] += Math.min(
        mission.unitCount * unit.behavior.caryingCapacity,
        maxResources
    );
}
