import 'reflect-metadata';
import { AppDataSource } from './data-source';
import { Material } from '../material/material.entity';
import { Item } from '../item/item.entity';
import { Recipe } from '../craft/recipe.entity';
import { Monster } from '../monster/monster.entity';

// ──────────────────────────────────────────────
// MATÉRIAUX — 10 nouveaux (Égouts + Désert)
// ──────────────────────────────────────────────

const NEW_MATERIALS: Partial<Material>[] = [
  // Marais (Sprint 3 — re-seed si absents après migration MySQL)
  { name: 'Bave de Têtard',        description: 'Substance visqueuse sécrétée par les têtards vases.',       rarity: 'common' },
  { name: 'Écailles de Grenouille', description: 'Écailles dures et brillantes de grenouilles boueuses.',    rarity: 'common' },
  { name: 'Venin de Serpent',       description: 'Venin concentré extrait d\'un serpent des marais.',         rarity: 'rare' },
  { name: 'Spores Vénéneuses',     description: 'Spores toxiques récoltées sur les champi vénéneux.',        rarity: 'rare' },
  { name: 'Fragment de Boue',      description: 'Éclat de boue cristallisée prélevé sur un golem.',          rarity: 'common' },
  // Égouts
  { name: 'Poil de Rat',        description: 'Poil rêche arraché à un rat d\'égout. Sert de rembourrage.',    rarity: 'common' },
  { name: 'Gelée Toxique',      description: 'Substance corrosive récupérée sur un slime.',                   rarity: 'common' },
  { name: 'Fil de Soie Géant',  description: 'Fil incroyablement résistant tissé par une araignée géante.',   rarity: 'rare' },
  { name: 'Cuir de Croco',      description: 'Cuir épais et écailleux, presque impénétrable.',                rarity: 'rare' },
  { name: 'Couronne du Roi',    description: 'Couronne tordue portée par le Roi des Rats. Irradie de pouvoir.', rarity: 'epic' },
  // Désert
  { name: 'Dard de Scorpion',   description: 'Dard venimeux encore suintant.',                                rarity: 'common' },
  { name: 'Plume de Vautour',   description: 'Plume noire et résistante, légère comme le vent.',              rarity: 'common' },
  { name: 'Bandelette Maudite', description: 'Tissu ancien imprégné de magie noire.',                         rarity: 'rare' },
  { name: 'Sable Cristallisé',  description: 'Grain de sable fusionné en cristal par la chaleur du désert.',  rarity: 'rare' },
  { name: 'Œil du Sphinx',      description: 'Gemme mystique arrachée au Sphinx. Pulse d\'énergie ancienne.', rarity: 'epic' },
];

// ──────────────────────────────────────────────
// ITEMS CRAFTABLES — 12 nouveaux
// ──────────────────────────────────────────────

const NEW_ITEMS: Partial<Item>[] = [
  // Marais — Sprint 3 (re-seed si absents après migration MySQL)
  { name: 'Bâton de Roseau',   type: 'weapon',  rarity: 'common', attackBonus: 3,  buyPrice: 0, minLevel: 1, description: 'Un bâton taillé dans un roseau des marais.' },
  { name: 'Dague Rouillée',    type: 'weapon',  rarity: 'common', attackBonus: 5,  buyPrice: 0, minLevel: 1, description: 'Une dague usée mais encore tranchante.' },
  { name: 'Épée Courte',       type: 'weapon',  rarity: 'rare',   attackBonus: 9,  buyPrice: 0, minLevel: 3, description: 'Une épée courte bien équilibrée.' },
  { name: 'Gilet de Cuir',     type: 'armor',   rarity: 'common', defenseBonus: 3, buyPrice: 0, minLevel: 1, description: 'Un gilet de cuir tanné offrant une protection basique.' },
  { name: 'Cotte de Mailles',  type: 'armor',   rarity: 'rare',   defenseBonus: 7, buyPrice: 0, minLevel: 3, description: 'Une cotte de mailles robuste.' },
  // Marais (2 nouveaux)
  { name: 'Potion Antipoison',  type: 'consumable', rarity: 'common',  attackBonus: 0, defenseBonus: 0, forceBonus: 20,  buyPrice: 0, minLevel: 1, zone: null, description: 'Neutralise les poisons et restaure 20 endurance.' },
  { name: 'Bouclier de Boue',   type: 'armor',      rarity: 'common',  attackBonus: 0, defenseBonus: 4, buyPrice: 0, minLevel: 2, zone: 'marais', description: 'Forgé dans la boue cristallisée des golems.' },
  // Égouts (5 nouveaux)
  { name: 'Lame Empoisonnée',   type: 'weapon',     rarity: 'rare',    attackBonus: 11, defenseBonus: 0, buyPrice: 0, minLevel: 5, zone: 'egouts', description: 'Chaque coup inflige un poison insidieux.' },
  { name: 'Armure de Soie',     type: 'armor',      rarity: 'rare',    attackBonus: 0,  defenseBonus: 8, agiliteBonus: 2, buyPrice: 0, minLevel: 5, zone: 'egouts', description: 'Légère et résistante, tissée par des araignées géantes.' },
  { name: 'Plastron de Croco',  type: 'armor',      rarity: 'rare',    attackBonus: 0,  defenseBonus: 11, buyPrice: 0, minLevel: 7, zone: 'egouts', description: 'Cuir de crocodile assemblé en plastron imposant.' },
  { name: 'Grande Potion de Soin', type: 'consumable', rarity: 'rare', attackBonus: 0, defenseBonus: 0, forceBonus: 0, buyPrice: 0, minLevel: 4, zone: null, description: 'Restaure 80% des PV.' },
  { name: 'Épée du Roi',        type: 'weapon',     rarity: 'epic',    attackBonus: 16, defenseBonus: 0, buyPrice: 0, minLevel: 8, zone: 'egouts', description: 'Forgée avec la couronne du Roi des Rats.' },
  // Désert (5 nouveaux)
  { name: 'Dague du Scorpion',  type: 'weapon',     rarity: 'rare',    attackBonus: 14, defenseBonus: 0, buyPrice: 0, minLevel: 9, zone: 'desert', description: 'Le venin du scorpion suinte encore de la lame.' },
  { name: 'Cape du Vautour',    type: 'armor',      rarity: 'rare',    attackBonus: 0,  defenseBonus: 12, agiliteBonus: 3, buyPrice: 0, minLevel: 9, zone: 'desert', description: 'Cape de plumes noires, silencieuse et protectrice.' },
  { name: 'Armure de la Momie', type: 'armor',      rarity: 'epic',    attackBonus: 0,  defenseBonus: 16, buyPrice: 0, minLevel: 11, zone: 'desert', description: 'Bandelettes enchantées, dures comme le roc.' },
  { name: 'Lame du Désert',     type: 'weapon',     rarity: 'epic',    attackBonus: 22, defenseBonus: 0, buyPrice: 0, minLevel: 11, zone: 'desert', description: 'Cristal de sable fusionné en lame tranchante.' },
  { name: 'Sceptre Prophétique', type: 'weapon',    rarity: 'legendary', attackBonus: 30, defenseBonus: 0, intelligenceBonus: 5, buyPrice: 0, minLevel: 13, zone: 'desert', description: 'Seul artefact capable de canaliser la vision du Sphinx.' },
];

// ──────────────────────────────────────────────
// MONSTER → MATERIAL LOOT MAPPING
// ──────────────────────────────────────────────

const MONSTER_LOOT: Record<string, string> = {
  // Marais (re-seed si absents après migration MySQL)
  'Têtard Vase':       'Bave de Têtard',
  'Grenouille Boueuse': 'Écailles de Grenouille',
  'Serpent des Marais': 'Venin de Serpent',
  'Champi Vénéneux':   'Spores Vénéneuses',
  'Golem de Boue':     'Fragment de Boue',
  // Égouts
  'Rat d\'Égout':      'Poil de Rat',
  'Slime Toxique':     'Gelée Toxique',
  'Araignée Géante':   'Fil de Soie Géant',
  'Crocodile':         'Cuir de Croco',
  'Roi des Rats':      'Couronne du Roi',
  // Désert
  'Scorpion':          'Dard de Scorpion',
  'Vautour':           'Plume de Vautour',
  'Momie':             'Bandelette Maudite',
  'Ver des Sables':    'Sable Cristallisé',
  'Sphinx':            'Œil du Sphinx',
};

// ──────────────────────────────────────────────
// RECETTES — 12 nouvelles (nom ingrédient → résolu en runtime)
// ──────────────────────────────────────────────

interface RecipeDef {
  name: string;
  resultItemName: string;
  craftDurationSeconds: number;
  enduranceCost: number;
  ingredientNames: { materialName: string; quantity: number }[];
}

const NEW_RECIPES: RecipeDef[] = [
  // Marais — Sprint 3 (re-seed si absents)
  {
    name: 'Craft Dague Rouillée',
    resultItemName: 'Dague Rouillée',
    craftDurationSeconds: 15,
    enduranceCost: 8,
    ingredientNames: [
      { materialName: 'Bave de Têtard', quantity: 3 },
      { materialName: 'Écailles de Grenouille', quantity: 1 },
    ],
  },
  {
    name: 'Craft Gilet de Cuir',
    resultItemName: 'Gilet de Cuir',
    craftDurationSeconds: 30,
    enduranceCost: 10,
    ingredientNames: [
      { materialName: 'Écailles de Grenouille', quantity: 3 },
      { materialName: 'Fragment de Boue', quantity: 2 },
    ],
  },
  {
    name: 'Craft Épée Courte',
    resultItemName: 'Épée Courte',
    craftDurationSeconds: 60,
    enduranceCost: 15,
    ingredientNames: [
      { materialName: 'Venin de Serpent', quantity: 2 },
      { materialName: 'Fragment de Boue', quantity: 3 },
      { materialName: 'Écailles de Grenouille', quantity: 2 },
    ],
  },
  // Marais (2 nouveaux)
  {
    name: 'Craft Potion Antipoison',
    resultItemName: 'Potion Antipoison',
    craftDurationSeconds: 10,
    enduranceCost: 5,
    ingredientNames: [
      { materialName: 'Spores Vénéneuses', quantity: 2 },
      { materialName: 'Venin de Serpent', quantity: 1 },
    ],
  },
  {
    name: 'Craft Bouclier de Boue',
    resultItemName: 'Bouclier de Boue',
    craftDurationSeconds: 25,
    enduranceCost: 10,
    ingredientNames: [
      { materialName: 'Fragment de Boue', quantity: 4 },
      { materialName: 'Écailles de Grenouille', quantity: 2 },
    ],
  },
  // Égouts (5)
  {
    name: 'Craft Lame Empoisonnée',
    resultItemName: 'Lame Empoisonnée',
    craftDurationSeconds: 45,
    enduranceCost: 12,
    ingredientNames: [
      { materialName: 'Gelée Toxique', quantity: 2 },
      { materialName: 'Venin de Serpent', quantity: 1 },
      { materialName: 'Poil de Rat', quantity: 3 },
    ],
  },
  {
    name: 'Craft Armure de Soie',
    resultItemName: 'Armure de Soie',
    craftDurationSeconds: 60,
    enduranceCost: 14,
    ingredientNames: [
      { materialName: 'Fil de Soie Géant', quantity: 4 },
      { materialName: 'Poil de Rat', quantity: 2 },
    ],
  },
  {
    name: 'Craft Plastron de Croco',
    resultItemName: 'Plastron de Croco',
    craftDurationSeconds: 90,
    enduranceCost: 16,
    ingredientNames: [
      { materialName: 'Cuir de Croco', quantity: 3 },
      { materialName: 'Fragment de Boue', quantity: 2 },
      { materialName: 'Fil de Soie Géant', quantity: 1 },
    ],
  },
  {
    name: 'Craft Grande Potion de Soin',
    resultItemName: 'Grande Potion de Soin',
    craftDurationSeconds: 20,
    enduranceCost: 8,
    ingredientNames: [
      { materialName: 'Gelée Toxique', quantity: 2 },
      { materialName: 'Spores Vénéneuses', quantity: 2 },
    ],
  },
  {
    name: 'Craft Épée du Roi',
    resultItemName: 'Épée du Roi',
    craftDurationSeconds: 120,
    enduranceCost: 20,
    ingredientNames: [
      { materialName: 'Couronne du Roi', quantity: 1 },
      { materialName: 'Cuir de Croco', quantity: 3 },
      { materialName: 'Gelée Toxique', quantity: 2 },
    ],
  },
  // Désert (5)
  {
    name: 'Craft Dague du Scorpion',
    resultItemName: 'Dague du Scorpion',
    craftDurationSeconds: 60,
    enduranceCost: 14,
    ingredientNames: [
      { materialName: 'Dard de Scorpion', quantity: 3 },
      { materialName: 'Plume de Vautour', quantity: 2 },
    ],
  },
  {
    name: 'Craft Cape du Vautour',
    resultItemName: 'Cape du Vautour',
    craftDurationSeconds: 90,
    enduranceCost: 16,
    ingredientNames: [
      { materialName: 'Plume de Vautour', quantity: 4 },
      { materialName: 'Bandelette Maudite', quantity: 2 },
    ],
  },
  {
    name: 'Craft Armure de la Momie',
    resultItemName: 'Armure de la Momie',
    craftDurationSeconds: 150,
    enduranceCost: 20,
    ingredientNames: [
      { materialName: 'Bandelette Maudite', quantity: 3 },
      { materialName: 'Sable Cristallisé', quantity: 2 },
      { materialName: 'Cuir de Croco', quantity: 1 },
    ],
  },
  {
    name: 'Craft Lame du Désert',
    resultItemName: 'Lame du Désert',
    craftDurationSeconds: 180,
    enduranceCost: 22,
    ingredientNames: [
      { materialName: 'Sable Cristallisé', quantity: 3 },
      { materialName: 'Dard de Scorpion', quantity: 2 },
      { materialName: 'Bandelette Maudite', quantity: 1 },
    ],
  },
  {
    name: 'Craft Sceptre Prophétique',
    resultItemName: 'Sceptre Prophétique',
    craftDurationSeconds: 300,
    enduranceCost: 25,
    ingredientNames: [
      { materialName: 'Œil du Sphinx', quantity: 1 },
      { materialName: 'Sable Cristallisé', quantity: 3 },
      { materialName: 'Bandelette Maudite', quantity: 2 },
    ],
  },
];

// ──────────────────────────────────────────────
// SEED RUNNER
// ──────────────────────────────────────────────

async function seed() {
  await AppDataSource.initialize();
  console.log('DB connectée (MySQL)');

  const materialRepo = AppDataSource.getRepository(Material);
  const itemRepo = AppDataSource.getRepository(Item);
  const recipeRepo = AppDataSource.getRepository(Recipe);
  const monsterRepo = AppDataSource.getRepository(Monster);

  // 1. Seed matériaux
  console.log('\n── Matériaux ──');
  const materialMap: Record<string, string> = {};

  // Charger les matériaux existants dans le map
  const existingMats = await materialRepo.find();
  for (const mat of existingMats) {
    materialMap[mat.name] = mat.id;
  }

  for (const data of NEW_MATERIALS) {
    if (materialMap[data.name!]) {
      console.log(`⏭  ${data.name} (déjà présent)`);
      continue;
    }
    const mat = await materialRepo.save(materialRepo.create(data));
    materialMap[mat.name] = mat.id;
    console.log(`✅ ${data.name} (${data.rarity})`);
  }

  // 2. Seed items craftables
  console.log('\n── Items craftables ──');
  const itemMap: Record<string, string> = {};

  const existingItems = await itemRepo.find();
  for (const item of existingItems) {
    itemMap[item.name] = item.id;
  }

  for (const data of NEW_ITEMS) {
    if (itemMap[data.name!]) {
      console.log(`⏭  ${data.name} (déjà présent)`);
      continue;
    }
    const item = await itemRepo.save(itemRepo.create(data));
    itemMap[item.name] = item.id;
    console.log(`✅ ${data.name} (${data.rarity}, ${data.type})`);
  }

  // 3. Mapper les drops des monstres Égouts/Désert
  console.log('\n── Monster drops ──');
  for (const [monsterName, materialName] of Object.entries(MONSTER_LOOT)) {
    const materialId = materialMap[materialName];
    if (!materialId) {
      console.error(`❌ Matériau "${materialName}" introuvable pour ${monsterName}`);
      continue;
    }
    const monster = await monsterRepo.findOne({ where: { name: monsterName } });
    if (!monster) {
      console.error(`❌ Monstre "${monsterName}" introuvable`);
      continue;
    }
    if (monster.dropMaterialId === materialId) {
      console.log(`⏭  ${monsterName} → ${materialName} (déjà mappé)`);
      continue;
    }
    monster.dropMaterialId = materialId;
    await monsterRepo.save(monster);
    console.log(`✅ ${monsterName} → ${materialName}`);
  }

  // 4. Seed recettes
  console.log('\n── Recettes ──');
  for (const recipeDef of NEW_RECIPES) {
    const exists = await recipeRepo.findOne({ where: { name: recipeDef.name } });
    if (exists) {
      console.log(`⏭  ${recipeDef.name} (déjà présente)`);
      continue;
    }

    const resultItemId = itemMap[recipeDef.resultItemName];
    if (!resultItemId) {
      console.error(`❌ Item "${recipeDef.resultItemName}" introuvable pour recette ${recipeDef.name}`);
      continue;
    }

    const ingredients = recipeDef.ingredientNames.map((ing) => {
      const matId = materialMap[ing.materialName];
      if (!matId) {
        throw new Error(`Matériau "${ing.materialName}" introuvable pour recette ${recipeDef.name}`);
      }
      return { materialId: matId, quantity: ing.quantity };
    });

    await recipeRepo.save(
      recipeRepo.create({
        name: recipeDef.name,
        resultItemId,
        craftDurationSeconds: recipeDef.craftDurationSeconds,
        enduranceCost: recipeDef.enduranceCost,
        ingredients,
      }),
    );
    console.log(`✅ ${recipeDef.name} (${recipeDef.ingredientNames.length} ingrédients, ${recipeDef.craftDurationSeconds}s)`);
  }

  // Résumé
  const totalMats = await materialRepo.count();
  const totalItems = await itemRepo.count();
  const totalRecipes = await recipeRepo.count();
  const monstersWithDrop = await monsterRepo.count({ where: { dropMaterialId: undefined } as any });
  const totalMonsters = await monsterRepo.count();

  console.log(`\n✅ Seed craft/drops terminé`);
  console.log(`   Matériaux: ${totalMats} | Items: ${totalItems} | Recettes: ${totalRecipes} | Monstres: ${totalMonsters}`);

  await AppDataSource.destroy();
}

seed().catch((err) => {
  console.error('Seed craft/drops échoué :', err);
  process.exit(1);
});
