import FalukantPredefineFirstname from "../../models/falukant/predefine/firstname.js";
import FalukantPredefineLastname from "../../models/falukant/predefine/lastname.js";
import BranchType from "../../models/falukant/type/branch.js";
import ProductType from "../../models/falukant/type/product.js";
import FalukantStockType from "../../models/falukant/type/stock.js";
import TitleOfNobility from "../../models/falukant/type/title_of_nobility.js";
import TitleRequirement from "../../models/falukant/type/title_requirement.js";
import { sequelize } from "../sequelize.js";

export const initializeFalukantPredefines = async () => {
    await initializeFalukantFirstnames();
    await initializeFalukantLastnames();
    await initializeFalukantStockTypes();
    await initializeFalukantProducts();
    // initializeFalukantTitles() wurde nach initializeFalukantTypes.js verschoben
    await initializeFalukantTitleRequirements();
    await initializeFalukantBranchTypes();
    await initializeFalukantTownProductWorth();
}

const initializeFalukantFirstnames = async () => {
    await FalukantPredefineFirstname.bulkCreate([
        { name: "Alexander", gender: "male" },
        { name: "Ben", gender: "male" },
        { name: "Christian", gender: "male" },
        { name: "Daniel", gender: "male" },
        { name: "Elias", gender: "male" },
        { name: "Felix", gender: "male" },
        { name: "Gabriel", gender: "male" },
        { name: "Hans", gender: "male" },
        { name: "Ismail", gender: "male" },
        { name: "Jakob", gender: "male" },
        { name: "Kai", gender: "male" },
        { name: "Lukas", gender: "male" },
        { name: "Maximilian", gender: "male" },
        { name: "Niklas", gender: "male" },
        { name: "Oliver", gender: "male" },
        { name: "Paul", gender: "male" },
        { name: "Quentin", gender: "male" },
        { name: "Robert", gender: "male" },
        { name: "Sebastian", gender: "male" },
        { name: "Thomas", gender: "male" },
        { name: "Ulf", gender: "male" },
        { name: "Vincent", gender: "male" },
        { name: "Thorsten", gender: "male" },
        { name: "Ulrich", gender: "male" },
        { name: "Torben", gender: "male" },
        { name: "Torsten", gender: "male" },
        { name: "Uwe", gender: "male" },
        { name: "Viktor", gender: "male" },
        { name: "Wolfgang", gender: "male" },
        { name: "Xaver", gender: "male" },
        { name: "Yannik", gender: "male" },
        { name: "Zacharias", gender: "male" },
        { name: "Aaron", gender: "male" },
        { name: "Bruno", gender: "male" },
        { name: "Carl", gender: "male" },
        { name: "David", gender: "male" },
        { name: "Emil", gender: "male" },
        { name: "Fabian", gender: "male" },
        { name: "Georg", gender: "male" },
        { name: "Heinrich", gender: "male" },
        { name: "Ian", gender: "male" },
        { name: "Jonas", gender: "male" },
        { name: "Karl", gender: "male" },
        { name: "Leon", gender: "male" },
        { name: "Matthias", gender: "male" },
        { name: "Nils", gender: "male" },
        { name: "Oskar", gender: "male" },
        { name: "Peter", gender: "male" },
        { name: "Ralf", gender: "male" },
        { name: "Simon", gender: "male" },
        { name: "Tobias", gender: "male" },
        { name: "Ulrich", gender: "male" },
        { name: "Vince", gender: "male" },
        { name: "Walter", gender: "male" },
        { name: "Xeno", gender: "male" },
        { name: "Yves", gender: "male" },
        { name: "Zeno", gender: "male" },
        { name: "Anna", gender: "female" },
        { name: "Berit", gender: "female" },
        { name: "Charlotte", gender: "female" },
        { name: "Diana", gender: "female" },
        { name: "Emilia", gender: "female" },
        { name: "Fiona", gender: "female" },
        { name: "Greta", gender: "female" },
        { name: "Hanna", gender: "female" },
        { name: "Isabelle", gender: "female" },
        { name: "Johanna", gender: "female" },
        { name: "Katharina", gender: "female" },
        { name: "Lena", gender: "female" },
        { name: "Marie", gender: "female" },
        { name: "Nina", gender: "female" },
        { name: "Olivia", gender: "female" },
        { name: "Paula", gender: "female" },
        { name: "Quirina", gender: "female" },
        { name: "Rebecca", gender: "female" },
        { name: "Sophia", gender: "female" },
        { name: "Theresa", gender: "female" },
        { name: "Ulrike", gender: "female" },
        { name: "Valeria", gender: "female" },
        { name: "Wilma", gender: "female" },
        { name: "Xenia", gender: "female" },
        { name: "Yara", gender: "female" },
        { name: "Zoe", gender: "female" },
        { name: "Antonia", gender: "female" },
        { name: "Beate", gender: "female" },
        { name: "Carla", gender: "female" },
        { name: "Dorothea", gender: "female" },
        { name: "Elisabeth", gender: "female" },
        { name: "Franziska", gender: "female" },
        { name: "Gerda", gender: "female" },
        { name: "Helena", gender: "female" },
        { name: "Irene", gender: "female" },
        { name: "Julia", gender: "female" },
        { name: "Klara", gender: "female" },
        { name: "Leonie", gender: "female" },
        { name: "Marlene", gender: "female" },
        { name: "Nele", gender: "female" },
        { name: "Petra", gender: "female" },
        { name: "Renate", gender: "female" },
        { name: "Sandra", gender: "female" },
        { name: "Tanja", gender: "female" },
        { name: "Ursula", gender: "female" },
        { name: "Vanessa", gender: "female" },
        { name: "Waltraud", gender: "female" },
        { name: "Xaveria", gender: "female" },
        { name: "Yvonne", gender: "female" },
        { name: "Zora", gender: "female" },
    ], {
        ignoreDuplicates: true, 
    });
}

const initializeFalukantLastnames = async () => {
    await FalukantPredefineLastname.bulkCreate([
        { name: "Adler" },
        { name: "Bauer" },
        { name: "Becker" },
        { name: "Bergmann" },
        { name: "Braun" },
        { name: "Busch" },
        { name: "Dreyer" },
        { name: "Eberhardt" }, 
        { name: "Fischer" },
        { name: "Franke" },
        { name: "Friedrich" },
        { name: "Geiger" },
        { name: "Gärtner" },
        { name: "Hartmann" },
        { name: "Hoffmann" },
        { name: "Hofmann" },
        { name: "Horn" },
        { name: "Huber" },
        { name: "Jäger" },
        { name: "Jung" },
        { name: "Kaiser" },
        { name: "Keller" },
        { name: "Klein" },
        { name: "Koch" },
        { name: "König" },
        { name: "Krüger" },
        { name: "Lang" },
        { name: "Lehmann" },
        { name: "Ludwig" },
        { name: "Maier" },
        { name: "Meyer" },
        { name: "Müller" },
        { name: "Neumann" },
        { name: "Neff" },
        { name: "Obermeier" },
        { name: "Otto" },
        { name: "Peters" },
        { name: "Ritter" },
        { name: "Richter" },
        { name: "Rosen" },
        { name: "Schäfer" },
        { name: "Schmidt" },
        { name: "Schneider" },
        { name: "Schulz" },
        { name: "Schulze" },
        { name: "Schwarz" },
        { name: "Schuster" },
        { name: "Sommer" },
        { name: "Stein" },
        { name: "Tanner" },
        { name: "Thiel" },
        { name: "Ullmann" },
        { name: "Ullrich" },
        { name: "Vogel" },
        { name: "Voigt" },
        { name: "Wagner" },
        { name: "Walter" },
        { name: "Weber" },
        { name: "Weiß" },
        { name: "Winter" },
        { name: "Wolf" },
        { name: "Xaver" },
        { name: "Xavier" },
        { name: "Zimmer" },
        { name: "Zimmermann" },
        { name: "Albrecht" },
        { name: "Arnold" },
        { name: "Baumann" },
        { name: "Dietrich" }, 
        { name: "Engel" },
        { name: "Graf" },
        { name: "Kirsch" },
        { name: "Lenz" },
        { name: "Schirmer" },
        { name: "Vogt" },
        { name: "Ziegler" },
    ], {
        ignoreDuplicates: true,
    });
}

async function initializeFalukantStockTypes() {
    try {
        await FalukantStockType.bulkCreate([
            { labelTr: 'wood', cost: 15 },
            { labelTr: 'stone', cost: 25 },
            { labelTr: 'iron', cost: 100 },
            { labelTr: 'field', cost: 5 },
        ]);
    } catch (error) {
    }
}

async function initializeFalukantProducts() {
    // compute min/max cumulative tax across regions
    const taxRows = await sequelize.query(`
        WITH RECURSIVE ancestors AS (
          SELECT id AS start_id, id, parent_id, tax_percent FROM falukant_data.region
          UNION ALL
          SELECT a.start_id, r.id, r.parent_id, r.tax_percent
          FROM falukant_data.region r
          JOIN ancestors a ON r.id = a.parent_id
        ), totals AS (
          SELECT start_id, COALESCE(SUM(tax_percent), 0) AS total FROM ancestors GROUP BY start_id
        )
        SELECT COALESCE(MIN(total),0) AS min_total, COALESCE(MAX(total),0) AS max_total FROM totals
    `, { type: sequelize.QueryTypes.SELECT });

    const minTax = parseFloat(taxRows?.[0]?.min_total) || 0;
    const maxTax = parseFloat(taxRows?.[0]?.max_total) || 0;
    const factorMin = (minTax >= 100) ? 1 : (1 / (1 - minTax / 100));
    const factorMax = (maxTax >= 100) ? 1 : (1 / (1 - maxTax / 100));

    const baseProducts = [
        { labelTr: 'wheat', category: 1, productionTime: 2, sellCost: 7 },
        { labelTr: 'grain', category: 1, productionTime: 2, sellCost: 7 },
        { labelTr: 'carrot', category: 1, productionTime: 1, sellCost: 5},
        { labelTr: 'fish', category: 1, productionTime: 2, sellCost: 7 },
        { labelTr: 'meat', category: 1, productionTime: 2, sellCost: 7 },
        { labelTr: 'leather', category: 1, productionTime: 2, sellCost: 7 },
        { labelTr: 'wood', category: 1, productionTime: 2, sellCost: 7 },
        { labelTr: 'stone', category: 1, productionTime: 2, sellCost: 7 },
        { labelTr: 'milk', category: 1, productionTime: 1, sellCost: 6 },
        { labelTr: 'cheese', category: 1, productionTime: 1, sellCost: 6 },
        { labelTr: 'bread', category: 1, productionTime: 1, sellCost: 6 },
        { labelTr: 'beer', category: 2, productionTime: 3, sellCost: 6 },
        { labelTr: 'iron', category: 2, productionTime: 4, sellCost: 15 },
        { labelTr: 'copper', category: 2, productionTime: 4, sellCost: 15 },
        { labelTr: 'spices', category: 2, productionTime: 8, sellCost: 30 },
        { labelTr: 'salt', category: 2, productionTime: 4, sellCost: 15 },
        { labelTr: 'sugar', category: 2, productionTime: 4, sellCost: 15 },
        { labelTr: 'vinegar', category: 2, productionTime: 4, sellCost: 15 },
        { labelTr: 'cotton', category: 2, productionTime: 4, sellCost: 15 },
        { labelTr: 'wine', category: 2, productionTime: 4, sellCost: 15 },
        { labelTr: 'gold', category: 3, productionTime: 4, sellCost: 30 },
        { labelTr: 'diamond', category: 3, productionTime: 4, sellCost: 30 },
        { labelTr: 'furniture', category: 3, productionTime: 4, sellCost: 30 },
        { labelTr: 'clothing', category: 3, productionTime: 4, sellCost: 30 },
        { labelTr: 'jewelry', category: 4, productionTime: 5, sellCost: 60 },
        { labelTr: 'painting', category: 4, productionTime: 5, sellCost: 60 },
        { labelTr: 'book', category: 4, productionTime: 5, sellCost: 60 },
        { labelTr: 'weapon', category: 4, productionTime: 5, sellCost: 60 },
        { labelTr: 'armor', category: 4, productionTime: 5, sellCost: 60 },
        { labelTr: 'shield', category: 4, productionTime: 5, sellCost: 60 },
        { labelTr: 'horse', category: 5, productionTime: 5, sellCost: 60 },
        { labelTr: 'ox', category: 5, productionTime: 5, sellCost: 60 },
    ];

    const productsToInsert = baseProducts;

    await ProductType.bulkCreate(productsToInsert, {
        ignoreDuplicates: true,
    });
}

// Adelstitel-Initialisierung wurde nach initializeFalukantTypes.js verschoben

async function initializeFalukantTitleRequirements() {
    const titleRequirements = [
        { labelTr: "civil",     requirements: [{ type: "money",    value: 5000 }, { type: "cost", value: 500 }] },
        { labelTr: "sir",       requirements: [{ type: "branches", value: 2    }, { type: "cost", value: 1000 }] },
        { labelTr: "townlord",  requirements: [{ type: "cost",     value: 3000 }] },
        { labelTr: "by",        requirements: [{ type: "cost",     value: 6000 }] },
        { labelTr: "landlord",  requirements: [{ type: "cost",     value: 9000 }] },
        { labelTr: "knight",    requirements: [{ type: "cost",     value: 11000 }] },
        { labelTr: "baron",     requirements: [{ type: "branches", value: 4    }, { type: "cost", value: 15000 }] },
        { labelTr: "count",     requirements: [{ type: "cost",     value: 19000 }] },
        { labelTr: "palsgrave", requirements: [{ type: "cost",     value: 25000 }] },
        { labelTr: "margrave",  requirements: [{ type: "cost",     value: 33000 }] },
        { labelTr: "landgrave", requirements: [{ type: "cost",     value: 47000 }] },
        { labelTr: "ruler",     requirements: [{ type: "cost",     value: 66000 }] },
        { labelTr: "elector",   requirements: [{ type: "cost",     value: 79000 }] },
        { labelTr: "imperial-prince", requirements: [{ type: "cost", value: 99999 }] },
        { labelTr: "duke",      requirements: [{ type: "cost",     value: 130000 }] },
        { labelTr: "grand-duke",requirements: [{ type: "cost",     value: 170000 }] },
        { labelTr: "prince-regent", requirements: [{ type: "cost", value: 270000 }] },
        { labelTr: "king",      requirements: [{ type: "cost",     value: 500000 }] },
    ];

    const titles = await TitleOfNobility.findAll();
    const requirementsToInsert = [];

    for (let i = 0; i < titleRequirements.length; i++) {
        const titleReq = titleRequirements[i];
        const title = titles.find(t => t.labelTr === titleReq.labelTr);
        if (!title) continue;

        if (i > 1) {
            titleReq.requirements.push({
                type:  "money",
                value: 5000 * Math.pow(3, i - 1),
            });
        }

        for (const req of titleReq.requirements) {
            requirementsToInsert.push({
                titleId:          title.id,
                requirementType:  req.type,
                requirementValue: req.value,
            });
        }
    }

    await TitleRequirement.bulkCreate(requirementsToInsert, { ignoreDuplicates: true });
}

async function initializeFalukantBranchTypes() {
    await BranchType.bulkCreate([
        { labelTr: 'production', baseCost: 3000 },
        { labelTr: 'store', baseCost: 2000  },
        { labelTr: 'fullstack', baseCost: 4500},
    ], { ignoreDuplicates: true });
}

async function initializeFalukantTownProductWorth() {
    const deleteQuery = 'delete from \"falukant_data\".\"town_product_worth\"';
    const createQuery = 'insert into \"falukant_data\".\"town_product_worth\" (\"product_id\", \"region_id\", \"worth_percent\") \
                   select ftp.\"id\", fdr.\"id\", ROUND(40 + RANDOM() * 20) \
                   from \"falukant_type\".\"product\" ftp, \"falukant_data\".\"region\" fdr';
    sequelize.query(deleteQuery);
    sequelize.query(createQuery);   
}