import 'dotenv/config';
import * as bcrypt from 'bcrypt';
import { PrismaClient } from '../src/generated/prisma/client.js';
import { PrismaPg } from '@prisma/adapter-pg';

const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });

async function main() {
  console.log('Seeding database...\n');

  // Create password hash
  const passwordHash = await bcrypt.hash('password123', 10);

  // Create Admin User
  const admin = await prisma.user.upsert({
    where: { email: 'admin@dimension47.local' },
    update: {},
    create: {
      username: 'admin',
      email: 'admin@dimension47.local',
      passwordHash,
      role: 'ADMIN',
    },
  });
  console.log('Created Admin:', admin.username);

  // Create GM User
  const gm = await prisma.user.upsert({
    where: { email: 'gm@dimension47.local' },
    update: {},
    create: {
      username: 'gamemaster',
      email: 'gm@dimension47.local',
      passwordHash,
      role: 'GM',
    },
  });
  console.log('Created GM:', gm.username);

  // Create Player Users
  const player1 = await prisma.user.upsert({
    where: { email: 'player1@dimension47.local' },
    update: {},
    create: {
      username: 'spieler1',
      email: 'player1@dimension47.local',
      passwordHash,
      role: 'PLAYER',
    },
  });
  console.log('Created Player:', player1.username);

  const player2 = await prisma.user.upsert({
    where: { email: 'player2@dimension47.local' },
    update: {},
    create: {
      username: 'spieler2',
      email: 'player2@dimension47.local',
      passwordHash,
      role: 'PLAYER',
    },
  });
  console.log('Created Player:', player2.username);

  // Create Test Campaign
  const campaign = await prisma.campaign.upsert({
    where: { id: '00000000-0000-0000-0000-000000000001' },
    update: {},
    create: {
      id: '00000000-0000-0000-0000-000000000001',
      name: 'Abendliche Schatten',
      description: 'Eine spannende Kampagne in der Welt von Golarion. Die Helden erkunden uralte Ruinen und stellen sich finsteren Mächten.',
      gmId: gm.id,
    },
  });
  console.log('Created Campaign:', campaign.name);

  // Add members to campaign
  await prisma.campaignMember.upsert({
    where: { campaignId_userId: { campaignId: campaign.id, userId: gm.id } },
    update: {},
    create: { campaignId: campaign.id, userId: gm.id },
  });

  await prisma.campaignMember.upsert({
    where: { campaignId_userId: { campaignId: campaign.id, userId: player1.id } },
    update: {},
    create: { campaignId: campaign.id, userId: player1.id },
  });

  await prisma.campaignMember.upsert({
    where: { campaignId_userId: { campaignId: campaign.id, userId: player2.id } },
    update: {},
    create: { campaignId: campaign.id, userId: player2.id },
  });
  console.log('Added members to campaign');

  // Create Test Characters
  const character1 = await prisma.character.upsert({
    where: { id: '00000000-0000-0000-0000-000000000101' },
    update: {},
    create: {
      id: '00000000-0000-0000-0000-000000000101',
      campaignId: campaign.id,
      ownerId: player1.id,
      name: 'Thorin Eisenschild',
      type: 'PC',
      level: 3,
      hpCurrent: 38,
      hpMax: 42,
      hpTemp: 0,
      ancestryId: 'dwarf',
      classId: 'fighter',
      backgroundId: 'warrior',
      experiencePoints: 1200,
    },
  });
  console.log('Created Character:', character1.name);

  // Add abilities for character1
  const abilities1 = [
    { ability: 'STR' as const, score: 18 },
    { ability: 'DEX' as const, score: 12 },
    { ability: 'CON' as const, score: 16 },
    { ability: 'INT' as const, score: 10 },
    { ability: 'WIS' as const, score: 14 },
    { ability: 'CHA' as const, score: 8 },
  ];

  for (const ab of abilities1) {
    await prisma.characterAbility.upsert({
      where: { characterId_ability: { characterId: character1.id, ability: ab.ability } },
      update: { score: ab.score },
      create: { characterId: character1.id, ability: ab.ability, score: ab.score },
    });
  }
  console.log('Added abilities to', character1.name);

  const character2 = await prisma.character.upsert({
    where: { id: '00000000-0000-0000-0000-000000000102' },
    update: {},
    create: {
      id: '00000000-0000-0000-0000-000000000102',
      campaignId: campaign.id,
      ownerId: player2.id,
      name: 'Elara Sternenlicht',
      type: 'PC',
      level: 3,
      hpCurrent: 24,
      hpMax: 28,
      hpTemp: 0,
      ancestryId: 'elf',
      classId: 'wizard',
      backgroundId: 'scholar',
      experiencePoints: 1200,
    },
  });
  console.log('Created Character:', character2.name);

  // Add abilities for character2
  const abilities2 = [
    { ability: 'STR' as const, score: 8 },
    { ability: 'DEX' as const, score: 14 },
    { ability: 'CON' as const, score: 12 },
    { ability: 'INT' as const, score: 18 },
    { ability: 'WIS' as const, score: 14 },
    { ability: 'CHA' as const, score: 12 },
  ];

  for (const ab of abilities2) {
    await prisma.characterAbility.upsert({
      where: { characterId_ability: { characterId: character2.id, ability: ab.ability } },
      update: { score: ab.score },
      create: { characterId: character2.id, ability: ab.ability, score: ab.score },
    });
  }
  console.log('Added abilities to', character2.name);

  // Create an NPC
  const npc = await prisma.character.upsert({
    where: { id: '00000000-0000-0000-0000-000000000201' },
    update: {},
    create: {
      id: '00000000-0000-0000-0000-000000000201',
      campaignId: campaign.id,
      ownerId: null,
      name: 'Meister Aldric',
      type: 'NPC',
      level: 5,
      hpCurrent: 55,
      hpMax: 55,
      hpTemp: 0,
    },
  });
  console.log('Created NPC:', npc.name);

  // Create a second campaign
  const campaign2 = await prisma.campaign.upsert({
    where: { id: '00000000-0000-0000-0000-000000000002' },
    update: {},
    create: {
      id: '00000000-0000-0000-0000-000000000002',
      name: 'Die verlorene Stadt',
      description: 'Eine Expedition in die legendäre verlorene Stadt Xin-Shalast.',
      gmId: gm.id,
    },
  });
  console.log('Created Campaign:', campaign2.name);

  await prisma.campaignMember.upsert({
    where: { campaignId_userId: { campaignId: campaign2.id, userId: gm.id } },
    update: {},
    create: { campaignId: campaign2.id, userId: gm.id },
  });

  console.log('\n✅ Database seeded successfully!');
  console.log('\n📋 Test Accounts:');
  console.log('   Admin:    admin@dimension47.local / password123');
  console.log('   GM:       gm@dimension47.local / password123');
  console.log('   Player 1: player1@dimension47.local / password123');
  console.log('   Player 2: player2@dimension47.local / password123');
}

main()
  .catch((e) => {
    console.error('Seeding failed:', e);
    process.exit(1);
  })
  .finally(() => prisma.$disconnect());
