import { PrismaClient } from '@prisma/client'
import { PrismaLibSql } from '@prisma/adapter-libsql'
import { PrismaMariaDb } from '@prisma/adapter-mariadb'
import bcrypt from 'bcryptjs'

function createAdapter() {
  if (process.env.DB_PROVIDER === 'mysql') {
    return new PrismaMariaDb(process.env.DATABASE_URL!)
  }
  return new PrismaLibSql({ url: process.env.DATABASE_URL! })
}

const prisma = new PrismaClient({ adapter: createAdapter() })

async function main() {
  console.log('🌱 Starting seed...')

  // Clear existing data (in correct order due to foreign keys)
  await prisma.workoutLog.deleteMany()
  await prisma.assignedWorkout.deleteMany()
  await prisma.workoutExercise.deleteMany()
  await prisma.workoutTemplate.deleteMany()
  await prisma.exercise.deleteMany()
  await prisma.testimonial.deleteMany()
  await prisma.contactSubmission.deleteMany()
  // Don't delete sessions/accounts to avoid auth issues
  await prisma.user.deleteMany({ where: { role: 'member' } })

  const hashedPassword = await bcrypt.hash('password123', 10)
  const adminPassword = await bcrypt.hash('admin123', 10)

  // ============ ADMIN ============
  const admin = await prisma.user.upsert({
    where: { email: 'gillecamille@gmail.com' },
    update: { password: adminPassword },
    create: {
      email: 'gillecamille@gmail.com',
      name: 'Camille',
      password: adminPassword,
      role: 'admin',
    },
  })
  console.log('✅ Admin created:', admin.email)

  // ============ MEMBERS ============
  const marie = await prisma.user.create({
    data: {
      email: 'marie@test.com',
      name: 'Marie Dupont',
      password: hashedPassword,
      role: 'member',
    },
  })

  const thomas = await prisma.user.create({
    data: {
      email: 'thomas@test.com',
      name: 'Thomas Bernard',
      password: hashedPassword,
      role: 'member',
    },
  })

  const sophie = await prisma.user.create({
    data: {
      email: 'sophie@test.com',
      name: 'Sophie Laurent',
      password: hashedPassword,
      role: 'member',
    },
  })

  const lucas = await prisma.user.create({
    data: {
      email: 'lucas@test.com',
      name: 'Lucas Martin',
      password: hashedPassword,
      role: 'member',
    },
  })

  const emma = await prisma.user.create({
    data: {
      email: 'emma@test.com',
      name: 'Emma Petit',
      password: hashedPassword,
      role: 'member',
    },
  })

  console.log('✅ Members created: Marie, Thomas, Sophie, Lucas, Emma')

  // ============ EXERCISES ============
  const exercises = await Promise.all([
    prisma.exercise.create({
      data: {
        name: 'Développé couché',
        description: 'Exercice de base pour les pectoraux',
        mediaUrl: '/exercises/bench-press.gif',
        mediaType: 'gif',
        category: 'chest',
        createdBy: admin.id,
      },
    }),
    prisma.exercise.create({
      data: {
        name: 'Squat',
        description: 'Exercice fondamental pour les jambes',
        mediaUrl: '/exercises/squat.gif',
        mediaType: 'gif',
        category: 'legs',
        createdBy: admin.id,
      },
    }),
    prisma.exercise.create({
      data: {
        name: 'Rowing barre',
        description: 'Exercice pour le dos',
        mediaUrl: '/exercises/barbell-row.gif',
        mediaType: 'gif',
        category: 'back',
        createdBy: admin.id,
      },
    }),
    prisma.exercise.create({
      data: {
        name: 'Curl biceps',
        description: 'Isolation des biceps',
        mediaUrl: '/exercises/bicep-curl.gif',
        mediaType: 'gif',
        category: 'arms',
        createdBy: admin.id,
      },
    }),
    prisma.exercise.create({
      data: {
        name: 'Développé épaules',
        description: 'Exercice pour les épaules',
        mediaUrl: '/exercises/shoulder-press.gif',
        mediaType: 'gif',
        category: 'shoulders',
        createdBy: admin.id,
      },
    }),
    prisma.exercise.create({
      data: {
        name: 'Tractions',
        description: 'Exercice au poids du corps pour le dos',
        mediaUrl: '/exercises/pull-up.gif',
        mediaType: 'gif',
        category: 'back',
        createdBy: admin.id,
      },
    }),
    prisma.exercise.create({
      data: {
        name: 'Dips',
        description: 'Exercice au poids du corps pour triceps et pectoraux',
        mediaUrl: '/exercises/dips.gif',
        mediaType: 'gif',
        category: 'chest',
        createdBy: admin.id,
      },
    }),
    prisma.exercise.create({
      data: {
        name: 'Fentes',
        description: 'Exercice unilatéral pour les jambes',
        mediaUrl: '/exercises/lunges.gif',
        mediaType: 'gif',
        category: 'legs',
        createdBy: admin.id,
      },
    }),
    prisma.exercise.create({
      data: {
        name: 'Crunch',
        description: 'Exercice de base pour les abdominaux',
        mediaUrl: '/exercises/crunch.gif',
        mediaType: 'gif',
        category: 'core',
        createdBy: admin.id,
      },
    }),
    prisma.exercise.create({
      data: {
        name: 'Planche',
        description: 'Gainage pour le core',
        mediaUrl: '/exercises/plank.gif',
        mediaType: 'gif',
        category: 'core',
        createdBy: admin.id,
      },
    }),
  ])

  const [devCouche, squat, rowing, curl, devEpaules, tractions, dips, fentes, crunch, planche] = exercises
  console.log('✅ Exercises created:', exercises.length)

  // ============ WORKOUT TEMPLATES ============
  const fullBodyDebutant = await prisma.workoutTemplate.create({
    data: {
      title: 'Full Body Débutant',
      description: 'Programme complet pour débutants - 3x par semaine',
      estimatedDurationMin: 45,
      createdBy: admin.id,
      exercises: {
        create: [
          { exerciseId: squat.id, order: 0, targetSets: 3, targetReps: 10, targetWeight: 40, restBetweenSetsSec: 90, restAfterExerciseSec: 120, note: 'Garde le dos bien droit, descends jusqu\'aux cuisses parallèles au sol. Respire bien!' },
          { exerciseId: devCouche.id, order: 1, targetSets: 3, targetReps: 10, targetWeight: 30, restBetweenSetsSec: 90, restAfterExerciseSec: 120, note: 'Serre bien les omoplates, contrôle la descente. Ne rebondis pas sur la poitrine.' },
          { exerciseId: rowing.id, order: 2, targetSets: 3, targetReps: 10, targetWeight: 30, restBetweenSetsSec: 90, restAfterExerciseSec: 120, note: 'Tire les coudes vers l\'arrière, serre les omoplates en haut du mouvement.' },
          { exerciseId: devEpaules.id, order: 3, targetSets: 3, targetReps: 12, targetWeight: 16, restBetweenSetsSec: 60, restAfterExerciseSec: 90, note: 'Ne cambre pas le dos! Garde les abdos engagés.' },
          { exerciseId: curl.id, order: 4, targetSets: 3, targetReps: 12, targetWeight: 10, restBetweenSetsSec: 60, restAfterExerciseSec: 0, note: 'Pas de balancement, seuls les avant-bras bougent. Contrôle la phase négative.' },
        ],
      },
    },
  })

  const upperBody = await prisma.workoutTemplate.create({
    data: {
      title: 'Upper Body',
      description: 'Séance haut du corps',
      estimatedDurationMin: 50,
      createdBy: admin.id,
      exercises: {
        create: [
          { exerciseId: devCouche.id, order: 0, targetSets: 4, targetReps: 8, targetWeight: 50, restBetweenSetsSec: 120, restAfterExerciseSec: 150 },
          { exerciseId: rowing.id, order: 1, targetSets: 4, targetReps: 8, targetWeight: 45, restBetweenSetsSec: 120, restAfterExerciseSec: 150 },
          { exerciseId: devEpaules.id, order: 2, targetSets: 3, targetReps: 10, targetWeight: 24, restBetweenSetsSec: 90, restAfterExerciseSec: 120 },
          { exerciseId: tractions.id, order: 3, targetSets: 3, targetReps: 8, targetWeight: null, restBetweenSetsSec: 90, restAfterExerciseSec: 120, note: 'Poids du corps, utiliser assistance si nécessaire' },
          { exerciseId: dips.id, order: 4, targetSets: 3, targetReps: 10, targetWeight: null, restBetweenSetsSec: 90, restAfterExerciseSec: 90 },
          { exerciseId: curl.id, order: 5, targetSets: 3, targetReps: 12, targetWeight: 12, restBetweenSetsSec: 60, restAfterExerciseSec: 0 },
        ],
      },
    },
  })

  const lowerBody = await prisma.workoutTemplate.create({
    data: {
      title: 'Lower Body',
      description: 'Séance jambes intensive',
      estimatedDurationMin: 55,
      createdBy: admin.id,
      exercises: {
        create: [
          { exerciseId: squat.id, order: 0, targetSets: 4, targetReps: 8, targetWeight: 60, restBetweenSetsSec: 150, restAfterExerciseSec: 180 },
          { exerciseId: fentes.id, order: 1, targetSets: 3, targetReps: 12, targetWeight: 20, restBetweenSetsSec: 90, restAfterExerciseSec: 120, note: '12 reps par jambe' },
          { exerciseId: squat.id, order: 2, targetSets: 3, targetReps: 15, targetWeight: 40, restBetweenSetsSec: 90, restAfterExerciseSec: 120, note: 'Série légère, focus sur la technique' },
          { exerciseId: crunch.id, order: 3, targetSets: 3, targetReps: 20, targetWeight: null, restBetweenSetsSec: 45, restAfterExerciseSec: 60 },
          { exerciseId: planche.id, order: 4, targetSets: 3, targetReps: 45, targetWeight: null, restBetweenSetsSec: 60, restAfterExerciseSec: 0, note: '45 secondes de maintien' },
        ],
      },
    },
  })

  const fullBodyAvance = await prisma.workoutTemplate.create({
    data: {
      title: 'Full Body Avancé',
      description: 'Programme intensif pour athlètes confirmés',
      estimatedDurationMin: 75,
      createdBy: admin.id,
      exercises: {
        create: [
          { exerciseId: squat.id, order: 0, targetSets: 5, targetReps: 5, targetWeight: 80, restBetweenSetsSec: 180, restAfterExerciseSec: 180 },
          { exerciseId: devCouche.id, order: 1, targetSets: 5, targetReps: 5, targetWeight: 70, restBetweenSetsSec: 180, restAfterExerciseSec: 180 },
          { exerciseId: tractions.id, order: 2, targetSets: 4, targetReps: 8, targetWeight: 10, restBetweenSetsSec: 120, restAfterExerciseSec: 150, note: 'Lestées avec 10kg' },
          { exerciseId: devEpaules.id, order: 3, targetSets: 4, targetReps: 8, targetWeight: 32, restBetweenSetsSec: 90, restAfterExerciseSec: 120 },
          { exerciseId: rowing.id, order: 4, targetSets: 4, targetReps: 8, targetWeight: 55, restBetweenSetsSec: 90, restAfterExerciseSec: 120 },
          { exerciseId: dips.id, order: 5, targetSets: 3, targetReps: 12, targetWeight: 10, restBetweenSetsSec: 90, restAfterExerciseSec: 90, note: 'Lestés avec 10kg' },
          { exerciseId: curl.id, order: 6, targetSets: 3, targetReps: 10, targetWeight: 14, restBetweenSetsSec: 60, restAfterExerciseSec: 60 },
          { exerciseId: planche.id, order: 7, targetSets: 3, targetReps: 60, targetWeight: null, restBetweenSetsSec: 60, restAfterExerciseSec: 0, note: '60 secondes' },
        ],
      },
    },
  })

  console.log('✅ Workout templates created: 4')

  // ============ HELPER FUNCTIONS ============
  const today = startOfDay(new Date())

  async function createCompletedWorkout(
    userId: string,
    templateId: string,
    daysAgo: number,
    exercises: { exerciseId: string; sets: number; reps: number; weight: number | null }[]
  ) {
    const date = subDays(today, daysAgo)
    const workout = await prisma.assignedWorkout.create({
      data: {
        userId,
        templateId,
        scheduledDate: date,
        scheduleType: 'once',
        status: 'completed',
        startedAt: date,
        completedAt: new Date(date.getTime() + 45 * 60 * 1000), // 45 min later
        assignedById: admin.id,
      },
    })

    for (const ex of exercises) {
      for (let setNum = 1; setNum <= ex.sets; setNum++) {
        await prisma.workoutLog.create({
          data: {
            assignedWorkoutId: workout.id,
            exerciseId: ex.exerciseId,
            setNumber: setNum,
            weightUsed: ex.weight,
            repsDone: ex.reps + Math.floor(Math.random() * 3) - 1, // ±1 rep variation
            loggedAt: date,
          },
        })
      }
    }
    return workout
  }

  function startOfDay(date: Date): Date {
    const d = new Date(date)
    d.setHours(0, 0, 0, 0)
    return d
  }

  function subDays(date: Date, days: number): Date {
    const d = new Date(date)
    d.setDate(d.getDate() - days)
    return d
  }

  function addDays(date: Date, days: number): Date {
    const d = new Date(date)
    d.setDate(d.getDate() + days)
    return d
  }

  // ============ MARIE - Active member with history ============
  // 5 completed workouts
  for (let i = 14; i >= 3; i -= 2) {
    await createCompletedWorkout(marie.id, fullBodyDebutant.id, i, [
      { exerciseId: squat.id, sets: 3, reps: 10, weight: 40 + Math.floor((14 - i) / 4) * 2.5 },
      { exerciseId: devCouche.id, sets: 3, reps: 10, weight: 30 },
      { exerciseId: rowing.id, sets: 3, reps: 10, weight: 30 },
      { exerciseId: devEpaules.id, sets: 3, reps: 12, weight: 16 },
      { exerciseId: curl.id, sets: 3, reps: 12, weight: 10 },
    ])
  }

  // Today's workout (pending)
  await prisma.assignedWorkout.create({
    data: {
      userId: marie.id,
      templateId: fullBodyDebutant.id,
      scheduledDate: today,
      scheduleType: 'once',
      status: 'pending',
      assignedById: admin.id,
    },
  })

  // Upcoming workouts
  await prisma.assignedWorkout.create({
    data: {
      userId: marie.id,
      templateId: upperBody.id,
      scheduledDate: addDays(today, 2),
      scheduleType: 'once',
      status: 'pending',
      assignedById: admin.id,
    },
  })

  await prisma.assignedWorkout.create({
    data: {
      userId: marie.id,
      templateId: lowerBody.id,
      scheduledDate: addDays(today, 4),
      scheduleType: 'once',
      status: 'pending',
      assignedById: admin.id,
    },
  })

  console.log('✅ Marie: 5 completed, 1 today, 2 upcoming')

  // ============ THOMAS - Workout in progress ============
  // 3 completed workouts
  for (let i = 10; i >= 4; i -= 3) {
    await createCompletedWorkout(thomas.id, upperBody.id, i, [
      { exerciseId: devCouche.id, sets: 4, reps: 8, weight: 50 },
      { exerciseId: rowing.id, sets: 4, reps: 8, weight: 45 },
      { exerciseId: devEpaules.id, sets: 3, reps: 10, weight: 24 },
      { exerciseId: tractions.id, sets: 3, reps: 8, weight: null },
      { exerciseId: dips.id, sets: 3, reps: 10, weight: null },
      { exerciseId: curl.id, sets: 3, reps: 12, weight: 12 },
    ])
  }

  // Today's workout - IN PROGRESS with partial logs
  const thomasInProgress = await prisma.assignedWorkout.create({
    data: {
      userId: thomas.id,
      templateId: upperBody.id,
      scheduledDate: today,
      scheduleType: 'once',
      status: 'in_progress',
      startedAt: new Date(today.getTime() + 10 * 60 * 60 * 1000), // Started 10am today
      assignedById: admin.id,
    },
  })

  // Partial logs (2 exercises completed, mid-workout)
  for (let setNum = 1; setNum <= 4; setNum++) {
    await prisma.workoutLog.create({
      data: {
        assignedWorkoutId: thomasInProgress.id,
        exerciseId: devCouche.id,
        setNumber: setNum,
        weightUsed: 52.5,
        repsDone: setNum <= 2 ? 8 : 7,
        loggedAt: today,
      },
    })
  }

  for (let setNum = 1; setNum <= 2; setNum++) {
    await prisma.workoutLog.create({
      data: {
        assignedWorkoutId: thomasInProgress.id,
        exerciseId: rowing.id,
        setNumber: setNum,
        weightUsed: 47.5,
        repsDone: 8,
        loggedAt: today,
      },
    })
  }

  console.log('✅ Thomas: 3 completed, 1 in_progress (partially logged)')

  // ============ SOPHIE - New member, no workouts ============
  // Nothing to create, just the user exists
  console.log('✅ Sophie: New member (no workouts)')

  // ============ LUCAS - Missed workouts ============
  // 1 completed workout
  await createCompletedWorkout(lucas.id, fullBodyDebutant.id, 7, [
    { exerciseId: squat.id, sets: 3, reps: 10, weight: 35 },
    { exerciseId: devCouche.id, sets: 3, reps: 10, weight: 25 },
    { exerciseId: rowing.id, sets: 3, reps: 10, weight: 25 },
    { exerciseId: devEpaules.id, sets: 3, reps: 12, weight: 14 },
    { exerciseId: curl.id, sets: 3, reps: 12, weight: 8 },
  ])

  // 2 skipped workouts
  await prisma.assignedWorkout.create({
    data: {
      userId: lucas.id,
      templateId: fullBodyDebutant.id,
      scheduledDate: subDays(today, 5),
      scheduleType: 'once',
      status: 'skipped',
      assignedById: admin.id,
    },
  })

  await prisma.assignedWorkout.create({
    data: {
      userId: lucas.id,
      templateId: fullBodyDebutant.id,
      scheduledDate: subDays(today, 3),
      scheduleType: 'once',
      status: 'skipped',
      assignedById: admin.id,
    },
  })

  // Tomorrow's workout
  await prisma.assignedWorkout.create({
    data: {
      userId: lucas.id,
      templateId: fullBodyDebutant.id,
      scheduledDate: addDays(today, 1),
      scheduleType: 'once',
      status: 'pending',
      assignedById: admin.id,
    },
  })

  console.log('✅ Lucas: 1 completed, 2 skipped, 1 tomorrow')

  // ============ EMMA - Heavy user ============
  // 12 completed workouts over the past month
  const emmaTemplates = [fullBodyAvance, upperBody, lowerBody, fullBodyAvance]
  for (let i = 0; i < 12; i++) {
    const template = emmaTemplates[i % emmaTemplates.length]
    const daysAgo = 28 - (i * 2)
    if (daysAgo > 0) {
      const baseWeight = 60 + i * 2 // Progressive overload

      await createCompletedWorkout(emma.id, template.id, daysAgo, [
        { exerciseId: squat.id, sets: 5, reps: 5, weight: baseWeight + 20 },
        { exerciseId: devCouche.id, sets: 5, reps: 5, weight: baseWeight + 10 },
        { exerciseId: tractions.id, sets: 4, reps: 8, weight: 10 },
        { exerciseId: devEpaules.id, sets: 4, reps: 8, weight: baseWeight / 2 },
        { exerciseId: rowing.id, sets: 4, reps: 8, weight: baseWeight - 5 },
        { exerciseId: dips.id, sets: 3, reps: 12, weight: 10 },
        { exerciseId: curl.id, sets: 3, reps: 10, weight: 14 },
        { exerciseId: planche.id, sets: 3, reps: 60, weight: null },
      ])
    }
  }

  // Weekly recurring workouts for the next 2 weeks
  for (let week = 0; week < 2; week++) {
    await prisma.assignedWorkout.create({
      data: {
        userId: emma.id,
        templateId: fullBodyAvance.id,
        scheduledDate: addDays(today, week * 7 + 1), // Monday
        scheduleType: 'weekly',
        status: 'pending',
        assignedById: admin.id,
      },
    })

    await prisma.assignedWorkout.create({
      data: {
        userId: emma.id,
        templateId: upperBody.id,
        scheduledDate: addDays(today, week * 7 + 3), // Wednesday
        scheduleType: 'weekly',
        status: 'pending',
        assignedById: admin.id,
      },
    })

    await prisma.assignedWorkout.create({
      data: {
        userId: emma.id,
        templateId: lowerBody.id,
        scheduledDate: addDays(today, week * 7 + 5), // Friday
        scheduleType: 'weekly',
        status: 'pending',
        assignedById: admin.id,
      },
    })
  }

  console.log('✅ Emma: 12 completed, 6 weekly recurring')

  // ============ TESTIMONIALS ============
  await prisma.testimonial.createMany({
    data: [
      {
        authorName: 'Marie D.',
        authorTitle: 'Cliente depuis 1 an',
        content: "Louis m'a aidée à transformer mon corps et ma confiance en moi. Ses programmes sont parfaitement adaptés à mes objectifs.",
        isFeatured: true,
        displayOrder: 1,
      },
      {
        authorName: 'Thomas B.',
        authorTitle: 'Client depuis 6 mois',
        content: "Un coaching personnalisé et un suivi impeccable. J'ai gagné 5kg de muscle en 6 mois grâce à ses conseils.",
        isFeatured: true,
        displayOrder: 2,
      },
      {
        authorName: 'Sophie L.',
        authorTitle: 'Cliente depuis 2 ans',
        content: "Le meilleur investissement que j'ai fait pour ma santé. Louis est professionnel, motivant et toujours disponible.",
        isFeatured: true,
        displayOrder: 3,
      },
      {
        authorName: 'Lucas M.',
        authorTitle: 'Client depuis 3 mois',
        content: "Après plusieurs tentatives en solo, j'ai enfin trouvé la motivation avec Louis. L'application est super pratique à la salle!",
        isFeatured: false,
        displayOrder: 4,
      },
      {
        authorName: 'Emma P.',
        authorTitle: 'Athlète confirmée',
        content: "Même avec mon niveau avancé, Louis a su me pousser plus loin. Ses programmes Full Body Avancé sont redoutables!",
        isFeatured: false,
        displayOrder: 5,
      },
    ],
  })

  console.log('✅ Testimonials created: 5')

  // ============ SUMMARY ============
  const memberCount = await prisma.user.count({ where: { role: 'member' } })
  const workoutCount = await prisma.assignedWorkout.count()
  const logCount = await prisma.workoutLog.count()

  console.log('')
  console.log('🎉 Seed completed!')
  console.log('==================')
  console.log(`👤 Members: ${memberCount}`)
  console.log(`🏋️ Assigned workouts: ${workoutCount}`)
  console.log(`📝 Workout logs: ${logCount}`)
  console.log('')
  console.log('Test accounts (password: password123):')
  console.log('  - marie@test.com (active, has workout today)')
  console.log('  - thomas@test.com (workout in progress)')
  console.log('  - sophie@test.com (new, no workouts)')
  console.log('  - lucas@test.com (missed workouts)')
  console.log('  - emma@test.com (heavy user)')
  console.log('')
  console.log('Admin account (password: admin123):')
  console.log('  - gillecamille@gmail.com')
}

main()
  .catch((e) => {
    console.error(e)
    process.exit(1)
  })
  .finally(async () => {
    await prisma.$disconnect()
  })
