// SPDX-FileCopyrightText: 2021 Johannes Loher
// SPDX-FileCopyrightText: 2021 Oliver Rümpelein
// SPDX-FileCopyrightText: 2021 Gesina Schwalbe
//
// SPDX-License-Identifier: MIT

import { ModifiableDataBase } from "../common/common-data";
import { DS4 } from "../config";

export type ItemType = keyof typeof DS4.i18n.itemTypes;

export type DS4ItemData =
    | DS4WeaponData
    | DS4ArmorData
    | DS4ShieldData
    | DS4SpellData
    | DS4EquipmentData
    | DS4LootData
    | DS4TalentData
    | DS4RacialAbilityData
    | DS4LanguageData
    | DS4AlphabetData
    | DS4SpecialCreatureAbilityData;

export interface DS4ItemDataHelper<T, U extends ItemType> extends Item.Data<T> {
    type: U;
}

type DS4WeaponData = DS4ItemDataHelper<DS4WeaponDataData, "weapon">;
type DS4ArmorData = DS4ItemDataHelper<DS4ArmorDataData, "armor">;
type DS4ShieldData = DS4ItemDataHelper<DS4ShieldDataData, "shield">;
type DS4SpellData = DS4ItemDataHelper<DS4SpellDataData, "spell">;
type DS4EquipmentData = DS4ItemDataHelper<DS4EquipmentDataData, "equipment">;
type DS4LootData = DS4ItemDataHelper<DS4LootDataData, "loot">;
type DS4TalentData = DS4ItemDataHelper<DS4TalentDataData, "talent">;
type DS4RacialAbilityData = DS4ItemDataHelper<DS4RacialAbilityDataData, "racialAbility">;
type DS4LanguageData = DS4ItemDataHelper<DS4LanguageDataData, "language">;
type DS4AlphabetData = DS4ItemDataHelper<DS4AlphabetDataData, "alphabet">;
type DS4SpecialCreatureAbilityData = DS4ItemDataHelper<DS4SpecialCreatureAbilityDataData, "specialCreatureAbility">;

// templates

interface DS4ItemDataDataBase {
    description: string;
}
interface DS4ItemDataDataPhysical {
    quantity: number;
    price: number;
    availability: keyof typeof DS4.i18n.itemAvailabilities;
    storageLocation: string;
}

export function isDS4ItemDataTypePhysical(input: DS4ItemData["data"]): boolean {
    return "quantity" in input && "price" in input && "availability" in input && "storageLocation" in input;
}

interface DS4ItemDataDataEquipable {
    equipped: boolean;
}

interface DS4ItemDataDataProtective {
    armorValue: number;
}

export interface UnitData<UnitType> {
    value: string;
    unit: UnitType;
}
export type TemporalUnit = keyof typeof DS4.i18n.temporalUnits;
type CustomTemporalUnit = keyof typeof DS4.i18n.customTemporalUnits;
type DistanceUnit = keyof typeof DS4.i18n.distanceUnits;

// types

export interface DS4WeaponDataData extends DS4ItemDataDataBase, DS4ItemDataDataPhysical, DS4ItemDataDataEquipable {
    attackType: AttackType;
    weaponBonus: number;
    opponentDefense: number;
}

export type AttackType = keyof typeof DS4.i18n.attackTypes;

export interface DS4ArmorDataData
    extends DS4ItemDataDataBase,
        DS4ItemDataDataPhysical,
        DS4ItemDataDataEquipable,
        DS4ItemDataDataProtective {
    armorMaterialType: keyof typeof DS4.i18n.armorMaterialTypes;
    armorType: keyof typeof DS4.i18n.armorTypes;
}

export interface DS4TalentDataData extends DS4ItemDataDataBase {
    rank: DS4TalentRank;
}

export interface DS4TalentRank extends ModifiableDataBase<number> {
    max: number;
}

export interface DS4SpellDataData extends DS4ItemDataDataBase, DS4ItemDataDataEquipable {
    spellType: keyof typeof DS4.i18n.spellTypes;
    bonus: string;
    spellCategory: keyof typeof DS4.i18n.spellCategories;
    maxDistance: UnitData<DistanceUnit>;
    effectRadius: UnitData<DistanceUnit>;
    duration: UnitData<CustomTemporalUnit>;
    cooldownDuration: UnitData<TemporalUnit>;
    minimumLevels: {
        healer: number | null;
        wizard: number | null;
        sorcerer: number | null;
    };
}

export interface DS4ShieldDataData
    extends DS4ItemDataDataBase,
        DS4ItemDataDataPhysical,
        DS4ItemDataDataEquipable,
        DS4ItemDataDataProtective {}

export interface DS4EquipmentDataData extends DS4ItemDataDataBase, DS4ItemDataDataPhysical, DS4ItemDataDataEquipable {}

export interface DS4LootDataData extends DS4ItemDataDataBase, DS4ItemDataDataPhysical {}

export type DS4RacialAbilityDataData = DS4ItemDataDataBase;

export type DS4LanguageDataData = DS4ItemDataDataBase;

export type DS4AlphabetDataData = DS4ItemDataDataBase;

export interface DS4SpecialCreatureAbilityDataData extends DS4ItemDataDataBase {
    experiencePoints: number;
}