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

const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;

export class TradeGoodEditorApplication extends HandlebarsApplicationMixin(ApplicationV2) {
    #good = null;
    #onSaved = null;

    static DEFAULT_OPTIONS = {
        id: "augur-nexus-trade-good-editor",
        classes: ["augur-nexus", "augur-theme-fantasy", "trade-good-editor-window"],
        tag: "div",
        window: { title: "Custom Trade Good", resizable: false, minimizable: true },
        position: { width: 520, height: 500 },
        actions: {
            pickCustomGoodImage: TradeGoodEditorApplication._onPickImage,
            saveCustomGood: TradeGoodEditorApplication._onSave,
            cancelCustomGood: TradeGoodEditorApplication._onCancel
        }
    };

    static PARTS = { content: { template: "modules/augur-nexus/templates/trade/trade-good-editor.hbs" } };

    static show({ good = null, onSaved = null } = {}) {
        const app = new this({ good, onSaved });
        app.render(true, { focus: true });
        return app;
    }

    constructor({ good = null, onSaved = null } = {}, options = {}) {
        super(options);
        this.#good = good ? foundry.utils.deepClone(good) : null;
        this.#onSaved = typeof onSaved === "function" ? onSaved : null;
    }

    get title() { return this.#good ? `Edit ${this.#good.name}` : "Add Custom Trade Good"; }

    async _prepareContext() {
        const good = this.#good || {
            name: "",
            familyId: "",
            tradeValue: 10,
            imageSrc: "",
            lot: { label: "", description: "", weightLb: 50 }
        };
        const goods = await TradeGoodsCatalog.getGoods({ includeArchived: true });
        const categoryValues = this.#options(goods.map(entry => entry.familyId));
        const categoryIsCustom = !categoryValues.includes(String(good.familyId || ""));
        return {
            good,
            categories: categoryValues.map(value => ({ value, label: this.#displayLabel(value), selected: value === good.familyId })),
            categoryIsCustom,
            categoryCustomValue: categoryIsCustom ? String(good.familyId || "") : ""
        };
    }

    _onRender(context, options) {
        super._onRender(context, options);
        if (this.window?.title) this.window.title.textContent = this.title;
        for (const select of this.element.querySelectorAll("[data-custom-good-preset]")) {
            select.addEventListener("change", () => this.#toggleCustomField(select));
            this.#toggleCustomField(select);
        }
    }

    static _onSave() { return this.#save(); }
    static _onCancel() { return this.close(); }

    static _onPickImage() {
        const input = this.element.querySelector('[name="imageSrc"]');
        const picker = new foundry.applications.apps.FilePicker.implementation({
            type: "image",
            current: "assets/",
            callback: src => {
                input.value = src;
                const image = this.element.querySelector("[data-custom-good-preview] img");
                if (image) image.src = src;
            }
        });
        return picker.browse();
    }

    async #save() {
        const value = name => this.element.querySelector(`[name="${name}"]`)?.value;
        const name = String(value("name") || "").trim();
        if (!name) return ui.notifications.warn("Give the custom trade good a name.");
        const tradeValue = Number(value("tradeValue"));
        if (!Number.isFinite(tradeValue) || tradeValue < 0) return ui.notifications.warn("Trade value must be zero or greater.");
        const selectedOrCustom = (presetName, customName, fallback) => {
            const preset = String(value(presetName) || "");
            return preset === "__custom__" ? String(value(customName) || fallback).trim() || fallback : preset || fallback;
        };
        const saved = await TradeGoodsCatalog.saveCustomGood({
            ...(this.#good || {}),
            name,
            imageSrc: String(value("imageSrc") || ""),
            familyId: selectedOrCustom("familyPreset", "familyCustom", "custom"),
            tradeValue,
            lot: {
                label: String(value("lotLabel") || `Lots of ${name}`).trim(),
                description: String(value("description") || "").trim(),
                weightLb: Math.max(0, Number(value("weightLb")) || 0)
            }
        });
        await this.#onSaved?.(saved);
        await this.close();
    }

    #options(values = []) {
        return [...new Set(values.map(value => String(value || "").trim()).filter(Boolean))]
            .sort((left, right) => left.localeCompare(right));
    }

    #displayLabel(value) {
        return String(value || "").replace(/-/g, " ").replace(/\b\w/g, letter => letter.toLocaleUpperCase());
    }

    #toggleCustomField(select) {
        const input = this.element.querySelector(`[name="${select.dataset.customInput}"]`);
        if (!input) return;
        const custom = select.value === "__custom__";
        input.hidden = !custom;
        input.disabled = !custom;
        if (custom && document.activeElement === select) input.focus();
    }
}
