import { TradeRegionSceneService } from "../services/TradeRegionSceneService.js";
import { TradeGoodsCatalog } from "../services/TradeGoodsCatalog.js";

const MODULE_ID = "augur-nexus";
export const MAX_MARKETPLACE_GOODS_PER_ROLE = 5;

export class SettlementMarketplaceModel {
    static isMarketplace(shop = {}) {
        return shop?.moduleData?.[MODULE_ID]?.marketplace?.enabled === true
            || shop?.source?.templateId === "settlement-marketplace";
    }

    static getRules(shop = {}, entity = {}) {
        const source = shop?.moduleData?.[MODULE_ID]?.marketplace || {};
        const schemaVersion = Number(source.schemaVersion || 0);
        const locationTypeId = TradeRegionSceneService.getLocationTypeId(entity);
        const marketRates = TradeGoodsCatalog.getMarketRates();
        const marketTier = String(entity?.moduleData?.[MODULE_ID]?.trade?.marketTier || locationTypeId || "outpost");
        const buysTradeGoodsByDefault = ["town", "city", "market", "hub", "settlement"].includes(marketTier);
        const importMultiplier = ["city", "hub"].includes(marketTier) ? marketRates.cityImportMultiplier : 1;
        const quantityMin = this.#integer(source.quantityMin, 1, 1, 99);
        return {
            regionalMultiplier: marketRates.sourceMultiplier,
            importMultiplier,
            buysTradeGoods: schemaVersion >= 5 && typeof source.buysTradeGoods === "boolean"
                ? source.buysTradeGoods
                : buysTradeGoodsByDefault,
            regionalVariety: this.#integer(source.regionalVariety, 2, 0, 10),
            quantityMin,
            quantityMax: this.#integer(source.quantityMax, 3, quantityMin, 99)
        };
    }

    static toModuleData(rules = {}) {
        const quantityMin = this.#integer(rules.quantityMin, 1, 1, 99);
        return {
            enabled: true,
            schemaVersion: 6,
            buysTradeGoods: rules.buysTradeGoods === true,
            regionalVariety: this.#integer(rules.regionalVariety, 2, 0, 10),
            quantityMin,
            quantityMax: this.#integer(rules.quantityMax, 3, quantityMin, 99)
        };
    }

    static getEconomy(entity = {}) {
        const source = entity?.economy || {};
        const produces = this.#entries(source.produces).slice(0, MAX_MARKETPLACE_GOODS_PER_ROLE);
        return {
            schemaVersion: 2,
            produces
        };
    }

    static async getEconomyView(entity = {}) {
        const economy = this.getEconomy(entity);
        const goods = await TradeGoodsCatalog.getGoodsForLocation(entity);
        const goodsById = new Map(goods.map(good => [good.id, good]));
        const produced = economy.produces.map(({ goodId }) => {
            const good = goodsById.get(goodId);
            return {
                id: goodId,
                name: good?.name || goodId,
                imageSrc: good?.imageSrc || "",
                tooltip: good?.lot?.description || good?.name || goodId
            };
        });
        return {
            produced,
            hasProduced: produced.length > 0,
            hasGoods: produced.length > 0
        };
    }

    static toEconomy(producedIds = []) {
        const produces = this.#ids(producedIds).slice(0, MAX_MARKETPLACE_GOODS_PER_ROLE);
        return {
            schemaVersion: 2,
            produces: produces.map(goodId => ({ goodId })),
            needs: []
        };
    }

    static #entries(entries = []) { return this.#ids((Array.isArray(entries) ? entries : []).map(entry => entry?.goodId)).map(goodId => ({ goodId })); }
    static #ids(values = []) { return [...new Set((Array.isArray(values) ? values : []).map(String).filter(Boolean))]; }
    static #integer(value, fallback, minimum, maximum) {
        const number = Number(value);
        const normalized = Number.isFinite(number) ? Math.floor(number) : Number(fallback);
        return Math.min(maximum, Math.max(minimum, normalized));
    }
}
