import { DataSource } from 'typeorm';
import * as bcrypt from 'bcrypt';
import { User } from '../../users/entities/user.entity';
import { Category } from '../../categories/entities/category.entity';
import { Channel } from '../../channels/entities/channel.entity';
import { Movie } from '../../movies/entities/movie.entity';
import { Series } from '../../series/entities/series.entity';
import { Season } from '../../series/entities/season.entity';
import { Episode } from '../../series/entities/episode.entity';
import { Profile } from '../../profiles/entities/profile.entity';
import { Favorite } from '../../favorites/entities/favorite.entity';
import { History } from '../../history/entities/history.entity';

const dataSource = new DataSource({
  type: 'postgres',
  host: process.env.DB_HOST || 'localhost',
  port: parseInt(process.env.DB_PORT || '5432', 10),
  username: process.env.DB_USERNAME || 'postgres',
  password: process.env.DB_PASSWORD || 'postgres',
  database: process.env.DB_NAME || 'cattv',
  entities: [User, Category, Channel, Movie, Series, Season, Episode, Profile, Favorite, History],
  synchronize: true,
  logging: true,
});

async function seed() {
  console.log('🌱 Starting database seed...');

  await dataSource.initialize();
  console.log('✅ Database connection established');

  const userRepo = dataSource.getRepository(User);
  const categoryRepo = dataSource.getRepository(Category);
  const channelRepo = dataSource.getRepository(Channel);
  const movieRepo = dataSource.getRepository(Movie);
  const seriesRepo = dataSource.getRepository(Series);
  const seasonRepo = dataSource.getRepository(Season);
  const episodeRepo = dataSource.getRepository(Episode);

  // ── Admin User ───────────────────────────────────────────────────────────
  console.log('\n👤 Creating admin user...');
  const existingAdmin = await userRepo.findOne({ where: { email: 'admin@cattv.com' } });
  if (!existingAdmin) {
    const passwordHash = await bcrypt.hash('admin123456', 12);
    const admin = userRepo.create({
      email: 'admin@cattv.com',
      username: 'admin',
      passwordHash,
      role: 'ADMIN' as any,
      status: 'ACTIVE' as any,
    });
    await userRepo.save(admin);
    console.log('  ✅ Admin user created (admin@cattv.com / admin123456)');
  } else {
    console.log('  ⏭️  Admin user already exists');
  }

  // ── Categories ───────────────────────────────────────────────────────────
  console.log('\n📂 Creating categories...');
  const categoriesData = [
    { name: 'Deportes', slug: 'deportes', icon: '⚽', type: 'TV', order: 1 },
    { name: 'Noticias', slug: 'noticias', icon: '📰', type: 'TV', order: 2 },
    { name: 'Infantiles', slug: 'infantiles', icon: '🧸', type: 'ALL', order: 3 },
    { name: 'Entretenimiento', slug: 'entretenimiento', icon: '🎭', type: 'TV', order: 4 },
    { name: 'Música', slug: 'musica', icon: '🎵', type: 'TV', order: 5 },
    { name: 'Documentales', slug: 'documentales', icon: '🎬', type: 'ALL', order: 6 },
    { name: 'Acción', slug: 'accion', icon: '💥', type: 'MOVIE', order: 7 },
    { name: 'Comedia', slug: 'comedia', icon: '😂', type: 'ALL', order: 8 },
    { name: 'Terror', slug: 'terror', icon: '👻', type: 'MOVIE', order: 9 },
    { name: 'Drama', slug: 'drama', icon: '🎭', type: 'ALL', order: 10 },
    { name: 'Ciencia Ficción', slug: 'ciencia-ficcion', icon: '🚀', type: 'ALL', order: 11 },
  ];

  const categories: Record<string, Category> = {};
  for (const catData of categoriesData) {
    const existing = await categoryRepo.findOne({ where: { slug: catData.slug } });
    if (!existing) {
      const category = categoryRepo.create(catData as any);
      const saved = (await categoryRepo.save(category)) as any;
      categories[catData.slug] = saved;
      console.log(`  ✅ Category "${catData.name}" created`);
    } else {
      categories[catData.slug] = existing;
      console.log(`  ⏭️  Category "${catData.name}" already exists`);
    }
  }

  // ── Channels ─────────────────────────────────────────────────────────────
  console.log('\n📺 Creating sample channels...');
  const channelsData = [
    {
      name: 'ESPN Deportes',
      streamUrl: 'https://stream.example.com/live/espn-deportes.m3u8',
      logoUrl: 'https://upload.wikimedia.org/wikipedia/commons/2/2f/ESPN_wordmark.svg',
      categorySlug: 'deportes',
      order: 1,
    },
    {
      name: 'CNN en Español',
      streamUrl: 'https://stream.example.com/live/cnn-espanol.m3u8',
      logoUrl: 'https://upload.wikimedia.org/wikipedia/commons/b/b1/CNN.svg',
      categorySlug: 'noticias',
      order: 1,
    },
    {
      name: 'Cartoon Network',
      streamUrl: 'https://stream.example.com/live/cartoon-network.m3u8',
      logoUrl: 'https://upload.wikimedia.org/wikipedia/commons/8/80/Cartoon_Network_2010_logo.svg',
      categorySlug: 'infantiles',
      order: 1,
    },
    {
      name: 'Discovery Channel',
      streamUrl: 'https://stream.example.com/live/discovery.m3u8',
      logoUrl: 'https://upload.wikimedia.org/wikipedia/commons/a/a0/Discovery_Channel_logo.svg',
      categorySlug: 'documentales',
      order: 1,
    },
    {
      name: 'MTV Latinoamérica',
      streamUrl: 'https://stream.example.com/live/mtv-latam.m3u8',
      logoUrl: 'https://upload.wikimedia.org/wikipedia/commons/6/68/MTV_Logo.svg',
      categorySlug: 'musica',
      order: 1,
    },
  ];

  for (const chData of channelsData) {
    const existing = await channelRepo.findOne({ where: { name: chData.name } });
    if (!existing) {
      const category = categories[chData.categorySlug];
      const channel = channelRepo.create({
        name: chData.name,
        streamUrl: chData.streamUrl,
        logoUrl: chData.logoUrl,
        categoryId: category.id,
        order: chData.order,
        isActive: true,
      });
      await channelRepo.save(channel);
      console.log(`  ✅ Channel "${chData.name}" created`);
    } else {
      console.log(`  ⏭️  Channel "${chData.name}" already exists`);
    }
  }

  // ── Movies ───────────────────────────────────────────────────────────────
  console.log('\n🎬 Creating sample movies...');
  const moviesData = [
    {
      title: 'El Secreto de la Montaña',
      synopsis: 'Un grupo de escaladores descubre un misterio ancestral oculto en las cumbres de los Andes.',
      streamUrl: 'https://stream.example.com/movies/secreto-montana.m3u8',
      posterUrl: 'https://picsum.photos/seed/movie1/300/450',
      backdropUrl: 'https://picsum.photos/seed/movie1bg/1280/720',
      durationMin: 128,
      year: 2024,
      rating: 7.8,
      categorySlugs: ['accion', 'drama'],
    },
    {
      title: 'Código Nocturno',
      synopsis: 'Un hacker descubre una conspiración global que amenaza con destruir la infraestructura digital del mundo.',
      streamUrl: 'https://stream.example.com/movies/codigo-nocturno.m3u8',
      posterUrl: 'https://picsum.photos/seed/movie2/300/450',
      backdropUrl: 'https://picsum.photos/seed/movie2bg/1280/720',
      durationMin: 142,
      year: 2023,
      rating: 8.2,
      categorySlugs: ['ciencia-ficcion', 'accion'],
    },
    {
      title: 'Risas al Amanecer',
      synopsis: 'Una comedia sobre una familia disfuncional que intenta organizar la boda perfecta.',
      streamUrl: 'https://stream.example.com/movies/risas-amanecer.m3u8',
      posterUrl: 'https://picsum.photos/seed/movie3/300/450',
      backdropUrl: 'https://picsum.photos/seed/movie3bg/1280/720',
      durationMin: 95,
      year: 2024,
      rating: 6.5,
      categorySlugs: ['comedia'],
    },
    {
      title: 'La Sombra del Bosque',
      synopsis: 'Una pareja se muda a una cabaña aislada sin saber que algo habita en la oscuridad del bosque.',
      streamUrl: 'https://stream.example.com/movies/sombra-bosque.m3u8',
      posterUrl: 'https://picsum.photos/seed/movie4/300/450',
      backdropUrl: 'https://picsum.photos/seed/movie4bg/1280/720',
      durationMin: 110,
      year: 2023,
      rating: 7.1,
      categorySlugs: ['terror'],
    },
    {
      title: 'Horizontes Perdidos',
      synopsis: 'Un documental épico que explora los rincones más remotos de la Tierra y sus civilizaciones olvidadas.',
      streamUrl: 'https://stream.example.com/movies/horizontes-perdidos.m3u8',
      posterUrl: 'https://picsum.photos/seed/movie5/300/450',
      backdropUrl: 'https://picsum.photos/seed/movie5bg/1280/720',
      durationMin: 156,
      year: 2024,
      rating: 9.0,
      categorySlugs: ['documentales'],
    },
  ];

  for (const movieData of moviesData) {
    const existing = await movieRepo.findOne({ where: { title: movieData.title } });
    if (!existing) {
      const movieCategories = movieData.categorySlugs
        .map((slug) => categories[slug])
        .filter(Boolean);

      const movie = movieRepo.create({
        title: movieData.title,
        synopsis: movieData.synopsis,
        streamUrl: movieData.streamUrl,
        posterUrl: movieData.posterUrl,
        backdropUrl: movieData.backdropUrl,
        durationMin: movieData.durationMin,
        year: movieData.year,
        rating: movieData.rating,
        isActive: true,
        categories: movieCategories,
      });
      await movieRepo.save(movie);
      console.log(`  ✅ Movie "${movieData.title}" created`);
    } else {
      console.log(`  ⏭️  Movie "${movieData.title}" already exists`);
    }
  }

  // ── Series ───────────────────────────────────────────────────────────────
  console.log('\n📺 Creating sample series...');
  const seriesData = [
    {
      title: 'Circuito Cerrado',
      synopsis: 'Un detective investiga una serie de crímenes conectados a un sistema de vigilancia secreto en una gran ciudad.',
      posterUrl: 'https://picsum.photos/seed/series1/300/450',
      backdropUrl: 'https://picsum.photos/seed/series1bg/1280/720',
      year: 2023,
      rating: 8.5,
      categorySlugs: ['drama', 'ciencia-ficcion'],
      seasons: [
        {
          number: 1,
          title: 'La Red',
          episodes: [
            { number: 1, title: 'Piloto', streamUrl: 'https://stream.example.com/series/cc/s01e01.m3u8', durationMin: 52 },
            { number: 2, title: 'Conexiones', streamUrl: 'https://stream.example.com/series/cc/s01e02.m3u8', durationMin: 48 },
            { number: 3, title: 'El Infiltrado', streamUrl: 'https://stream.example.com/series/cc/s01e03.m3u8', durationMin: 55 },
            { number: 4, title: 'Punto Ciego', streamUrl: 'https://stream.example.com/series/cc/s01e04.m3u8', durationMin: 50 },
            { number: 5, title: 'La Verdad', streamUrl: 'https://stream.example.com/series/cc/s01e05.m3u8', durationMin: 58 },
          ],
        },
        {
          number: 2,
          title: 'El Protocolo',
          episodes: [
            { number: 1, title: 'Nuevo Orden', streamUrl: 'https://stream.example.com/series/cc/s02e01.m3u8', durationMin: 54 },
            { number: 2, title: 'Doble Filo', streamUrl: 'https://stream.example.com/series/cc/s02e02.m3u8', durationMin: 51 },
            { number: 3, title: 'Colapso', streamUrl: 'https://stream.example.com/series/cc/s02e03.m3u8', durationMin: 60 },
          ],
        },
      ],
    },
    {
      title: 'Tierra Salvaje',
      synopsis: 'Un grupo de biólogos se adentra en territorios inexplorados para documentar especies en peligro de extinción.',
      posterUrl: 'https://picsum.photos/seed/series2/300/450',
      backdropUrl: 'https://picsum.photos/seed/series2bg/1280/720',
      year: 2024,
      rating: 9.1,
      categorySlugs: ['documentales'],
      seasons: [
        {
          number: 1,
          title: 'Amazonas',
          episodes: [
            { number: 1, title: 'El Corazón Verde', streamUrl: 'https://stream.example.com/series/ts/s01e01.m3u8', durationMin: 45 },
            { number: 2, title: 'Ríos de Vida', streamUrl: 'https://stream.example.com/series/ts/s01e02.m3u8', durationMin: 47 },
            { number: 3, title: 'Depredadores Nocturnos', streamUrl: 'https://stream.example.com/series/ts/s01e03.m3u8', durationMin: 44 },
            { number: 4, title: 'Los Guardianes', streamUrl: 'https://stream.example.com/series/ts/s01e04.m3u8', durationMin: 50 },
          ],
        },
      ],
    },
  ];

  for (const sd of seriesData) {
    const existing = await seriesRepo.findOne({ where: { title: sd.title } });
    if (!existing) {
      const seriesCategories = sd.categorySlugs
        .map((slug) => categories[slug])
        .filter(Boolean);

      const series = seriesRepo.create({
        title: sd.title,
        synopsis: sd.synopsis,
        posterUrl: sd.posterUrl,
        backdropUrl: sd.backdropUrl,
        year: sd.year,
        rating: sd.rating,
        isActive: true,
        categories: seriesCategories,
      });
      const savedSeries = (await seriesRepo.save(series)) as any;

      for (const seasonData of sd.seasons) {
        const season = seasonRepo.create({
          seriesId: savedSeries.id,
          number: seasonData.number,
          title: seasonData.title,
        });
        const savedSeason = (await seasonRepo.save(season)) as any;

        for (const epData of seasonData.episodes) {
          const episode = episodeRepo.create({
            seasonId: savedSeason.id,
            number: epData.number,
            title: epData.title,
            streamUrl: epData.streamUrl,
            durationMin: epData.durationMin,
          });
          await episodeRepo.save(episode);
        }
      }

      console.log(`  ✅ Series "${sd.title}" created with ${sd.seasons.length} season(s)`);
    } else {
      console.log(`  ⏭️  Series "${sd.title}" already exists`);
    }
  }

  // ── Done ─────────────────────────────────────────────────────────────────
  console.log('\n✨ Seed completed successfully!');
  console.log('\n📋 Summary:');
  console.log(`   Users:      ${await userRepo.count()}`);
  console.log(`   Categories: ${await categoryRepo.count()}`);
  console.log(`   Channels:   ${await channelRepo.count()}`);
  console.log(`   Movies:     ${await movieRepo.count()}`);
  console.log(`   Series:     ${await seriesRepo.count()}`);
  console.log(`   Seasons:    ${await seasonRepo.count()}`);
  console.log(`   Episodes:   ${await episodeRepo.count()}`);

  await dataSource.destroy();
  console.log('\n🔌 Database connection closed');
}

seed().catch((error) => {
  console.error('❌ Seed failed:', error);
  process.exit(1);
});
