import { PrismaClient, Prisma, UserRole, FunnelStage, TrainingStatus, SaleStatus, NotificationType, LicenseType } from '@prisma/client';
import * as bcrypt from 'bcrypt';

const prisma = new PrismaClient();

async function main() {
  console.log('=== MyFitCRM: Запуск сидирования базы данных ===\n');

  // ---------------------------------------------------------------------------
  // 1. Клуб
  // ---------------------------------------------------------------------------
  console.log('1. Создание клуба...');
  const club = await prisma.club.upsert({
    where: { slug: 'fitgym-premium' },
    update: {},
    create: {
      name: 'FitGym Premium',
      slug: 'fitgym-premium',
      address: 'ул. Ленина, 42, Москва',
      phone: '+74951234567',
      email: 'info@fitgym-premium.ru',
      timezone: 'Europe/Moscow',
    },
  });
  console.log(`   Клуб создан: ${club.name} (${club.id})`);

  // ---------------------------------------------------------------------------
  // 2. Хеширование паролей
  // ---------------------------------------------------------------------------
  console.log('2. Хеширование паролей...');
  const adminHash = await bcrypt.hash('admin123', 10);
  const trainerHash = await bcrypt.hash('trainer123', 10);

  // ---------------------------------------------------------------------------
  // 3. Департаменты
  // ---------------------------------------------------------------------------
  console.log('3. Создание департаментов...');
  const [deptGym, deptGroup] = await Promise.all([
    prisma.department.create({
      data: { clubId: club.id, name: 'Тренажёрный зал', description: 'Силовые и кардио тренировки' },
    }),
    prisma.department.create({
      data: { clubId: club.id, name: 'Групповые программы', description: 'Йога, пилатес, аэробика' },
    }),
  ]);
  console.log(`   Департаменты: ${deptGym.name}, ${deptGroup.name}`);

  // ---------------------------------------------------------------------------
  // 4. Пользователи (6 ролей)
  // ---------------------------------------------------------------------------
  console.log('4. Создание пользователей...');

  const superAdmin = await prisma.user.upsert({
    where: { clubId_phone: { clubId: club.id, phone: '+70000000001' } },
    update: {},
    create: {
      clubId: club.id,
      phone: '+70000000001',
      passwordHash: adminHash,
      firstName: 'Платформ',
      lastName: 'Админов',
      role: UserRole.SUPER_ADMIN,
    },
  });

  const clubAdmin = await prisma.user.upsert({
    where: { clubId_phone: { clubId: club.id, phone: '+70000000002' } },
    update: {},
    create: {
      clubId: club.id,
      phone: '+70000000002',
      passwordHash: adminHash,
      firstName: 'Клуб',
      lastName: 'Админов',
      role: UserRole.CLUB_ADMIN,
    },
  });

  const coordinator = await prisma.user.upsert({
    where: { clubId_phone: { clubId: club.id, phone: '+70000000003' } },
    update: {},
    create: {
      clubId: club.id,
      phone: '+70000000003',
      passwordHash: adminHash,
      firstName: 'Сергей',
      lastName: 'Координаторов',
      role: UserRole.COORDINATOR,
      departmentId: deptGym.id,
    },
  });

  const receptionist = await prisma.user.upsert({
    where: { clubId_phone: { clubId: club.id, phone: '+70000000004' } },
    update: {},
    create: {
      clubId: club.id,
      phone: '+70000000004',
      passwordHash: adminHash,
      firstName: 'Елена',
      lastName: 'Рецепцина',
      role: UserRole.RECEPTIONIST,
    },
  });

  const trainersData = [
    { phone: '+70000000010', firstName: 'Алексей', lastName: 'Тренеров', departmentId: deptGym.id },
    { phone: '+70000000011', firstName: 'Мария', lastName: 'Фитнесова', departmentId: deptGroup.id },
    { phone: '+70000000012', firstName: 'Дмитрий', lastName: 'Силачёв', departmentId: deptGym.id },
  ];

  const trainers = await Promise.all(
    trainersData.map((t) =>
      prisma.user.upsert({
        where: { clubId_phone: { clubId: club.id, phone: t.phone } },
        update: {},
        create: {
          clubId: club.id,
          phone: t.phone,
          passwordHash: trainerHash,
          firstName: t.firstName,
          lastName: t.lastName,
          role: UserRole.TRAINER,
          departmentId: t.departmentId,
        },
      }),
    ),
  );
  console.log(`   Суперадмин: ${superAdmin.firstName} ${superAdmin.lastName}`);
  console.log(`   Админ клуба: ${clubAdmin.firstName} ${clubAdmin.lastName}`);
  console.log(`   Координатор: ${coordinator.firstName} ${coordinator.lastName}`);
  console.log(`   Рецепционист: ${receptionist.firstName} ${receptionist.lastName}`);
  console.log(`   Тренеры: ${trainers.map((t) => `${t.firstName} ${t.lastName}`).join(', ')}`);

  // ---------------------------------------------------------------------------
  // 5. Залы
  // ---------------------------------------------------------------------------
  console.log('5. Создание залов...');
  const [roomPower, roomGroup, roomYoga] = await Promise.all([
    prisma.room.create({ data: { clubId: club.id, name: 'Зал силовой', capacity: 30, description: 'Тренажёры, свободные веса' } }),
    prisma.room.create({ data: { clubId: club.id, name: 'Зал групповых занятий', capacity: 25, description: 'Зеркала, маты, оборудование для групповых' } }),
    prisma.room.create({ data: { clubId: club.id, name: 'Зал йоги', capacity: 15, description: 'Тихий зал с мягким освещением' } }),
  ]);
  console.log(`   Залы: ${roomPower.name}, ${roomGroup.name}, ${roomYoga.name}`);

  // ---------------------------------------------------------------------------
  // 6. Категории услуг
  // ---------------------------------------------------------------------------
  console.log('6. Создание категорий услуг...');
  const [catPersonal, catGroup] = await Promise.all([
    prisma.serviceCategory.create({ data: { clubId: club.id, name: 'Персональные тренировки', sortOrder: 1 } }),
    prisma.serviceCategory.create({ data: { clubId: club.id, name: 'Групповые занятия', sortOrder: 2 } }),
  ]);
  console.log(`   Категории: ${catPersonal.name}, ${catGroup.name}`);

  // ---------------------------------------------------------------------------
  // 7. Услуги
  // ---------------------------------------------------------------------------
  console.log('7. Создание услуг...');
  const [svcPersonal, svcSplit, svcYoga, svcFunctional] = await Promise.all([
    prisma.service.create({
      data: { clubId: club.id, name: 'Персональная тренировка', description: 'Индивидуальное занятие с тренером', price: 3000, duration: 60, categoryId: catPersonal.id },
    }),
    prisma.service.create({
      data: { clubId: club.id, name: 'Сплит-тренировка (2 чел.)', description: 'Занятие для двоих с тренером', price: 2000, duration: 60, categoryId: catPersonal.id },
    }),
    prisma.service.create({
      data: { clubId: club.id, name: 'Хатха-йога', description: 'Групповое занятие йогой (до 15 чел.)', price: 1500, duration: 90, categoryId: catGroup.id },
    }),
    prisma.service.create({
      data: { clubId: club.id, name: 'Функциональный тренинг', description: 'Групповая функциональная тренировка', price: 1200, duration: 60, categoryId: catGroup.id },
    }),
  ]);
  console.log(`   Услуги: ${[svcPersonal, svcSplit, svcYoga, svcFunctional].map((s) => s.name).join(', ')}`);

  // ---------------------------------------------------------------------------
  // 8. Пакеты
  // ---------------------------------------------------------------------------
  console.log('8. Создание пакетов...');
  const [pkg10personal, pkgUnlimitedGroup] = await Promise.all([
    prisma.package.create({
      data: {
        clubId: club.id,
        name: '10 персональных тренировок',
        description: 'Пакет из 10 персональных тренировок. Срок действия 60 дней.',
        price: 25000,
        totalSessions: 10,
        validDays: 60,
        serviceId: svcPersonal.id,
      },
    }),
    prisma.package.create({
      data: {
        clubId: club.id,
        name: 'Безлимит групповых',
        description: 'Безлимитное посещение групповых занятий. Срок действия 30 дней.',
        price: 8000,
        totalSessions: 999,
        validDays: 30,
        serviceId: svcYoga.id,
      },
    }),
  ]);
  console.log(`   Пакеты: ${pkg10personal.name}, ${pkgUnlimitedGroup.name}`);

  // ---------------------------------------------------------------------------
  // 9. Клиенты
  // ---------------------------------------------------------------------------
  console.log('9. Создание клиентов...');
  const clientsData = [
    { firstName: 'Анна', lastName: 'Иванова', phone: '+79001000001', gender: 'FEMALE' as const, assignedTrainerId: trainers[0].id },
    { firstName: 'Пётр', lastName: 'Петров', phone: '+79001000002', gender: 'MALE' as const, assignedTrainerId: trainers[0].id },
    { firstName: 'Ольга', lastName: 'Сидорова', phone: '+79001000003', gender: 'FEMALE' as const, assignedTrainerId: trainers[1].id },
    { firstName: 'Игорь', lastName: 'Козлов', phone: '+79001000004', gender: 'MALE' as const, assignedTrainerId: trainers[1].id },
    { firstName: 'Наталья', lastName: 'Морозова', phone: '+79001000005', gender: 'FEMALE' as const, assignedTrainerId: trainers[2].id },
    { firstName: 'Андрей', lastName: 'Новиков', phone: '+79001000006', gender: 'MALE' as const, assignedTrainerId: trainers[2].id },
    { firstName: 'Екатерина', lastName: 'Волкова', phone: '+79001000007', gender: 'FEMALE' as const, assignedTrainerId: null },
    { firstName: 'Максим', lastName: 'Зайцев', phone: '+79001000008', gender: 'MALE' as const, assignedTrainerId: null },
    { firstName: 'Татьяна', lastName: 'Лебедева', phone: '+79001000009', gender: 'FEMALE' as const, assignedTrainerId: trainers[0].id },
    { firstName: 'Виктор', lastName: 'Орлов', phone: '+79001000010', gender: 'MALE' as const, assignedTrainerId: trainers[2].id },
  ];

  const clients = await Promise.all(
    clientsData.map((c) =>
      prisma.client.create({
        data: {
          clubId: club.id,
          firstName: c.firstName,
          lastName: c.lastName,
          phone: c.phone,
          gender: c.gender,
          assignedTrainerId: c.assignedTrainerId,
          source: 'seed',
          lastActivityAt: new Date(Date.now() - Math.floor(Math.random() * 30) * 24 * 60 * 60 * 1000),
        },
      }),
    ),
  );
  console.log(`   Клиенты: ${clients.length} шт.`);

  // ---------------------------------------------------------------------------
  // 10. Лицензия
  // ---------------------------------------------------------------------------
  console.log('10. Создание лицензии...');
  const now = new Date();
  const oneYearLater = new Date(now);
  oneYearLater.setFullYear(oneYearLater.getFullYear() + 1);

  const license = await prisma.license.upsert({
    where: { clubId: club.id },
    update: {},
    create: {
      clubId: club.id,
      type: LicenseType.STANDARD,
      startDate: now,
      endDate: oneYearLater,
      isActive: true,
      maxUsers: 50,
      maxClients: 1000,
    },
  });
  console.log(`   Лицензия: ${license.type}, до ${license.endDate.toISOString().split('T')[0]}`);

  // ---------------------------------------------------------------------------
  // 11. Модули клуба
  // ---------------------------------------------------------------------------
  console.log('11. Активация модулей...');
  const modules: { moduleId: string; enabled: boolean; limitsJson: Prisma.InputJsonValue | undefined }[] = [
    { moduleId: 'core', enabled: true, limitsJson: undefined },
    { moduleId: 'sales', enabled: true, limitsJson: undefined },
    { moduleId: 'coordinator', enabled: true, limitsJson: undefined },
    { moduleId: 'push', enabled: true, limitsJson: { max_messages: 5000 } },
    { moduleId: 'web_reception', enabled: true, limitsJson: undefined },
    { moduleId: 'web_reports', enabled: true, limitsJson: undefined },
    { moduleId: 'sip', enabled: true, limitsJson: { max_minutes: 1000 } },
    { moduleId: 'webhooks', enabled: true, limitsJson: { max_events: 10000 } },
    { moduleId: 'club_admin', enabled: true, limitsJson: undefined },
    { moduleId: 'email', enabled: true, limitsJson: { max_emails_per_month: 10000 } },
  ];

  await Promise.all(
    modules.map((m) =>
      prisma.clubModule.upsert({
        where: { clubId_moduleId: { clubId: club.id, moduleId: m.moduleId } },
        update: { enabled: m.enabled },
        create: { clubId: club.id, moduleId: m.moduleId, enabled: m.enabled, limitsJson: m.limitsJson },
      }),
    ),
  );
  console.log(`   Модули активированы: ${modules.map((m) => m.moduleId).join(', ')}`);

  // ---------------------------------------------------------------------------
  // 12. Воронка продаж
  // ---------------------------------------------------------------------------
  console.log('12. Создание записей воронки...');
  const funnelData = [
    { clientIdx: 6, stage: FunnelStage.NEW, trainerId: null, comment: 'Новый клиент, пришёл по рекламе' },
    { clientIdx: 7, stage: FunnelStage.NEW, trainerId: null, comment: 'Оставил заявку на сайте' },
    { clientIdx: 0, stage: FunnelStage.ASSIGNED, trainerId: trainers[0].id, comment: 'Назначен тренер Алексей' },
    { clientIdx: 1, stage: FunnelStage.COMPLETED, trainerId: trainers[0].id, previousStage: FunnelStage.ASSIGNED, comment: 'Пробная тренировка проведена' },
    { clientIdx: 2, stage: FunnelStage.REGULAR, trainerId: trainers[1].id, previousStage: FunnelStage.COMPLETED, comment: 'Купила абонемент, постоянный клиент' },
  ];

  const funnelEntries = await Promise.all(
    funnelData.map((f) =>
      prisma.funnelEntry.create({
        data: {
          clubId: club.id,
          clientId: clients[f.clientIdx].id,
          trainerId: f.trainerId,
          stage: f.stage,
          previousStage: (f as any).previousStage ?? null,
          comment: f.comment,
        },
      }),
    ),
  );
  console.log(`   Записи воронки: ${funnelEntries.length} шт.`);

  // ---------------------------------------------------------------------------
  // 13. Тренировки
  // ---------------------------------------------------------------------------
  console.log('13. Создание тренировок...');
  const tomorrow = new Date(now);
  tomorrow.setDate(tomorrow.getDate() + 1);
  tomorrow.setHours(10, 0, 0, 0);

  const trainingsData = [
    { trainerId: trainers[0].id, clientIdx: 0, serviceId: svcPersonal.id, roomId: roomPower.id, scheduledAt: tomorrow, status: TrainingStatus.PLANNED, duration: 60 },
    { trainerId: trainers[0].id, clientIdx: 1, serviceId: svcPersonal.id, roomId: roomPower.id, scheduledAt: new Date(tomorrow.getTime() + 2 * 60 * 60 * 1000), status: TrainingStatus.CONFIRMED, duration: 60 },
    { trainerId: trainers[1].id, clientIdx: 2, serviceId: svcYoga.id, roomId: roomYoga.id, scheduledAt: tomorrow, status: TrainingStatus.PLANNED, duration: 90 },
    { trainerId: trainers[1].id, clientIdx: 3, serviceId: svcFunctional.id, roomId: roomGroup.id, scheduledAt: new Date(tomorrow.getTime() + 3 * 60 * 60 * 1000), status: TrainingStatus.PLANNED, duration: 60 },
    { trainerId: trainers[2].id, clientIdx: 4, serviceId: svcPersonal.id, roomId: roomPower.id, scheduledAt: new Date(now.getTime() - 24 * 60 * 60 * 1000), status: TrainingStatus.COMPLETED, duration: 60 },
  ];

  const trainingRecords = await Promise.all(
    trainingsData.map((t) =>
      prisma.training.create({
        data: {
          clubId: club.id,
          trainerId: t.trainerId,
          clientId: clients[t.clientIdx].id,
          serviceId: t.serviceId,
          roomId: t.roomId,
          scheduledAt: t.scheduledAt,
          status: t.status,
          duration: t.duration,
        },
      }),
    ),
  );
  console.log(`   Тренировки: ${trainingRecords.length} шт.`);

  // ---------------------------------------------------------------------------
  // 14. Продажи
  // ---------------------------------------------------------------------------
  console.log('14. Создание продаж...');
  const salesData = [
    { trainerId: trainers[0].id, clientIdx: 0, packageId: pkg10personal.id, serviceId: svcPersonal.id, amount: 25000, status: SaleStatus.PAID, description: 'Пакет 10 персональных тренировок' },
    { trainerId: trainers[1].id, clientIdx: 2, packageId: pkgUnlimitedGroup.id, serviceId: svcYoga.id, amount: 8000, status: SaleStatus.PAID, description: 'Безлимит групповых на месяц' },
    { trainerId: trainers[2].id, clientIdx: 4, packageId: null, serviceId: svcPersonal.id, amount: 3000, status: SaleStatus.PENDING, description: 'Разовая персональная тренировка' },
  ];

  const saleRecords = await Promise.all(
    salesData.map((s) =>
      prisma.sale.create({
        data: {
          clubId: club.id,
          trainerId: s.trainerId,
          clientId: clients[s.clientIdx].id,
          packageId: s.packageId,
          serviceId: s.serviceId,
          amount: s.amount,
          status: s.status,
          description: s.description,
          paidAt: s.status === SaleStatus.PAID ? new Date() : null,
        },
      }),
    ),
  );
  console.log(`   Продажи: ${saleRecords.length} шт.`);

  // ---------------------------------------------------------------------------
  // 15. Настройки уведомлений
  // ---------------------------------------------------------------------------
  console.log('15. Создание настроек уведомлений...');
  const notificationTypes: NotificationType[] = [
    NotificationType.CLIENT_ASSIGNED,
    NotificationType.SERVICE_BOOKED,
    NotificationType.SERVICE_PAID,
    NotificationType.PACKAGE_TOPUP,
    NotificationType.BOOKING_CANCELLED,
    NotificationType.TRAINING_DEDUCTED,
    NotificationType.TRAININGS_ENDING,
    NotificationType.CLIENT_RETURNED,
    NotificationType.CLIENT_BIRTHDAY,
  ];

  await Promise.all(
    notificationTypes.map((nt) =>
      prisma.notificationSetting.upsert({
        where: { clubId_notificationType: { clubId: club.id, notificationType: nt } },
        update: { enabled: true },
        create: { clubId: club.id, notificationType: nt, enabled: true },
      }),
    ),
  );
  console.log(`   Типы уведомлений: ${notificationTypes.length} шт., все включены`);

  // ---------------------------------------------------------------------------
  // Итог
  // ---------------------------------------------------------------------------
  console.log('\n=== Сидирование завершено успешно ===');
  console.log(`Клуб:               ${club.name}`);
  console.log(`Пользователей:      ${4 + trainers.length}`);
  console.log(`Департаментов:      2`);
  console.log(`Залов:              3`);
  console.log(`Услуг:              4`);
  console.log(`Пакетов:            2`);
  console.log(`Клиентов:           ${clients.length}`);
  console.log(`Записей воронки:    ${funnelEntries.length}`);
  console.log(`Тренировок:         ${trainingRecords.length}`);
  console.log(`Продаж:             ${saleRecords.length}`);
  console.log(`Лицензия:           ${license.type}`);
  console.log(`Модулей:            ${modules.length}`);
  console.log(`Типов уведомлений:  ${notificationTypes.length}`);
}

main()
  .catch((e) => {
    console.error('Ошибка сидирования:', e);
    process.exit(1);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
