// PeepBox Streaming Platform — Comprehensive Persian Seed Data
// Run with: bun prisma/seed.ts

import { db } from "../src/lib/db";

// ===================== Helpers =====================
function rand(min: number, max: number): number {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
function randFloat(min: number, max: number, decimals = 1): number {
  const v = Math.random() * (max - min) + min;
  return parseFloat(v.toFixed(decimals));
}
function pick<T>(arr: T[], i: number): T {
  return arr[((i % arr.length) + arr.length) % arr.length];
}
function daysFromNow(days: number): Date {
  return new Date(Date.now() + days * 24 * 60 * 60 * 1000);
}
function daysAgo(days: number): Date {
  return new Date(Date.now() - days * 24 * 60 * 60 * 1000);
}
function makeDesc(titleFa: string, theme: string): string {
  return `«${titleFa}» روایتی پرکشش از ${theme} است. داستان در فضایی پر تنش و معما جریان دارد و شخصیت‌های اصلی در تلاش برای رسیدن به حقیقتی پنهان در پس پرده‌های تاریکی‌اند. کارگردان با تصویرسازی دقیق و فضاسازی خاص، تماشاگر را در سفری هیجان‌انگیز و فراموش‌نشدنی همراهی می‌کند که تا آخرین ثانیه، تعلیق را حفظ می‌کند.`;
}

// ===================== Sample Media URLs =====================
// All streams are HLS (MP4 sample hosts were unreachable from this environment).
const HLS_STREAMS = [
  "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8",
  "https://test-streams.mux.dev/test_001/stream.m3u8",
  "https://cph-p2p-msl.akamaized.net/hls/live/2000341/test/master.m3u8",
  "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
];
const HLS_1080P = HLS_STREAMS[0];
// Kept for backward-compat references in the rest of the file.
const MP4_URLS = HLS_STREAMS;
const LIVE_HLS = HLS_STREAMS;
const MUSIC_URLS = Array.from(
  { length: 16 },
  (_, i) => `https://www.soundhelix.com/examples/mp3/SoundHelix-Song-${i + 1}.mp3`
);

// Character role names for cast
const CHAR_NAMES = [
  "Alex Carter", "Maya Reed", "Detective Hayes", "Dr. Sara Vance",
  "Marcus Vale", "Eva Lin", "Noah Cross", "Layla Khan",
  "Derek Shaw", "Sofia Marin", "Julian Roe", "Nadia Brooks",
];
const CREW_PALETTE = [
  ["#7C3AED", "#EC4899"],
  ["#22D3EE", "#3B82F6"],
  ["#F59E0B", "#EF4444"],
  ["#10B981", "#22D3EE"],
  ["#EC4899", "#8B5CF6"],
  ["#3B82F6", "#06B6D4"],
  ["#A855F7", "#6366F1"],
  ["#F97316", "#EC4899"],
];

// ===================== Data Definitions =====================

const genreData = [
  { name: "Action", slug: "action", persianName: "اکشن" },
  { name: "Drama", slug: "drama", persianName: "درام" },
  { name: "Comedy", slug: "comedy", persianName: "کمدی" },
  { name: "Sci-Fi", slug: "sci-fi", persianName: "علمی‌تخیلی" },
  { name: "Horror", slug: "horror", persianName: "ترسناک" },
  { name: "Romance", slug: "romance", persianName: "عاشقانه" },
  { name: "Crime", slug: "crime", persianName: "جنایی" },
  { name: "Adventure", slug: "adventure", persianName: "ماجراجویی" },
  { name: "Animation", slug: "animation", persianName: "انیمیشن" },
  { name: "Documentary", slug: "documentary", persianName: "مستند" },
  { name: "Family", slug: "family", persianName: "خانوادگی" },
  { name: "Historical", slug: "historical", persianName: "تاریخی" },
  { name: "War", slug: "war", persianName: "جنگی" },
  { name: "Musical", slug: "musical", persianName: "موزیکال" },
  { name: "Mystery", slug: "mystery", persianName: "معمایی" },
  { name: "Fantasy", slug: "fantasy", persianName: "فانتزی" },
  { name: "Thriller", slug: "thriller", persianName: "هیجان‌انگیز" },
  { name: "Western", slug: "western", persianName: "وسترن" },
  { name: "Biography", slug: "biography", persianName: "بیوگرافی" },
  { name: "Sport", slug: "sport", persianName: "ورزشی" },
];

const countryData = [
  { name: "United States", slug: "usa", persianName: "آمریکا", code: "US" },
  { name: "United Kingdom", slug: "uk", persianName: "بریتانیا", code: "GB" },
  { name: "South Korea", slug: "south-korea", persianName: "کره جنوبی", code: "KR" },
  { name: "Japan", slug: "japan", persianName: "ژاپن", code: "JP" },
  { name: "France", slug: "france", persianName: "فرانسه", code: "FR" },
  { name: "Germany", slug: "germany", persianName: "آلمان", code: "DE" },
  { name: "Iran", slug: "iran", persianName: "ایران", code: "IR" },
  { name: "India", slug: "india", persianName: "هند", code: "IN" },
  { name: "China", slug: "china", persianName: "چین", code: "CN" },
  { name: "Spain", slug: "spain", persianName: "اسپانیا", code: "ES" },
  { name: "Italy", slug: "italy", persianName: "ایتالیا", code: "IT" },
  { name: "Turkey", slug: "turkey", persianName: "ترکیه", code: "TR" },
  { name: "Canada", slug: "canada", persianName: "کانادا", code: "CA" },
  { name: "Australia", slug: "australia", persianName: "استرالیا", code: "AU" },
  { name: "Sweden", slug: "sweden", persianName: "سوئد", code: "SE" },
  { name: "Denmark", slug: "denmark", persianName: "دانمارک", code: "DK" },
];

const actorData = [
  { name: "Tom Hardy", slug: "tom-hardy", persianName: "تام هاردی", bio: "بازیگر بریتانیایی با سبک بدیع در نقش‌های تاریک و دراماتیک." },
  { name: "Leonardo DiCaprio", slug: "leonardo-dicaprio", persianName: "لئوناردو دی‌کاپریو", bio: "افسانه هالیوودی با حضور در فیلم‌های ماندگار سینمای جهان." },
  { name: "Cate Blanchett", slug: "cate-blanchett", persianName: "کیت بلانشت", bio: "بازیگر استرالیایی و برنده جوایز متعدد اسکار." },
  { name: "Mahershala Ali", slug: "mahershala-ali", persianName: "محرشلا علی", bio: "بازیگر آمریکایی و دو بار برنده اسکار بهترین بازیگر نقش مکمل." },
  { name: "Viola Davis", slug: "viola-davis", persianName: "وایولا دیویس", bio: "بازیگر قدرتمند آمریکایی و برنده جایزه اسکار، امی و تونی." },
  { name: "Joaquin Phoenix", slug: "joaquin-phoenix", persianName: "خواکین فینیکس", bio: "بازیگر متد آمریکایی و برنده اسکار بهترین بازیگر نقش اول." },
  { name: "Charlize Theron", slug: "charlize-theron", persianName: "شارلیز ترون", bio: "بازیگر و تولیدکننده آفریقای جنوبی-آمریکایی." },
  { name: "Michael B. Jordan", slug: "michael-b-jordan", persianName: "مایکل بی جردن", bio: "بازیگر و کارگردان آمریکایی با شهرت در فیلم‌های اکشن." },
  { name: "Saoirse Ronan", slug: "saoirse-ronan", persianName: "سیرشا رونان", bio: "بازیگر ایرلندی-آمریکایی و نامزد چهار بار اسکار." },
  { name: "Daniel Kaluuya", slug: "daniel-kaluuya", persianName: "دنیل کالویا", bio: "بازیگر بریتانیایی و برنده اسکار بهترین بازیگر نقش مکمل." },
  { name: "Zendaya", slug: "zendaya", persianName: "زندایا", bio: "بازیگر و خواننده آمریکایی با دو جایزه امی." },
  { name: "Pedro Pascal", slug: "pedro-pascal", persianName: "پدرو پاسکال", bio: "بازیگر شیلیایی-آمریکایی و ستاره سریال‌های محبوب." },
  { name: "Florence Pugh", slug: "florence-pugh", persianName: "فلورنس پیو", bio: "بازیگر بریتانیایی و نامزد اسکار." },
  { name: "Oscar Isaac", slug: "oscar-isaac", persianName: "اسکار آیزاک", bio: "بازیگر گواتمالایی-آمریکایی با حضور در فیلم‌های استودیویی و مستقل." },
  { name: "Anya Taylor-Joy", slug: "anya-taylor-joy", persianName: "آنیا تیلور-جوی", bio: "بازیگر آرژانتینی-بریتانیایی با حضور در آثار ماندگار." },
  { name: "Taraneh Alidoosti", slug: "taraneh-alidoosti", persianName: "ترانه علیدوستی", bio: "بازیگر ایرانی و ستاره سینمای اصغر فرهادی." },
  { name: "Shahab Hosseini", slug: "shahab-hosseini", persianName: "شهاب حسینی", bio: "بازیگر ایرانی و برنده بهترین بازیگر مرد جشنواره کن." },
  { name: "Song Kang-ho", slug: "song-kang-ho", persianName: "سونگ کانگ-هو", bio: "بازیگر کره‌ای و ستاره فیلم‌های بونگ جون-هو." },
  { name: "Penélope Cruz", slug: "penelope-cruz", persianName: "پنه‌لوپه کروز", bio: "بازیگر اسپانیایی و موز کریستین آثار پدرو آلمودوار." },
  { name: "Riz Ahmed", slug: "riz-ahmed", persianName: "ریز احمد", bio: "بازیگر بریتانیایی-پاکستانی و نامزد اسکار." },
];

const directorData = [
  { name: "Christopher Nolan", slug: "christopher-nolan", persianName: "کریستوفر نولان", bio: "کارگردان بریتانیایی و استاد فیلم‌های ساختاری پیچیده." },
  { name: "Denis Villeneuve", slug: "denis-villeneuve", persianName: "دنی ویلنوو", bio: "کارگردان کانادایی و خالق فضاهای علمی‌تخیلی نفس‌گیر." },
  { name: "Greta Gerwig", slug: "greta-gerwig", persianName: "گرتا گرگ", bio: "کارگردان آمریکایی و نامزد اسکار بهترین کارگردانی." },
  { name: "Bong Joon-ho", slug: "bong-joon-ho", persianName: "بونگ جون-هو", bio: "کارگردان کره‌ای و برنده نخل طلای کن و اسکار." },
  { name: "Asghar Farhadi", slug: "asghar-farhadi", persianName: "اصغر فرهادی", bio: "کارگردان ایرانی و دو بار برنده اسکار بهترین فیلم غیرانگلیسی." },
  { name: "Jordan Peele", slug: "jordan-peele", persianName: "جوردن پیل", bio: "کارگردان آمریکایی و برنده اسکار بهترین فیلم‌نامه غیراقتباسی." },
  { name: "Ari Aster", slug: "ari-aster", persianName: "آری استر", bio: "کارگردان آمریکایی و خالق فیلم‌های وحشت آوانگارد." },
  { name: "Chloé Zhao", slug: "chloe-zhao", persianName: "کلویی ژائو", bio: "کارگردان چینی-آمریکایی و برنده اسکار بهترین کارگردانی." },
  { name: "Park Chan-wook", slug: "park-chan-wook", persianName: "پارک چان-ووک", bio: "کارگردان کره‌ای و استاد درام‌های خشن و ظریف." },
  { name: "Alex Garland", slug: "alex-garland", persianName: "الکس گارلند", bio: "نویسنده و کارگردان بریتانیایی و خالق آثار علمی‌تخیلی پرکشش." },
];

// Movie definitions — 24 movies; first 6 are heroes with backdrops
type MovieDef = {
  slug: string;
  title: string;
  persianTitle: string;
  originalTitle?: string;
  theme: string;
  shortDesc: string;
  imdb: number;
  year: number;
  duration: number;
  country: string; // slug
  language: string;
  ageRating: string;
  quality: string;
  isDubbed: boolean;
  isFeatured: boolean;
  isTrending: boolean;
  isNew: boolean;
  isPremium: boolean;
  views: number;
  featuredOrder: number;
  genres: string[]; // slugs
  cast: number[]; // actor indices
  directorIdx: number;
};

const movieDefs: MovieDef[] = [
  { slug: "neon-horizon", title: "Neon Horizon", persianTitle: "افق نئون", originalTitle: "Neon Horizon", theme: "آینده‌ی ویرانشهری و جستجوی هویت", shortDesc: "در شهری نئونی، یک هکر راز سیستم را کشف می‌کند.", imdb: 8.7, year: 2023, duration: 142, country: "usa", language: "en", ageRating: "16+", quality: "2160p", isDubbed: true, isFeatured: true, isTrending: true, isNew: false, isPremium: true, views: 482000, featuredOrder: 1, genres: ["sci-fi", "thriller", "action"], cast: [0, 5, 10], directorIdx: 1 },
  { slug: "desert-storm", title: "Desert Storm", persianTitle: "طوفان صحرا", originalTitle: "Desert Storm", theme: "جنگ و بقا در بیابان", shortDesc: "تیم ویژه‌ای در صحرا در تله زمان می‌افتد.", imdb: 8.2, year: 2022, duration: 138, country: "uk", language: "en", ageRating: "16+", quality: "1080p", isDubbed: false, isFeatured: true, isTrending: true, isNew: false, isPremium: true, views: 318000, featuredOrder: 2, genres: ["war", "action", "drama"], cast: [1, 7, 3], directorIdx: 0 },
  { slug: "midnight-requiem", title: "Midnight Requiem", persianTitle: "مرثیه نیمه‌شب", theme: "جنایت و رستگاری در شهر تاریک", shortDesc: "کارآگاهی در پی حقیقتی خطرناک می‌رود.", imdb: 8.9, year: 2021, duration: 152, country: "usa", language: "en", ageRating: "18+", quality: "2160p", isDubbed: false, isFeatured: true, isTrending: true, isNew: false, isPremium: true, views: 412000, featuredOrder: 3, genres: ["crime", "thriller", "drama"], cast: [2, 4, 8], directorIdx: 5 },
  { slug: "the-last-protocol", title: "The Last Protocol", persianTitle: "پروتکل آخر", theme: "جاسوسی و توطئه بین‌المللی", shortDesc: "مأموری که برای آخرین بار فراخوانده می‌شود.", imdb: 8.0, year: 2024, duration: 128, country: "uk", language: "en", ageRating: "16+", quality: "1080p", isDubbed: true, isFeatured: true, isTrending: false, isNew: true, isPremium: true, views: 156000, featuredOrder: 4, genres: ["action", "thriller", "crime"], cast: [0, 11, 13], directorIdx: 1 },
  { slug: "crimson-sky", title: "Crimson Sky", persianTitle: "آسمان سرخ", theme: "عشق و انقلاب در آسمانی سرخ", shortDesc: "دو دل در میان آشوب یک انقلاب.", imdb: 8.4, year: 2023, duration: 134, country: "france", language: "fr", ageRating: "13+", quality: "1080p", isDubbed: true, isFeatured: true, isTrending: false, isNew: true, isPremium: false, views: 243000, featuredOrder: 5, genres: ["romance", "drama", "historical"], cast: [14, 9, 2], directorIdx: 2 },
  { slug: "silent-frequency", title: "Silent Frequency", persianTitle: "فرکانس سکوت", theme: "رازهای امواج رادیویی و یک شهر گمشده", shortDesc: "صدایی از اعماق زمان شکافته می‌شود.", imdb: 7.9, year: 2024, duration: 121, country: "canada", language: "en", ageRating: "13+", quality: "1080p", isDubbed: false, isFeatured: true, isTrending: true, isNew: true, isPremium: false, views: 198000, featuredOrder: 6, genres: ["sci-fi", "mystery", "thriller"], cast: [6, 12, 19], directorIdx: 9 },
  { slug: "iron-covenant", title: "Iron Covenant", persianTitle: "پیمان آهنین", theme: "وفاداری و خیانت در میان برادران اسلحه", shortDesc: "یک پیمان کهنه در برابر خون جدید.", imdb: 7.6, year: 2022, duration: 130, country: "usa", language: "en", ageRating: "18+", quality: "1080p", isDubbed: false, isFeatured: false, isTrending: true, isNew: false, isPremium: true, views: 287000, featuredOrder: 0, genres: ["crime", "action", "drama"], cast: [3, 1, 6], directorIdx: 5 },
  { slug: "echoes-of-tomorrow", title: "Echoes of Tomorrow", persianTitle: "پژواک‌های فردا", theme: "زمان و سرنوشت در یک حلقه بی‌انتها", shortDesc: "اگر فردا را دیدی، چه می‌کردی؟", imdb: 8.1, year: 2023, duration: 145, country: "uk", language: "en", ageRating: "13+", quality: "2160p", isDubbed: true, isFeatured: false, isTrending: true, isNew: false, isPremium: true, views: 356000, featuredOrder: 0, genres: ["sci-fi", "drama", "mystery"], cast: [5, 14, 8], directorIdx: 0 },
  { slug: "the-glass-city", title: "The Glass City", persianTitle: "شهر شیشه‌ای", theme: "توهم و واقعیت در شهر شفاف", shortDesc: "هیچ چیز آنطور که به نظر می‌رسد نیست.", imdb: 7.8, year: 2024, duration: 118, country: "south-korea", language: "ko", ageRating: "16+", quality: "1080p", isDubbed: false, isFeatured: false, isTrending: true, isNew: true, isPremium: false, views: 134000, featuredOrder: 0, genres: ["mystery", "thriller", "drama"], cast: [17, 12, 4], directorIdx: 3 },
  { slug: "black-meridian", title: "Black Meridian", persianTitle: "نیمروزگان سیاه", theme: "نفرین یک خط جغرافیایی مرموز", shortDesc: "روی خطی که نباید از آن عبور کنی.", imdb: 7.4, year: 2021, duration: 124, country: "germany", language: "de", ageRating: "18+", quality: "1080p", isDubbed: false, isFeatured: false, isTrending: false, isNew: false, isPremium: true, views: 98000, featuredOrder: 0, genres: ["horror", "mystery", "thriller"], cast: [7, 2, 9], directorIdx: 6 },
  { slug: "shadow-protocol", title: "Shadow Protocol", persianTitle: "پروتکل سایه", theme: "جاسوسی سایبری در عصر جدید", shortDesc: "هیچ رازی در سایه‌ها پنهان نمی‌ماند.", imdb: 7.7, year: 2023, duration: 132, country: "usa", language: "en", ageRating: "16+", quality: "1080p", isDubbed: true, isFeatured: false, isTrending: false, isNew: true, isPremium: false, views: 167000, featuredOrder: 0, genres: ["action", "crime", "thriller"], cast: [11, 13, 0], directorIdx: 8 },
  { slug: "the-fall-of-empire", title: "The Fall of Empire", persianTitle: "سقوط امپراتوری", theme: "قدرت، فساد و فروپاشی", shortDesc: "هر امپراتوریی روزی سقوط می‌کند.", imdb: 8.6, year: 2020, duration: 156, country: "uk", language: "en", ageRating: "16+", quality: "2160p", isDubbed: false, isFeatured: false, isTrending: true, isNew: false, isPremium: true, views: 401000, featuredOrder: 0, genres: ["drama", "historical", "war"], cast: [1, 4, 5], directorIdx: 7 },
  { slug: "velocity", title: "Velocity", persianTitle: "سرعت", theme: "مسابقه و بقا در جاده‌های مرگ", shortDesc: "سرعت تنها راه زنده ماندن است.", imdb: 7.2, year: 2024, duration: 110, country: "usa", language: "en", ageRating: "13+", quality: "1080p", isDubbed: true, isFeatured: false, isTrending: false, isNew: true, isPremium: false, views: 145000, featuredOrder: 0, genres: ["action", "sport", "adventure"], cast: [7, 10, 13], directorIdx: 1 },
  { slug: "the-blue-hour", title: "The Blue Hour", persianTitle: "ساعت آبی", theme: "عشق ممنوعه در ساعت جادویی شب", shortDesc: "یک شب، یک عشق، یک فرار.", imdb: 7.9, year: 2022, duration: 117, country: "france", language: "fr", ageRating: "16+", quality: "1080p", isDubbed: false, isFeatured: false, isTrending: false, isNew: false, isPremium: true, views: 178000, featuredOrder: 0, genres: ["romance", "drama"], cast: [14, 9, 12], directorIdx: 2 },
  { slug: "asphalt-kings", title: "Asphalt Kings", persianTitle: "پادشاهان آسفالت", theme: "دنیای زیرزمینی مسابقات خیابانی", shortDesc: "در شب، جاده‌ها متعلق به آن‌هاست.", imdb: 7.0, year: 2023, duration: 122, country: "japan", language: "ja", ageRating: "16+", quality: "1080p", isDubbed: true, isFeatured: false, isTrending: true, isNew: false, isPremium: false, views: 211000, featuredOrder: 0, genres: ["action", "crime", "thriller"], cast: [11, 6, 17], directorIdx: 8 },
  { slug: "the-tenth-signal", title: "The Tenth Signal", persianTitle: "سیگنال دهم", theme: "تماس با هوش فرازمینی", shortDesc: "دهمین پیام، آخرین هشدار است.", imdb: 8.3, year: 2021, duration: 140, country: "usa", language: "en", ageRating: "13+", quality: "2160p", isDubbed: false, isFeatured: false, isTrending: false, isNew: false, isPremium: true, views: 276000, featuredOrder: 0, genres: ["sci-fi", "mystery", "drama"], cast: [5, 8, 19], directorIdx: 0 },
  { slug: "after-the-rain", title: "After the Rain", persianTitle: "بعد از باران", theme: "شفای روح در روستایی دورافتاده", shortDesc: "بعد از هر بارانی، رنگی تازه می‌روید.", imdb: 7.5, year: 2024, duration: 108, country: "japan", language: "ja", ageRating: "7+", quality: "1080p", isDubbed: true, isFeatured: false, isTrending: false, isNew: true, isPremium: false, views: 89000, featuredOrder: 0, genres: ["drama", "romance", "family"], cast: [12, 9, 14], directorIdx: 3 },
  { slug: "the-frozen-sea", title: "The Frozen Sea", persianTitle: "دریای یخ‌زده", theme: "سفر اکتشافی به قلب قطب", shortDesc: "زیر یخ‌ها رازی هزاران ساله خفته است.", imdb: 7.8, year: 2022, duration: 126, country: "sweden", language: "sv", ageRating: "13+", quality: "1080p", isDubbed: false, isFeatured: false, isTrending: false, isNew: false, isPremium: true, views: 142000, featuredOrder: 0, genres: ["adventure", "mystery", "drama"], cast: [13, 2, 4], directorIdx: 9 },
  { slug: "gravity-bound", title: "Gravity Bound", persianTitle: "اسیر جاذبه", theme: "نجات در فضا و بحران گرانش", shortDesc: "جاذبه می‌کشد، امید نگه می‌دارد.", imdb: 8.5, year: 2020, duration: 130, country: "usa", language: "en", ageRating: "13+", quality: "2160p", isDubbed: false, isFeatured: false, isTrending: true, isNew: false, isPremium: true, views: 388000, featuredOrder: 0, genres: ["sci-fi", "adventure", "drama"], cast: [6, 1, 3], directorIdx: 1 },
  { slug: "the-architect", title: "The Architect", persianTitle: "معمار", theme: "مغزی که شهرها را طراحی کرد و جنون را", shortDesc: "طرح یک عمر، جنون یک لحظه.", imdb: 7.6, year: 2023, duration: 119, country: "germany", language: "de", ageRating: "16+", quality: "1080p", isDubbed: true, isFeatured: false, isTrending: false, isNew: true, isPremium: true, views: 121000, featuredOrder: 0, genres: ["drama", "mystery", "biography"], cast: [4, 5, 8], directorIdx: 9 },
  { slug: "wildfront", title: "Wildfront", persianTitle: "مرز وحشی", theme: "غرب وحشی و یک قانون‌گذار جدید", shortDesc: "در مرز، قانون زنده می‌ماند.", imdb: 7.3, year: 2021, duration: 134, country: "usa", language: "en", ageRating: "16+", quality: "1080p", isDubbed: false, isFeatured: false, isTrending: false, isNew: false, isPremium: false, views: 95000, featuredOrder: 0, genres: ["western", "adventure", "action"], cast: [7, 0, 13], directorIdx: 7 },
  { slug: "paper-lanterns", title: "Paper Lanterns", persianTitle: "فانوس‌های کاغذی", theme: "سنتی، خانوادگی و جشنواره نور", shortDesc: "هر فانوس، یک آرزوی پنهان.", imdb: 7.7, year: 2024, duration: 102, country: "china", language: "zh", ageRating: "7+", quality: "1080p", isDubbed: true, isFeatured: false, isTrending: false, isNew: true, isPremium: false, views: 76000, featuredOrder: 0, genres: ["family", "drama", "fantasy"], cast: [12, 14, 9], directorIdx: 2 },
  { slug: "the-reckoning", title: "The Reckoning", persianTitle: "تسویه حساب", theme: "انتقام و عدالت در دنیای تاریک", shortDesc: "هر بدهی، روز پرداخت دارد.", imdb: 7.9, year: 2022, duration: 128, country: "uk", language: "en", ageRating: "18+", quality: "1080p", isDubbed: false, isFeatured: false, isTrending: true, isNew: false, isPremium: true, views: 234000, featuredOrder: 0, genres: ["crime", "thriller", "action"], cast: [3, 1, 6], directorIdx: 5 },
  { slug: "north-star", title: "North Star", persianTitle: "ستاره قطبی", theme: "هدایت امید در تاریکی مطلق", shortDesc: "یک ستاره، یک مسیر، یک نجات.", imdb: 8.0, year: 2023, duration: 115, country: "denmark", language: "da", ageRating: "13+", quality: "1080p", isDubbed: true, isFeatured: false, isTrending: false, isNew: false, isPremium: false, views: 167000, featuredOrder: 0, genres: ["drama", "adventure", "biography"], cast: [8, 4, 19], directorIdx: 8 },
  { slug: "the-crimson-veil", title: "The Crimson Veil", persianTitle: "نقاب سرخ", theme: "توهم، خشم و یک نقاب سرخ", shortDesc: "پشت نقاب، حقیقتی خونین نهفته است.", imdb: 7.4, year: 2024, duration: 113, country: "italy", language: "it", ageRating: "18+", quality: "1080p", isDubbed: false, isFeatured: false, isTrending: false, isNew: true, isPremium: true, views: 102000, featuredOrder: 0, genres: ["horror", "mystery", "thriller"], cast: [2, 12, 14], directorIdx: 6 },
];

// Series definitions
type SeriesDef = {
  slug: string;
  title: string;
  persianTitle: string;
  theme: string;
  shortDesc: string;
  imdb: number;
  year: number;
  totalSeasons: number;
  endYear?: number;
  country: string;
  language: string;
  ageRating: string;
  quality: string;
  isDubbed: boolean;
  isFeatured: boolean;
  isTrending: boolean;
  isNew: boolean;
  isPremium: boolean;
  views: number;
  genres: string[];
  cast: number[];
  directorIdx: number;
  seasons: { number: number; year: number; episodes: number }[];
};

const seriesDefs: SeriesDef[] = [
  { slug: "throne-of-shadows", title: "Throne of Shadows", persianTitle: "بازی تاج و تخت سایه‌ها", theme: "قدرت، خیانت و فروپاشی خاندان‌ها", shortDesc: "در بازی تاج، هیچ‌کس در امان نیست.", imdb: 9.1, year: 2019, totalSeasons: 2, endYear: 2023, country: "usa", language: "en", ageRating: "18+", quality: "2160p", isDubbed: true, isFeatured: true, isTrending: true, isNew: false, isPremium: true, views: 920000, genres: ["drama", "fantasy", "historical"], cast: [2, 5, 11, 4], directorIdx: 1, seasons: [{ number: 1, year: 2019, episodes: 6 }, { number: 2, year: 2023, episodes: 4 }] },
  { slug: "city-lights", title: "City Lights", persianTitle: "چراغ‌های شهر", theme: "عشق و توهم در شهر نور", shortDesc: "هر چراغ، داستانی از دل‌شکستگی.", imdb: 8.7, year: 2022, totalSeasons: 2, country: "south-korea", language: "ko", ageRating: "16+", quality: "1080p", isDubbed: false, isFeatured: false, isTrending: true, isNew: false, isPremium: false, views: 612000, genres: ["drama", "romance"], cast: [17, 12, 14], directorIdx: 3, seasons: [{ number: 1, year: 2022, episodes: 5 }] },
  { slug: "shadows-of-silence", title: "Shadows of Silence", persianTitle: "سایه‌های سکوت", theme: "رازهای یک شهر ساکت", shortDesc: "سکوت، بلندترین فریاد است.", imdb: 8.4, year: 2023, totalSeasons: 1, country: "uk", language: "en", ageRating: "16+", quality: "1080p", isDubbed: true, isFeatured: false, isTrending: false, isNew: true, isPremium: true, views: 345000, genres: ["mystery", "crime", "thriller"], cast: [0, 4, 8], directorIdx: 6, seasons: [{ number: 1, year: 2023, episodes: 6 }] },
  { slug: "fracture-line", title: "Fracture Line", persianTitle: "خط شکست", theme: "زلزله، فروپاشی و دوباره ساختن", shortDesc: "وقتی زمین می‌شکند، انسان می‌ماند.", imdb: 8.0, year: 2024, totalSeasons: 1, country: "japan", language: "ja", ageRating: "13+", quality: "1080p", isDubbed: false, isFeatured: false, isTrending: true, isNew: true, isPremium: false, views: 234000, genres: ["drama", "adventure"], cast: [13, 9, 12], directorIdx: 2, seasons: [{ number: 1, year: 2024, episodes: 4 }] },
  { slug: "project-match", title: "Project Match", persianTitle: "پروژه کبریت", theme: "سازمان مخفی و جنگ اطلاعاتی", shortDesc: "یک جرقه، همه‌چیز را روشن می‌کند.", imdb: 8.5, year: 2021, totalSeasons: 2, endYear: 2023, country: "usa", language: "en", ageRating: "16+", quality: "1080p", isDubbed: true, isFeatured: false, isTrending: false, isNew: false, isPremium: true, views: 478000, genres: ["crime", "thriller", "action"], cast: [11, 1, 19], directorIdx: 8, seasons: [{ number: 1, year: 2021, episodes: 5 }, { number: 2, year: 2023, episodes: 4 }] },
  { slug: "final-route", title: "Final Route", persianTitle: "مسیر نهایی", theme: "مسابقه مرگ و آزادی", shortDesc: "تنها یک نفر به خط پایان می‌رسد.", imdb: 7.9, year: 2024, totalSeasons: 1, country: "south-korea", language: "ko", ageRating: "18+", quality: "1080p", isDubbed: false, isFeatured: false, isTrending: true, isNew: true, isPremium: true, views: 287000, genres: ["action", "thriller", "drama"], cast: [7, 10, 17], directorIdx: 3, seasons: [{ number: 1, year: 2024, episodes: 6 }] },
];

// Episode titles per series
const EPISODE_TITLES = [
  "آغاز", "سایه‌ها", "افشا", "خط قرمز", "نقطه بازگشت", "تسویه",
  "پیمان", "فروپاشی", "حقیقت پنهان", "آخرین نفس",
];

// Live categories
const liveCategoryData = [
  { name: "Entertainment", slug: "entertainment", persianName: "سرگرمی", sortOrder: 0 },
  { name: "News", slug: "news", persianName: "خبری", sortOrder: 1 },
  { name: "Sports", slug: "sports", persianName: "ورزشی", sortOrder: 2 },
  { name: "Music", slug: "music", persianName: "موسیقی", sortOrder: 3 },
  { name: "Kids", slug: "kids", persianName: "کودک", sortOrder: 4 },
  { name: "Movies", slug: "movies", persianName: "فیلم", sortOrder: 5 },
  { name: "Documentary", slug: "documentary", persianName: "مستند", sortOrder: 6 },
  { name: "Religion", slug: "religion", persianName: "مذهبی", sortOrder: 7 },
];

// Live channels: 12+ across categories
const liveChannelData = [
  { name: "PeepBox TV", slug: "peepbox-tv", persianName: "پیت‌باکس تی‌وی", categorySlug: "entertainment", color1: "#7C3AED", color2: "#EC4899", lang: "fa", nowPlaying: "برنامه زنده شبانه", nextProgram: "میزگرد فیلم", viewers: 12400 },
  { name: "Cinema Channel", slug: "cinema-channel", persianName: "شبکه فیلم", categorySlug: "movies", color1: "#22D3EE", color2: "#3B82F6", lang: "fa", nowPlaying: "فیلم سینمایی", nextProgram: "نقد و بررسی", viewers: 8900 },
  { name: "Music Plus", slug: "music-plus", persianName: "موزیک پلاس", categorySlug: "music", color1: "#F59E0B", color2: "#EF4444", lang: "fa", nowPlaying: "کنسرت زنده", nextProgram: "بهترین‌های هفته", viewers: 6700 },
  { name: "Sport One", slug: "sport-one", persianName: "اسپرت۱", categorySlug: "sports", color1: "#10B981", color2: "#22D3EE", lang: "fa", nowPlaying: "مسابقه فوتبال", nextProgram: "خلاصه بازی‌ها", viewers: 18900 },
  { name: "Kids Land", slug: "kids-land", persianName: "کودک‌لند", categorySlug: "kids", color1: "#EC4899", color2: "#8B5CF6", lang: "fa", nowPlaying: "انیمیشن شب", nextProgram: "آموزش نقاشی", viewers: 5400 },
  { name: "Doc Plus", slug: "doc-plus", persianName: "مستند پلاس", categorySlug: "documentary", color1: "#3B82F6", color2: "#06B6D4", lang: "fa", nowPlaying: "اسرار اقیانوس", nextProgram: "جهان حیوانات", viewers: 4200 },
  { name: "Negah News", slug: "negah-news", persianName: "خبر نگاه", categorySlug: "news", color1: "#A855F7", color2: "#6366F1", lang: "fa", nowPlaying: "اخبار ساعت ۲۱", nextProgram: "تحلیل روز", viewers: 15600 },
  { name: "Aram", slug: "aram", persianName: "آرامش", categorySlug: "religion", color1: "#F97316", color2: "#EC4899", lang: "fa", nowPlaying: "موعظه شب", nextProgram: "نوحه‌خوانی", viewers: 3100 },
  { name: "Game Stream", slug: "game-stream", persianName: "گیم استریم", categorySlug: "entertainment", color1: "#7C3AED", color2: "#22D3EE", lang: "fa", nowPlaying: "مسابقه آنلاین", nextProgram: "نقد بازی", viewers: 9800 },
  { name: "World News", slug: "world-news", persianName: "جهان خبر", categorySlug: "news", color1: "#22D3EE", color2: "#7C3AED", lang: "en", nowPlaying: "World News Live", nextProgram: "Tech Report", viewers: 11200 },
  { name: "Classic Movies", slug: "classic-movies", persianName: "کلاسیک سینما", categorySlug: "movies", color1: "#EC4899", color2: "#F59E0B", lang: "en", nowPlaying: "Classic Hour", nextProgram: "Director Cut", viewers: 4500 },
  { name: "Live Sports 2", slug: "live-sports-2", persianName: "ورزش زنده ۲", categorySlug: "sports", color1: "#10B981", color2: "#F59E0B", lang: "fa", nowPlaying: "بسکتبال", nextProgram: "کشتی کج", viewers: 7600 },
  { name: "Animation TV", slug: "animation-tv", persianName: "انیمیشن تی‌وی", categorySlug: "kids", color1: "#8B5CF6", color2: "#EC4899", lang: "fa", nowPlaying: "سریال انیمیشنی", nextProgram: "کارتون کوتاه", viewers: 6300 },
  { name: "Documentary World", slug: "documentary-world", persianName: "دنیای مستند", categorySlug: "documentary", color1: "#3B82F6", color2: "#10B981", lang: "en", nowPlaying: "Nature Documentary", nextProgram: "History Hour", viewers: 5200 },
];

// Music artists
const musicArtistData = [
  { name: "Aria Sound", slug: "aria-sound", persianName: "آریا ساند", bio: "هنرمند موسیقی الکترونیک با سبک امبینت و سینث‌ویو.", monthlyListeners: 245000, verified: true },
  { name: "Nocturne", slug: "nocturne", persianName: "نوکتورن", bio: "پروژه موسیقی خلوت‌شبانه با نت‌های جazz و الکترونیک.", monthlyListeners: 187000, verified: true },
  { name: "The Velvet Hours", slug: "the-velvet-hours", persianName: "ساعات مخملی", bio: "گروه ایندی راک با حس و حال نوستالژیک.", monthlyListeners: 134000, verified: false },
  { name: "Mira Lo", slug: "mira-lo", persianName: "میرا لو", bio: "خواننده پاپ زیرزمینی با صدای اتییر.", monthlyListeners: 312000, verified: true },
  { name: "Pulse Theory", slug: "pulse-theory", persianName: "پالس تئوری", bio: "تیم تهیه‌کننده موسیقی الکترونیک رقص.", monthlyListeners: 198000, verified: false },
  { name: "Desert Echo", slug: "desert-echo", persianName: "پژواک صحرا", bio: "ترکیب موسیقی فولکلور شرقی با الکترونیک مدرن.", monthlyListeners: 156000, verified: true },
  { name: "Solar Field", slug: "solar-field", persianName: "میدان خورشیدی", bio: "آهنگساز موسیقی فضایی و امبینت.", monthlyListeners: 98000, verified: false },
];

// Music albums: at least 8
const musicAlbumData = [
  { artistSlug: "aria-sound", title: "Neon Dreams", persianTitle: "رویاهای نئون", year: 2023, genre: "Electronic", tracksCount: 4, colorIdx: 0 },
  { artistSlug: "nocturne", title: "Midnight Tape", persianTitle: "نوار نیمه‌شب", year: 2022, genre: "Jazz", tracksCount: 4, colorIdx: 1 },
  { artistSlug: "the-velvet-hours", title: "Velvet Road", persianTitle: "جاده مخملی", year: 2024, genre: "Indie Rock", tracksCount: 3, colorIdx: 2 },
  { artistSlug: "mira-lo", title: "Echoes", persianTitle: "پژواک‌ها", year: 2023, genre: "Pop", tracksCount: 4, colorIdx: 3 },
  { artistSlug: "pulse-theory", title: "Bass Theory", persianTitle: "تئوری بیس", year: 2024, genre: "EDM", tracksCount: 3, colorIdx: 4 },
  { artistSlug: "desert-echo", title: "Sandstorm", persianTitle: "طوفان شن", year: 2022, genre: "World", tracksCount: 3, colorIdx: 5 },
  { artistSlug: "aria-sound", title: "Horizon", persianTitle: "افق", year: 2024, genre: "Ambient", tracksCount: 3, colorIdx: 6 },
  { artistSlug: "solar-field", title: "Stellar", persianTitle: "ستاره‌ای", year: 2023, genre: "Ambient", tracksCount: 3, colorIdx: 7 },
];

// Track titles (per album)
const TRACK_TITLES = [
  "Opening", "First Light", "Drift", "Fade", "Reverie", "Cascade",
  "Aurora", "Liminal", "Mirage", "Pulse", "Velvet", "Sandstorm",
];

// Subscription plans
const planData = [
  { name: "free", persianName: "رایگان", priceMonthly: 0, priceQuarterly: 0, priceYearly: 0, maxDevices: 1, maxQuality: "720p", hasPremium: false, hasLiveTv: false, hasMusic: true, hasAds: true, concurrentStreams: 1, color: "#94A3B8", features: '["کیفیت 720p","۱ دستگاه","موسیقی محدود","با تبلیغ"]', sortOrder: 0 },
  { name: "basic", persianName: "پایه", priceMonthly: 49000, priceQuarterly: 130000, priceYearly: 490000, maxDevices: 1, maxQuality: "1080p", hasPremium: false, hasLiveTv: false, hasMusic: true, hasAds: false, concurrentStreams: 1, color: "#22D3EE", features: '["کیفیت 1080p","۱ دستگاه","بدون تبلیغ","دانلود محدود"]', sortOrder: 1 },
  { name: "standard", persianName: "استاندارد", priceMonthly: 99000, priceQuarterly: 270000, priceYearly: 990000, maxDevices: 2, maxQuality: "1080p", hasPremium: true, hasLiveTv: false, hasMusic: true, hasAds: false, concurrentStreams: 2, color: "#7C3AED", features: '["کیفیت 1080p","۲ دستگاه همزمان","محتوای ویژه","بدون تبلیغ"]', sortOrder: 2 },
  { name: "premium", persianName: "پرمیوم", priceMonthly: 149000, priceQuarterly: 410000, priceYearly: 1490000, maxDevices: 4, maxQuality: "2160p", hasPremium: true, hasLiveTv: true, hasMusic: true, hasAds: false, concurrentStreams: 4, color: "#EC4899", features: '["کیفیت 4K HDR","۴ دستگاه همزمان","تلویزیون زنده","موسیقی بی‌نهایت","بدون تبلیغ"]', sortOrder: 3 },
  { name: "vip", persianName: "وی‌آی‌پی", priceMonthly: 249000, priceQuarterly: 690000, priceYearly: 2490000, maxDevices: 6, maxQuality: "2160p", hasPremium: true, hasLiveTv: true, hasMusic: true, hasAds: false, concurrentStreams: 6, color: "#F59E0B", features: '["کیفیت 4K HDR","۶ دستگاه همزمان","تلویزیون زنده","موسیقی بی‌نهایت","محتوای انحصاری","پشتیبانی ۲۴/۷","بدون تبلیغ"]', sortOrder: 4 },
];

// Users
const userData = [
  { email: "admin@peepboxtv.me", name: "مدیر PeepBox", role: "admin", plan: "vip", referralCode: "PEEPBOX", referredById: null, passwordHash: "demo-admin-hash" },
  { email: "user1@peepboxtv.me", name: "آرش رضایی", role: "user", plan: "premium", referralCode: "USER1X9K", referredById: null, passwordHash: "demo-hash" },
  { email: "user2@peepboxtv.me", name: "سارا محمدی", role: "user", plan: "standard", referralCode: "USER2PLQ", referredById: null, passwordHash: "demo-hash" },
  { email: "user3@peepboxtv.me", name: "محمد کریمی", role: "user", plan: "basic", referralCode: "USER3R7M", referredById: null, passwordHash: "demo-hash" },
  { email: "user4@peepboxtv.me", name: "نگار احمدی", role: "user", plan: "free", referralCode: "USER4TZB", referredById: null, passwordHash: "demo-hash" },
];

// Settings
const settingData: { key: string; value: string; group: string }[] = [
  { key: "site_name", value: "PeepBox", group: "general" },
  { key: "site_tagline", value: "سرگرمی، بدون مرز", group: "general" },
  { key: "primary_color", value: "#7C3AED", group: "general" },
  { key: "secondary_color", value: "#EC4899", group: "general" },
  { key: "accent_color", value: "#22D3EE", group: "general" },
  { key: "feature_ai", value: "true", group: "general" },
  { key: "feature_music", value: "true", group: "general" },
  { key: "feature_live", value: "true", group: "general" },
  { key: "feature_ads", value: "true", group: "ads" },
  { key: "feature_referral", value: "true", group: "general" },
  { key: "feature_wallet", value: "true", group: "general" },
  { key: "feature_pwa", value: "true", group: "pwa" },
  { key: "smtp_enabled", value: "false", group: "smtp" },
  { key: "tmdb_enabled", value: "false", group: "tmdb" },
  { key: "ai_model", value: "glm-4.6", group: "ai" },
  { key: "contact_email", value: "support@peepboxtv.me", group: "general" },
];

// ===================== Main =====================

async function main() {
  console.log("🗑️  Clearing existing data...");
  await db.$transaction([
    db.walletTransaction.deleteMany(),
    db.wallet.deleteMany(),
    db.payment.deleteMany(),
    db.subscription.deleteMany(),
    db.playlistTrack.deleteMany(),
    db.playlist.deleteMany(),
    db.favorite.deleteMany(),
    db.watchHistory.deleteMany(),
    db.device.deleteMany(),
    db.notification.deleteMany(),
    db.referralTransaction.deleteMany(),
    db.advertisement.deleteMany(),
    db.searchLog.deleteMany(),
    db.auditLog.deleteMany(),
    db.securityLog.deleteMany(),
    db.coupon.deleteMany(),
    db.videoSource.deleteMany(),
    db.episode.deleteMany(),
    db.season.deleteMany(),
    db.movieCast.deleteMany(),
    db.movieDirector.deleteMany(),
    db.seriesCast.deleteMany(),
    db.seriesDirector.deleteMany(),
    db.movie.deleteMany(),
    db.series.deleteMany(),
    db.musicTrack.deleteMany(),
    db.musicAlbum.deleteMany(),
    db.musicArtist.deleteMany(),
    db.liveChannel.deleteMany(),
    db.liveCategory.deleteMany(),
    db.actor.deleteMany(),
    db.director.deleteMany(),
    db.genre.deleteMany(),
    db.country.deleteMany(),
    db.subscriptionPlan.deleteMany(),
    db.setting.deleteMany(),
    db.user.deleteMany(),
  ]);
  console.log("✅ Cleared.");

  // ----- Taxonomy -----
  console.log("🌱 Seeding genres, countries, actors, directors...");
  const genres = await Promise.all(genreData.map((g) => db.genre.create({ data: g })));
  const genreMap = new Map(genres.map((g) => [g.slug, g]));
  const countries = await Promise.all(countryData.map((c) => db.country.create({ data: c })));
  const countryMap = new Map(countries.map((c) => [c.slug, c]));
  const actors = await Promise.all(actorData.map((a) => db.actor.create({ data: a })));
  const directors = await Promise.all(directorData.map((d) => db.director.create({ data: d })));

  // ----- Settings -----
  console.log("⚙️  Seeding settings...");
  await db.setting.createMany({ data: settingData });

  // ----- Subscription Plans -----
  console.log("💳 Seeding subscription plans...");
  const plans = await Promise.all(planData.map((p) => db.subscriptionPlan.create({ data: p })));
  const planMap = new Map(plans.map((p) => [p.name, p]));

  // ----- Movies + sources + cast + directors -----
  console.log("🎬 Seeding 24 movies...");
  const movieIds: string[] = [];
  for (let i = 0; i < movieDefs.length; i++) {
    const m = movieDefs[i];
    const movie = await db.movie.create({
      data: {
        slug: m.slug,
        title: m.title,
        persianTitle: m.persianTitle,
        originalTitle: m.originalTitle ?? null,
        description: makeDesc(m.persianTitle, m.theme),
        shortDesc: m.shortDesc,
        poster: null,
        backdrop: m.isFeatured ? `/images/heroes/hero-${m.featuredOrder}.jpg` : null,
        trailer: null,
        imdbRating: m.imdb,
        releaseYear: m.year,
        duration: m.duration,
        countryId: countryMap.get(m.country)!.id,
        language: m.language,
        ageRating: m.ageRating,
        quality: m.quality,
        isDubbed: m.isDubbed,
        hasSubtitle: true,
        isFeatured: m.isFeatured,
        isTrending: m.isTrending,
        isNew: m.isNew,
        isPremium: m.isPremium,
        status: "published",
        views: m.views,
        featuredOrder: m.featuredOrder,
        genres: { connect: m.genres.map((s) => ({ id: genreMap.get(s)!.id })) },
      },
    });
    movieIds.push(movie.id);

    // Cast (2-4 actors)
    for (let k = 0; k < m.cast.length; k++) {
      const actorIdx = m.cast[k];
      await db.movieCast.create({
        data: {
          movieId: movie.id,
          actorId: actors[actorIdx].id,
          role: CHAR_NAMES[(i * 3 + k) % CHAR_NAMES.length],
          order: k,
        },
      });
    }
    // Director
    await db.movieDirector.create({
      data: { movieId: movie.id, directorId: directors[m.directorIdx].id },
    });

    // 3 video sources per movie (720p, 1080p HLS, 2160p)
    await db.videoSource.create({
      data: { movieId: movie.id, quality: "720p", url: pick(MP4_URLS, i * 2 + 1), isHls: true, size: 800 },
    });
    await db.videoSource.create({
      data: { movieId: movie.id, quality: "1080p", url: HLS_1080P, isHls: true, size: 1500 },
    });
    await db.videoSource.create({
      data: { movieId: movie.id, quality: "2160p", url: pick(MP4_URLS, i * 2 + 2), isHls: true, size: 6000 },
    });
  }

  // ----- Series + seasons + episodes + sources -----
  console.log("📺 Seeding series with seasons & episodes...");
  const episodeIds: string[] = [];
  for (let i = 0; i < seriesDefs.length; i++) {
    const s = seriesDefs[i];
    const series = await db.series.create({
      data: {
        slug: s.slug,
        title: s.title,
        persianTitle: s.persianTitle,
        description: makeDesc(s.persianTitle, s.theme),
        shortDesc: s.shortDesc,
        poster: null,
        backdrop: null,
        trailer: null,
        imdbRating: s.imdb,
        releaseYear: s.year,
        endYear: s.endYear ?? null,
        totalSeasons: s.totalSeasons,
        countryId: countryMap.get(s.country)!.id,
        language: s.language,
        ageRating: s.ageRating,
        quality: s.quality,
        isDubbed: s.isDubbed,
        hasSubtitle: true,
        isFeatured: s.isFeatured,
        isTrending: s.isTrending,
        isNew: s.isNew,
        isPremium: s.isPremium,
        status: "published",
        views: s.views,
        featuredOrder: 0,
        genres: { connect: s.genres.map((g) => ({ id: genreMap.get(g)!.id })) },
      },
    });

    // Cast
    for (let k = 0; k < s.cast.length; k++) {
      const actorIdx = s.cast[k];
      await db.seriesCast.create({
        data: {
          seriesId: series.id,
          actorId: actors[actorIdx].id,
          role: CHAR_NAMES[(i * 4 + k) % CHAR_NAMES.length],
          order: k,
        },
      });
    }
    // Director
    await db.seriesDirector.create({
      data: { seriesId: series.id, directorId: directors[s.directorIdx].id },
    });

    // Seasons + Episodes
    for (const seasonDef of s.seasons) {
      const season = await db.season.create({
        data: {
          seriesId: series.id,
          number: seasonDef.number,
          title: `فصل ${seasonDef.number}`,
          year: seasonDef.year,
          episodesCount: seasonDef.episodes,
        },
      });
      for (let e = 1; e <= seasonDef.episodes; e++) {
        const ep = await db.episode.create({
          data: {
            seriesId: series.id,
            seasonId: season.id,
            number: e,
            title: EPISODE_TITLES[(e - 1) % EPISODE_TITLES.length],
            description: `قسمت ${e} از فصل ${seasonDef.number} سریال ${s.persianTitle}. در این قسمت، روایت داستان با چالشی جدید پیش می‌رود.`,
            duration: rand(40, 65),
            videoUrl: pick(MP4_URLS, e + seasonDef.number * 3),
            airDate: daysAgo(rand(30, 600)),
            views: rand(5000, 200000),
          },
        });
        episodeIds.push(ep.id);
        // Add video sources for the first episode of each season
        if (e === 1) {
          await db.videoSource.create({
            data: { episodeId: ep.id, quality: "1080p", url: HLS_1080P, isHls: true, size: 1500 },
          });
          await db.videoSource.create({
            data: { episodeId: ep.id, quality: "720p", url: pick(MP4_URLS, e + 1), isHls: true, size: 800 },
          });
        }
      }
    }
  }

  // ----- Live TV -----
  console.log("📡  Seeding live TV categories & channels...");
  const liveCategories = await Promise.all(liveCategoryData.map((c) => db.liveCategory.create({ data: c })));
  const liveCategoryMap = new Map(liveCategories.map((c) => [c.slug, c]));
  for (let i = 0; i < liveChannelData.length; i++) {
    const c = liveChannelData[i];
    await db.liveChannel.create({
      data: {
        name: c.name,
        slug: c.slug,
        persianName: c.persianName,
        logo: null,
        logoColor1: c.color1,
        logoColor2: c.color2,
        streamUrl: LIVE_HLS[i % LIVE_HLS.length],
        categoryId: liveCategoryMap.get(c.categorySlug)!.id,
        countryId: countryMap.get("iran")?.id ?? null,
        language: c.lang,
        quality: "1080p",
        status: "online",
        isFavorite: false,
        sortOrder: i,
        nowPlaying: c.nowPlaying,
        nextProgram: c.nextProgram,
        viewers: c.viewers,
      },
    });
  }

  // ----- Music -----
  console.log("🎵 Seeding music artists, albums, tracks...");
  const musicArtists = await Promise.all(musicArtistData.map((a) => db.musicArtist.create({ data: a })));
  const artistMap = new Map(musicArtists.map((a) => [a.slug, a]));

  const trackIds: string[] = [];
  for (let i = 0; i < musicAlbumData.length; i++) {
    const a = musicAlbumData[i];
    const artist = artistMap.get(a.artistSlug)!;
    const colors = CREW_PALETTE[a.colorIdx];
    const album = await db.musicAlbum.create({
      data: {
        artistId: artist.id,
        title: a.title,
        slug: `${a.title.toLowerCase().replace(/[^a-z0-9]+/g, "-")}-${i}`,
        persianTitle: a.persianTitle,
        cover: null,
        coverColor1: colors[0],
        coverColor2: colors[1],
        year: a.year,
        genre: a.genre,
        tracksCount: a.tracksCount,
      },
    });

    // Create tracks for this album
    for (let t = 0; t < a.tracksCount; t++) {
      const trackColors = CREW_PALETTE[(i + t) % CREW_PALETTE.length];
      const track = await db.musicTrack.create({
        data: {
          albumId: album.id,
          artistId: artist.id,
          title: TRACK_TITLES[(i * 3 + t) % TRACK_TITLES.length] + (t > 0 ? ` ${t + 1}` : ""),
          slug: `track-${i}-${t}-${album.slug}`,
          audioUrl: MUSIC_URLS[(i * 4 + t) % MUSIC_URLS.length],
          duration: rand(120, 300),
          cover: null,
          coverColor1: trackColors[0],
          coverColor2: trackColors[1],
          plays: rand(1000, 5000000),
          genre: a.genre,
          lyrics: null,
          isExplicit: Math.random() < 0.15,
        },
      });
      trackIds.push(track.id);
    }
  }

  // ----- Users -----
  console.log("👤 Seeding users...");
  const users = await Promise.all(userData.map((u) => db.user.create({ data: u })));
  const adminUser = users[0];
  // Link referrals: user2 & user3 referred by admin
  await db.user.update({ where: { id: users[1].id }, data: { referredById: adminUser.id } });
  await db.user.update({ where: { id: users[2].id }, data: { referredById: users[1].id } });

  // ----- Wallets -----
  console.log("💰 Seeding wallets + transactions...");
  const balances = [500000, 120000, 45000, 0, 88000];
  const wallets = await Promise.all(users.map((u, i) =>
    db.wallet.create({ data: { userId: u.id, balance: balances[i] } })
  ));

  // Wallet transactions: 2-3 per wallet
  for (let i = 0; i < wallets.length; i++) {
    const w = wallets[i];
    await db.walletTransaction.create({
      data: {
        walletId: w.id,
        amount: balances[i],
        type: "deposit",
        description: "شارژ اولیه کیف پول",
        referenceId: `INIT${1000 + i}`,
        createdAt: daysAgo(30 + i * 5),
      },
    });
    await db.walletTransaction.create({
      data: {
        walletId: w.id,
        amount: 20000,
        type: "gift",
        description: "کادو ورودی PeepBox",
        referenceId: `GIFT${2000 + i}`,
        createdAt: daysAgo(25),
      },
    });
    if (balances[i] > 50000) {
      await db.walletTransaction.create({
        data: {
          walletId: w.id,
          amount: -49000,
          type: "subscription",
          description: "پرداخت اشتراک از کیف پول",
          referenceId: `SUB${3000 + i}`,
          createdAt: daysAgo(10),
        },
      });
    }
  }

  // ----- Payments -----
  console.log("🧾 Seeding payments...");
  const paymentStatuses = ["paid", "paid", "paid", "pending", "failed", "paid", "paid", "pending"];
  const gateways = ["zarinpal", "idpay", "zarinpal", "wallet", "zarinpal", "idpay", "zarinpal", "wallet"];
  for (let i = 0; i < 8; i++) {
    const u = users[i % users.length];
    const planIdx = (i % (plans.length - 1)) + 1; // skip free
    await db.payment.create({
      data: {
        userId: u.id,
        amount: plans[planIdx].priceMonthly,
        gateway: gateways[i],
        status: paymentStatuses[i],
        type: i % 3 === 0 ? "wallet" : "subscription",
        referenceId: `ZP${10000 + i * 137}`,
        planId: plans[planIdx].id,
        createdAt: daysAgo(i * 3 + 1),
      },
    });
  }

  // ----- Subscriptions -----
  console.log("🎟️  Seeding subscriptions...");
  const userPlans = ["vip", "premium", "standard", "basic", "free"];
  for (let i = 0; i < users.length; i++) {
    const planName = userPlans[i];
    if (planName === "free") continue;
    const plan = planMap.get(planName)!;
    await db.subscription.create({
      data: {
        userId: users[i].id,
        planId: plan.id,
        status: "active",
        startAt: daysAgo(10),
        endAt: daysFromNow(20),
        amountPaid: plan.priceMonthly,
        createdAt: daysAgo(10),
      },
    });
  }

  // ----- Advertisements -----
  console.log("📣 Seeding advertisements...");
  const adTypes = ["banner", "preroll", "popup", "native", "midroll"];
  const adPositions = ["home_top", "home_mid", "sidebar", "player", "between_rows"];
  for (let i = 0; i < 5; i++) {
    await db.advertisement.create({
      data: {
        title: `تبلیغ ${i + 1} — حامی PeepBox`,
        type: adTypes[i],
        position: adPositions[i],
        imageUrl: null,
        videoUrl: null,
        targetUrl: "#",
        startAt: daysAgo(15),
        endAt: daysFromNow(45),
        impressions: rand(50000, 500000),
        clicks: rand(1000, 25000),
        maxImpressions: 1000000,
        isActive: true,
        revenue: rand(500000, 5000000),
      },
    });
  }

  // ----- Coupons -----
  console.log("🏷️  Seeding coupons...");
  await db.coupon.create({
    data: {
      code: "PEEPOFF20",
      percent: 20,
      amount: 0,
      maxUsage: 1000,
      usedCount: 137,
      expiresAt: daysFromNow(120),
      isActive: true,
    },
  });
  await db.coupon.create({
    data: {
      code: "WELCOME50",
      percent: 50,
      amount: 0,
      maxUsage: 1000,
      usedCount: 42,
      expiresAt: daysFromNow(60),
      isActive: true,
    },
  });

  // ----- Notifications -----
  console.log("🔔 Seeding notifications...");
  const notifTemplates = [
    { title: "خوش آمدید به PeepBox!", body: "از تماشای شما سپاسگزاریم. اشتراک ویژه خود را فعال کنید.", type: "system" },
    { title: "محتوای جدید اضافه شد", body: "فیلم «افق نئون» اکنون در دسترس است.", type: "new_content" },
    { title: "تخفیف ویژه", body: "با کد WELCOME50 تا ۵۰٪ تخفیف بگیرید!", type: "discount" },
    { title: "اشتراک شما فعال است", body: "اشتراک شما تا ۲۰ روز آینده معتبر است.", type: "subscription" },
    { title: "پیشنهاد هوش مصنوعی", body: "بر اساس تماشای شما، فیلم‌های مرتبط پیشنهاد می‌شود.", type: "ai" },
  ];
  for (let i = 0; i < users.length; i++) {
    const u = users[i];
    for (let k = 0; k < 3; k++) {
      const n = notifTemplates[(i + k) % notifTemplates.length];
      await db.notification.create({
        data: {
          userId: u.id,
          title: n.title,
          body: n.body,
          type: n.type,
          link: "#",
          read: k < (i % 3),
          createdAt: daysAgo(k * 2 + 1),
        },
      });
    }
  }

  // ----- Devices -----
  console.log("📱 Seeding devices...");
  const deviceData = [
    { name: "Chrome / Windows", type: "chrome", os: "Windows 11" },
    { name: "Android / Chrome", type: "android", os: "Android 14" },
    { name: "Safari / macOS", type: "safari", os: "macOS Sonoma" },
    { name: "PeepBox TV App", type: "tv", os: "Android TV 12" },
    { name: "iPhone / Safari", type: "ios", os: "iOS 17" },
  ];
  for (let i = 0; i < users.length; i++) {
    const u = users[i];
    const devCount = (i === 0) ? 2 : 1;
    for (let k = 0; k < devCount; k++) {
      const d = deviceData[(i + k) % deviceData.length];
      await db.device.create({
        data: {
          userId: u.id,
          name: d.name,
          type: d.type,
          os: d.os,
          userAgent: "Mozilla/5.0 (PeepBox)",
          lastActive: daysAgo(k),
          ip: `192.168.1.${10 + i * 5 + k}`,
          isActive: true,
        },
      });
    }
  }

  // ----- WatchHistory -----
  console.log("⏱️  Seeding watch history...");
  for (let i = 0; i < 5; i++) {
    const u = users[i % users.length];
    const movie = movieIds[i % movieIds.length];
    await db.watchHistory.create({
      data: {
        userId: u.id,
        movieId: movie,
        progress: rand(15, 80),
        position: rand(300, 7200),
        duration: rand(5400, 9000),
        lastWatchedAt: daysAgo(i + 1),
      },
    });
  }
  // Add one episode history
  if (episodeIds.length > 0) {
    await db.watchHistory.create({
      data: {
        userId: users[1].id,
        episodeId: episodeIds[0],
        seriesId: null,
        progress: 45,
        position: 1200,
        duration: 2700,
        lastWatchedAt: daysAgo(2),
      },
    });
  }

  // ----- SearchLog -----
  console.log("🔍 Seeding search logs...");
  const queries = ["اکشن", "فیلم جدید", "neon", "سریال کره‌ای", "موسیقی پاپ", "اطلاعات فیلم", "horror 2023"];
  for (let i = 0; i < queries.length; i++) {
    await db.searchLog.create({
      data: {
        userId: users[i % users.length].id,
        query: queries[i],
        resultsCount: rand(0, 50),
        filters: null,
        createdAt: daysAgo(i),
      },
    });
  }

  // ----- AuditLog -----
  console.log("📜 Seeding audit logs...");
  const auditActions = [
    { action: "login", entity: "User", entityId: null },
    { action: "update_settings", entity: "Setting", entityId: null },
    { action: "create_movie", entity: "Movie", entityId: null },
    { action: "login", entity: "User", entityId: null },
    { action: "delete_user", entity: "User", entityId: null },
  ];
  for (let i = 0; i < auditActions.length; i++) {
    await db.auditLog.create({
      data: {
        userId: users[i % users.length].id,
        action: auditActions[i].action,
        entity: auditActions[i].entity,
        entityId: auditActions[i].entityId,
        meta: JSON.stringify({ source: "seed", idx: i }),
        ip: `192.168.1.${20 + i}`,
        createdAt: daysAgo(i * 2),
      },
    });
  }

  // ----- SecurityLog -----
  console.log("🔒 Seeding security logs...");
  const securityEvents = ["login", "login", "failed_login", "logout", "rate_limit"];
  for (let i = 0; i < securityEvents.length; i++) {
    await db.securityLog.create({
      data: {
        userId: i === 2 ? null : users[i % users.length].id,
        event: securityEvents[i],
        ip: `192.168.1.${30 + i}`,
        userAgent: "Mozilla/5.0 (PeepBox)",
        meta: i === 2 ? JSON.stringify({ reason: "bad_password", attempts: 3 }) : null,
        createdAt: daysAgo(i * 3),
      },
    });
  }

  // ----- ReferralTransaction -----
  console.log("🤝 Seeding referral transactions...");
  await db.referralTransaction.create({
    data: {
      referrerId: adminUser.id,
      referredId: users[1].id,
      amount: 14900,
      commissionPercent: 10,
      type: "subscription",
      status: "paid",
      createdAt: daysAgo(9),
    },
  });
  await db.referralTransaction.create({
    data: {
      referrerId: users[1].id,
      referredId: users[2].id,
      amount: 9900,
      commissionPercent: 10,
      type: "subscription",
      status: "paid",
      createdAt: daysAgo(7),
    },
  });

  // ----- Favorites -----
  console.log("❤️  Seeding favorites...");
  for (let i = 0; i < users.length; i++) {
    const u = users[i];
    // 2 movie favorites
    for (let k = 0; k < 2; k++) {
      await db.favorite.create({
        data: {
          userId: u.id,
          movieId: movieIds[(i * 2 + k) % movieIds.length],
        },
      });
    }
    // 1 channel favorite
    if (i < liveChannelData.length) {
      const chan = await db.liveChannel.findFirst({ where: { slug: liveChannelData[i].slug } });
      if (chan) {
        await db.favorite.create({
          data: { userId: u.id, liveChannelId: chan.id },
        });
      }
    }
    // 1 music favorite
    if (trackIds.length > 0) {
      await db.favorite.create({
        data: { userId: u.id, musicTrackId: trackIds[i % trackIds.length] },
      });
    }
  }

  // ----- Playlists -----
  console.log("📋 Seeding playlists...");
  for (let i = 0; i < users.length - 2; i++) {
    const u = users[i];
    const playlist = await db.playlist.create({
      data: {
        userId: u.id,
        name: i === 0 ? "موسیقی صبح" : "لیست من",
        description: "نخستین پلی‌لیست من در PeepBox",
        isPublic: i === 0,
      },
    });
    for (let k = 0; k < 3; k++) {
      if (trackIds.length === 0) break;
      await db.playlistTrack.create({
        data: {
          playlistId: playlist.id,
          trackId: trackIds[(i * 3 + k) % trackIds.length],
          order: k,
        },
      });
    }
  }

  console.log("✅ Seed complete!");
  console.log(`   Movies: ${movieDefs.length}, Series: ${seriesDefs.length}`);
}

main()
  .then(async () => {
    await db.$disconnect();
    process.exit(0);
  })
  .catch(async (e) => {
    console.error("❌ Seed failed:", e);
    await db.$disconnect();
    process.exit(1);
  });
