import {UtilApplications} from "./UtilApplications.js";
import {SharedConsts} from "../shared/SharedConsts.js";
import {Config} from "./Config.js";
import {DataConverter} from "./DataConverter.js";
import {Vetools} from "./Vetools.js";
import {UtilActiveEffects} from "./UtilActiveEffects.js";

class DataConverterFeat {
	/**
	 * @param feat
	 * @param [opts] Options object.
	 * @param [opts.isAddPermission]
	 * @param [opts.filterValues] Pre-baked filter values to be re-used when importing this from the item.
	 * @param [opts.isAddDataFlags]
	 * @param [opts.isActorItem]
	 */
	static async pGetFeatItem (feat, opts) {
		opts = opts || {};

		const content = DataConverter.getWithDescriptionPlugins(() => {
			const prerequisite = Renderer.utils.getPrerequisiteText(feat.prerequisite);
			Renderer.feat.mergeAbilityIncrease(feat);
			return `<div>
				${prerequisite ? `<p><i>Prerequisite: ${prerequisite}</i></p>` : ""}
				${Renderer.get().setFirstSection(true).render({entries: feat.entries}, 2)}
			</div>`
		});

		const img = (await DataConverter.pGetIconImage("feat", feat)) || `modules/${SharedConsts.MODULE_NAME}/media/icon/mighty-force.svg`;

		const additionalData = await this._pGetAdditionalData(feat);

		const out = {
			name: UtilApplications.getCleanEntityName(DataConverter.getNameWithSourcePart(feat, {isActorItem: opts.isActorItem})),
			data: {
				source: DataConverter.getSourceWithPagePart(feat),
				description: {
					value: Config.get("importFeat", "isImportDescription") ? content : "",
					chat: "",
					unidentified: "",
				},

				activation: {type: "", cost: 0, condition: ""},
				duration: {value: 0, units: ""},
				target: {value: 0, units: "", type: ""},
				range: {value: 0, long: 0, units: null},
				uses: {value: 0, max: 0, per: ""},
				ability: "",
				actionType: "",
				attackBonus: 0,
				chatFlavor: "",
				critical: null,
				damage: {parts: [], versatile: ""},
				formula: "",
				save: {ability: "", dc: null},
				requirements: "",
				recharge: {value: 0, charged: true},

				...additionalData,
			},
			permission: {default: 0},
			type: "feat",
			img,
			flags: this._getFeatFlags(feat, opts),
			effects: [],
		};

		if (opts.isAddPermission) out.permission = {default: Config.get("importFeat", "permissions")};

		return out;
	}

	static _getFeatFlags (feat, opts) {
		opts = opts || {};

		const out = {
			[SharedConsts.MODULE_NAME_FAKE]: {
				page: UrlUtil.PG_FEATS,
				source: feat.source,
				hash: UrlUtil.URL_TO_HASH_BUILDER[UrlUtil.PG_FEATS](feat),
			},
		};

		if (opts.isAddDataFlags) {
			out[SharedConsts.MODULE_NAME_FAKE].propDroppable = "feat";
			out[SharedConsts.MODULE_NAME_FAKE].filterValues = opts.filterValues;
		}

		return out;
	}

	static async pMutActorUpdateFeat (actor, actorUpdate, feat, dataBuilderOpts) {
		const sideData = await this.pGetSideData(feat);
		DataConverter.mutActorUpdate(actor, actorUpdate, feat, {sideData});
	}

	static async pGetSideData (feat) {
		return DataConverter.pGetSideData_(
			feat,
			{
				propBrew: "foundryFeat",
				fnLoadJson: Vetools.pGetRaceSideData,
				propJson: "feat",
			},
		);
	}

	static async _pGetAdditionalData (feat) {
		return DataConverter.pGetAdditionalData_(feat, {propBrew: "foundryFeat", fnLoadJson: Vetools.pGetFeatSideData, propJson: "feat"});
	}

	static async pHasFeatSideLoadedEffects (actor, feat) {
		return (await DataConverter.pGetAdditionalEffectsRaw_(feat, {propBrew: "foundryFeat", fnLoadJson: Vetools.pGetFeatSideData, propJson: "feat"}))?.length > 0;
	}

	static async pGetFeatItemEffects (actor, feat, sheetItem, {additionalData} = {}) {
		const effectsRaw = await DataConverter.pGetAdditionalEffectsRaw_(feat, {propBrew: "foundryFeat", fnLoadJson: Vetools.pGetFeatSideData, propJson: "feat"});
		return UtilActiveEffects.getExpandedEffects(effectsRaw || [], {actor, sheetItem, parentName: feat.name, additionalData});
	}
}

export {DataConverterFeat};
