import "dotenv/config";
import { PrismaClient } from "../app/generated/prisma/client";
import type { Prisma } from "../app/generated/prisma/client";
import type {
  ActivityCategory,
  Vibe,
} from "../app/generated/prisma/enums";
import { PrismaPg } from "@prisma/adapter-pg";
import bcrypt from "bcryptjs";
import { encryptString, hmacHex } from "../lib/crypto";

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

// ============================================================================
// Helpers
// ============================================================================

const utc = (y: number, m0: number, d: number, h = 12, min = 0) =>
  new Date(Date.UTC(y, m0, d, h, min, 0, 0));

const img = (id: string) =>
  `https://images.unsplash.com/photo-${id}?w=1200&q=80&auto=format&fit=crop`;

const SEED_PASSWORD = "password123";

// ============================================================================
// Itineraries — disimpan sebagai const supaya data trip tetap padat.
// Format: header `Hari N — <hari>` lalu bullet `• HH:MM–HH:MM aktivitas`.
// Lokasi, pos, dan spot diambil dari kasus nyata (Papandayan via Cisurupan,
// Ciremai via Apuy, USS Liberty Tulamben, Karimun Jawa hopping, dst).
// ============================================================================

const ITIN_PAPANDAYAN = `Hari 1 — Sabtu
• 05:00–05:30  Meeting & briefing di Alun-alun Garut
• 05:30–07:00  Perjalanan menuju basecamp Cisurupan
• 07:00–08:00  Sarapan + repacking + pemanasan
• 08:00–11:00  Trekking Camp David — Hutan Mati — Pondok Salada
• 11:00–12:30  Setup tenda di Pondok Salada
• 12:30–14:00  ISHOMA + games kenalan grup
• 14:00–17:00  Eksplor Tegal Alun & Hutan Mati (golden hour foto)
• 17:00–19:00  Masak bareng + makan malam
• 19:00–21:00  Api unggun, kopi, sharing rencana summit
• 21:00         Istirahat

Hari 2 — Minggu
• 03:30–04:00  Bangun + sarapan ringan + air panas
• 04:00–05:30  Summit attack ke puncak Papandayan
• 05:30–07:00  Sunrise + foto bareng di puncak
• 07:00–09:00  Turun ke camp + sarapan utama
• 09:00–11:00  Beres-beres tenda + repacking
• 11:00–13:30  Turun ke basecamp Cisurupan
• 13:30–14:30  Bersih-bersih + makan siang
• 14:30–16:30  Perjalanan kembali ke Garut
• 16:30         Sampai Garut, bubar grup`;

const ITIN_CIREMAI = `Hari 1 — Sabtu
• 04:00–04:30  Meeting & briefing di Stasiun Kuningan
• 04:30–06:30  Perjalanan ke basecamp Apuy via Maja & Argapura
• 06:30–07:30  Sarapan + registrasi simaksi + repacking
• 07:30–10:30  Trek Pos 1 (Berod) → Pos 2 (Arban) → Pos 3 (Tegal Masawa)
• 10:30–11:30  ISHOMA di Pos 4 (Tegal Jamuju)
• 11:30–14:30  Lanjut Pos 5 (Sanghyang Rangkah) → Pos 6 (Goa Walet)
• 14:30–16:00  Setup tenda di Pos 6
• 16:00–18:00  Acara bebas + makan sore + persiapan summit
• 18:00–20:00  Briefing summit + early dinner
• 20:00         Istirahat (bangun dini hari)

Hari 2 — Minggu
• 02:00–02:30  Bangun + cemilan + minuman hangat
• 02:30–05:00  Summit attack ke puncak Sunan Cirebon (3.078 mdpl)
• 05:00–06:30  Sunrise di puncak Ciremai
• 06:30–08:30  Turun ke Pos 6 + sarapan
• 08:30–10:30  Beres tenda + repacking
• 10:30–14:00  Turun ke basecamp Apuy (track curam — hati-hati lutut)
• 14:00–15:00  Bersih-bersih + makan siang di basecamp
• 15:00–17:00  Kembali ke Stasiun Kuningan
• 17:00         Bubar grup`;

const ITIN_CAMPING = `Hari 1 — Sabtu
• 13:00–13:30  Meeting di Pertigaan Pasar Lembang
• 13:30–15:00  Perjalanan ke Ranca Upas via Ciwidey
• 15:00–16:00  Check-in + setup tenda dome (sudah disiapkan tim)
• 16:00–17:30  Tour camp area + ketemu rusa-rusa
• 17:30–19:00  Persiapan BBQ + nyalakan api unggun
• 19:00–21:00  Makan malam BBQ
• 21:00–23:00  Live music akustik + games
• 23:00         Istirahat

Hari 2 — Minggu
• 06:00–07:00  Sunrise + foto di hutan pinus
• 07:00–08:30  Sarapan (nasi goreng + roti bakar + kopi)
• 08:30–10:00  Memberi makan rusa + sesi foto
• 10:00–11:00  Beres tenda + bersih-bersih
• 11:00–11:30  Pulang menuju Lembang
• 12:00         Sampai Lembang, bubar grup`;

const ITIN_PAHAWANG = `Hari 1 — Sabtu (one-day trip)
• 07:00–07:30  Meeting di Dermaga Ketapang, Lampung Selatan
• 07:30–08:30  Briefing safety + fitting alat snorkel
• 08:30–09:30  Sailing menuju Pulau Pahawang Kecil
• 09:30–11:30  Snorkeling spot Cukuh Bedil — terumbu warna-warni
• 11:30–12:30  Pindah spot ke Pulau Kelagian Kecil
• 12:30–14:00  Makan siang + istirahat di pasir putih
• 14:00–15:30  Snorkeling Tanjung Putus + sesi foto underwater
• 15:30–16:30  Sailing kembali ke dermaga
• 16:30–17:00  Bersih-bersih + bubar grup`;

const ITIN_DIVING = `Hari 1 — Sabtu
• 06:30–07:00  Meeting di dive shop Tulamben + welcome coffee
• 07:00–08:00  Briefing dive plan + cek sertifikasi + fitting gear
• 08:00–09:00  Surface interval + pengecekan tank/regulator
• 09:00–10:30  Dive #1 — USS Liberty Wreck (5–28m, ~50 menit bottom time)
• 10:30–12:00  Surface interval + brunch + log dive
• 12:00–13:30  Dive #2 — Coral Garden / Drop Off (~50 menit)
• 13:30–15:00  Debrief + makan siang
• 15:00–17:00  Acara bebas (rest atau eksplor desa Tulamben)
• 17:00–19:00  Sunset di pantai Tulamben + dinner
• 19:00         Istirahat di homestay (mandiri)

Hari 2 — Minggu
• 06:00–06:30  Bangun + kopi
• 06:30–07:30  Briefing dive #3 (early morning visibility tinggi)
• 07:30–09:00  Dive #3 — Liberty Wreck pagi
• 09:00–10:30  Surface interval + sarapan + log
• 10:30–12:00  Dive #4 (opsional, fun dive shallow reef)
• 12:00–13:00  Bersih gear + debrief akhir
• 13:00–14:00  Makan siang penutupan
• 14:00         Bubar grup`;

const ITIN_ISLANDHOP = `Hari 1 — Jumat
• 07:00–07:30  Meeting di Pelabuhan Kartini Jepara
• 07:30–13:00  Penyeberangan kapal feri Jepara → Karimun Jawa
• 13:00–14:00  Tiba di Pelabuhan Karimun + transfer homestay
• 14:00–15:00  Check-in homestay + ISHOMA
• 15:00–17:30  Sunset di Bukit Love + foto-foto
• 17:30–19:00  Bersih-bersih + makan malam
• 19:00–21:00  Alun-alun Karimun + jajan kuliner
• 21:00         Istirahat

Hari 2 — Sabtu
• 06:30–07:30  Sarapan + briefing hopping
• 07:30–09:30  Boat ke Pulau Menjangan Kecil — snorkeling spot terumbu
• 09:30–11:30  Pulau Menjangan Besar — interaksi hiu (penangkaran)
• 11:30–13:00  Makan siang BBQ ikan di Pulau Cemara Besar
• 13:00–15:00  Pulau Cemara Kecil + foto pasir putih
• 15:00–17:00  Pulau Cilik — sunset + snorkel terakhir
• 17:00–18:30  Kembali ke homestay + bersih-bersih
• 18:30–20:00  Makan malam seafood
• 20:00         Acara bebas

Hari 3 — Minggu
• 06:00–07:00  Sunrise di Tanjung Gelam
• 07:00–09:00  Sarapan + pack-up
• 09:00–10:00  Belanja oleh-oleh di pelabuhan
• 10:00–16:00  Penyeberangan kapal feri Karimun → Jepara
• 16:00–17:00  Tiba di Pelabuhan Kartini, bubar grup`;

const ITIN_CITYTRIP = `Hari 1 — Sabtu
• 08:00–08:30  Meeting di Stasiun Tugu Yogyakarta
• 08:30–10:00  Sarapan Gudeg Yu Djum + briefing rute
• 10:00–12:00  Kotagede — kerajinan perak + Masjid Mataram
• 12:00–13:30  Makan siang Sate Klathak Pak Pong
• 13:30–16:00  Tamansari — pemandian Sultan + sumur Gumuling
• 16:00–17:30  Coffee break di kedai lokal Prawirotaman
• 17:30–19:30  Sunset di Bukit Bintang (Jl. Imogiri)
• 19:30–21:30  Angkringan Lik Man — kopi joss + nasi kucing
• 21:30         Drop ke penginapan masing-masing

Hari 2 — Minggu
• 06:00–07:00  Pickup dari penginapan
• 07:00–09:30  Perjalanan ke Kalibiru, Kulon Progo
• 09:30–11:30  Kalibiru — spot foto rumah pohon di tebing
• 11:30–13:00  Makan siang pecel di warung lokal
• 13:00–15:00  Pinus Pengger — instalasi seni alam
• 15:00–16:30  Heha Sky View (opsional, cek cuaca)
• 16:30–18:00  Kembali ke kota — drop di Stasiun Tugu / Bandara
• 18:00         Bubar grup`;

const ITIN_CULINARY = `Hari 1 — Sabtu (one-day food tour)
• 09:00–09:30  Meeting di Stasiun Bandung pintu utara + briefing rute
• 09:30–10:15  Stop 1: Surabi Enhaii (sarapan tradisional)
• 10:15–11:00  Stop 2: Lotek Kalipah Apo
• 11:00–11:45  Stop 3: Mie Kocok Mang Dadeng (Kebon Jukut)
• 11:45–12:30  Stop 4: Bakso Akung (cabang Burangrang)
• 12:30–13:30  Istirahat + jalan santai di Cihampelas
• 13:30–14:15  Stop 5: Batagor Kingsley
• 14:15–15:00  Stop 6: Cuanki Serayu
• 15:00–15:45  Stop 7: Es Cendol Elizabeth
• 15:45–16:30  Stop 8: Roti Gempol & Kopi Anjis (penutup)
• 16:30–17:00  Closing + foto bareng di Braga`;

const ITIN_CONCERT = `Hari 1 — Sabtu (showtime)
• 17:00–17:30  Meeting di Plaza GBK, depan loket Cat 1
• 17:30–18:30  Foto bareng pre-show + obrolan singkat
• 18:30–19:00  Masuk venue bareng (kategori tetap masing-masing)
• 19:00–22:30  Konser Coldplay — Music of the Spheres
• 22:30–23:00  Berkumpul lagi di luar gerbang utama GBK
• 23:00–00:30  After-party dinner di Senayan (resto TBA via grup WA)
• 00:30         Bubar`;

const ITIN_WORKSHOP = `Hari 1 — Sabtu
• 04:00–04:30  Meeting di Alun-alun Pangalengan
• 04:30–05:30  Briefing teknis + setup peralatan
• 05:30–07:30  Sunrise shoot di Perkebunan Teh Malabar
• 07:30–09:00  Sarapan + sesi review foto bareng mentor
• 09:00–11:00  Materi indoor: long exposure & filter ND
• 11:00–13:00  ISHOMA + transfer ke Situ Cileunca
• 13:00–16:00  Workshop on-field di Situ Cileunca (panorama, refleksi)
• 16:00–18:00  Golden hour shoot di Bukit Nini
• 18:00–19:30  Makan malam di villa
• 19:30–22:00  Sesi malam — milky way / star trail (cuaca permitting)
• 22:00         Istirahat di villa

Hari 2 — Minggu
• 05:00–07:00  Sunrise shoot di Pangalengan + foto siluet
• 07:00–08:30  Sarapan + diskusi hasil
• 08:30–11:00  Sesi editing Lightroom (laptop pribadi)
• 11:00–12:00  Review akhir + sertifikat
• 12:00–13:00  Makan siang penutupan
• 13:00–15:00  Kembali ke Alun-alun Pangalengan
• 15:00         Bubar grup`;

const ITIN_RETREAT = `Hari 1 — Jumat
• 14:00–15:00  Check-in Villa Sawah Ubud + welcome drink (jamu)
• 15:00–16:00  Tour fasilitas + pembagian welcome kit
• 16:00–17:30  Yin Yoga pembuka — release perjalanan
• 17:30–18:30  Journaling: niat & ekspektasi retreat
• 18:30–20:00  Dinner vegan (set menu)
• 20:00–21:00  Circle pengenalan + meditasi singkat
• 21:00         Lights-out

Hari 2 — Sabtu
• 06:00–07:30  Hatha Yoga matahari terbit
• 07:30–09:00  Sarapan vegan + tea ceremony
• 09:00–10:30  Meditasi guided: body scan
• 10:30–12:00  Pranayama (latihan napas)
• 12:00–13:30  Lunch + acara bebas (sawah walk)
• 13:30–15:00  Sound healing dengan singing bowl
• 15:00–16:30  Workshop: mindful eating + jamu making
• 16:30–18:00  Yin Yoga sore + savasana panjang
• 18:00–19:30  Dinner vegan
• 19:30–21:00  Sharing circle + meditasi malam
• 21:00         Lights-out

Hari 3 — Minggu
• 06:00–07:30  Vinyasa Flow penutupan
• 07:30–09:00  Sarapan + closing journaling
• 09:00–10:30  Closing circle + tukar pesan
• 10:30–11:30  Check-out + pelukan perpisahan
• 11:30–14:00  Acara bebas (rekomendasi spa/cafe sekitar)
• 14:00         Trip resmi ditutup`;

// ============================================================================
// 1. Cleanup — urutan FK aware (Payment → Booking → Review → Image →
//    Participant → Trip → OrgVerification → Profile → Account → User).
//    Seed wajib idempotent supaya `npm run seed` bisa di-run berulang.
// ============================================================================

async function cleanup() {
  await prisma.payment.deleteMany();
  await prisma.booking.deleteMany();
  await prisma.tripReview.deleteMany();
  await prisma.tripImage.deleteMany();
  await prisma.tripParticipant.deleteMany();
  await prisma.trip.deleteMany();
  await prisma.organizerVerification.deleteMany();
  await prisma.userProfile.deleteMany();
  await prisma.account.deleteMany();
  await prisma.user.deleteMany();
}

// ============================================================================
// 2. Users + Profile
// ============================================================================

interface SeedUser {
  key: string;
  name: string;
  email: string;
  isAdmin?: boolean;
  profile?: {
    bio?: string;
    city?: string;
    interests?: string[];
    instagram?: string;
    vibe?: Vibe;
  };
}

const SEED_USERS: SeedUser[] = [
  // Admin
  {
    key: "admin",
    name: "Admin Setrip",
    email: "admin@setrip.id",
    isAdmin: true,
  },
  // Organizers (akan di-link ke OrganizerVerification)
  {
    key: "dede",
    name: "Dede Inoen",
    email: "dede.inoen@setrip.id",
    profile: {
      bio: "Pendaki sejak 2015. Suka trip santai, bawa peserta pulang dengan selamat.",
      city: "Garut",
      interests: ["hiking", "camping", "fotografi"],
      instagram: "dede.inoen",
      vibe: "BALANCED",
    },
  },
  {
    key: "panji",
    name: "Panji Petualang",
    email: "panji@setrip.id",
    profile: {
      bio: "Trip leader 10+ tahun. Spesialis gunung & laut.",
      city: "Kuningan",
      interests: ["hiking", "diving", "snorkeling"],
      instagram: "panji.adv",
      vibe: "HARDCORE",
    },
  },
  {
    key: "fiersa",
    name: "Fiersa Besari",
    email: "fiersa@setrip.id",
    profile: {
      bio: "Buku, kopi, gunung. Kadang ngajak nonton konser bareng.",
      city: "Bandung",
      interests: ["hiking", "kuliner", "musik"],
      instagram: "fiersabesari",
      vibe: "CHILL",
    },
  },
  // Peserta
  {
    key: "budi",
    name: "Budi Santoso",
    email: "budi@gmail.com",
    profile: {
      bio: "Office worker yang lagi cari teman buat jalan akhir pekan.",
      city: "Jakarta",
      interests: ["hiking", "kuliner"],
      vibe: "BALANCED",
    },
  },
  {
    key: "sari",
    name: "Sari Dewi",
    email: "sari@gmail.com",
    profile: {
      bio: "Solo traveler. Suka pantai, ikan, dan tidur siang di hammock.",
      city: "Surabaya",
      interests: ["snorkeling", "yoga", "fotografi"],
      instagram: "saridew_id",
      vibe: "CHILL",
    },
  },
  {
    key: "doni",
    name: "Doni Prasetyo",
    email: "doni@gmail.com",
    profile: {
      bio: "Diver. Cari teman buddy fun-dive sebulan sekali.",
      city: "Denpasar",
      interests: ["diving", "freediving"],
      vibe: "HARDCORE",
    },
  },
  {
    key: "maya",
    name: "Maya Putri",
    email: "maya@gmail.com",
    profile: {
      bio: "Yoga teacher. Lagi belajar lebih hadir di setiap perjalanan.",
      city: "Yogyakarta",
      interests: ["yoga", "retreat", "kuliner"],
      instagram: "maya.putri",
      vibe: "CHILL",
    },
  },
  {
    key: "raka",
    name: "Raka Aditya",
    email: "raka@gmail.com",
    profile: {
      bio: "Anak baru di dunia trip. Energy tinggi, niat banyak.",
      city: "Bandung",
      interests: ["hiking", "konser"],
      vibe: "HARDCORE",
    },
  },
];

type UserMap = Record<string, { id: string; email: string; name: string }>;

async function seedUsers(): Promise<UserMap> {
  const password = await bcrypt.hash(SEED_PASSWORD, 12);
  const acceptedAt = new Date();

  const map: UserMap = {};
  for (const u of SEED_USERS) {
    const created = await prisma.user.create({
      data: {
        name: u.name,
        email: u.email,
        password,
        emailVerified: acceptedAt,
        acceptedTermsAndPrivacy: true,
        acceptedAt,
        profile: u.profile
          ? {
              create: {
                bio: u.profile.bio,
                city: u.profile.city,
                interests: u.profile.interests ?? [],
                instagram: u.profile.instagram,
                vibe: u.profile.vibe,
              },
            }
          : undefined,
      },
    });
    map[u.key] = { id: created.id, email: created.email, name: created.name };
  }
  return map;
}

// ============================================================================
// 3. Organizer Verification — APPROVED, PENDING, REJECTED untuk demo admin queue
// ============================================================================

interface SeedVerification {
  userKey: string;
  fullName: string;
  nik: string;
  birthDate: Date;
  address: string;
  bankName: string;
  bankAccountNumber: string;
  bankAccountName: string;
  status: "APPROVED" | "PENDING" | "REJECTED";
  rejectionReason?: string;
}

const SEED_VERIFICATIONS: SeedVerification[] = [
  {
    userKey: "dede",
    fullName: "Dede Inoen",
    nik: "3201010101010001",
    birthDate: utc(1990, 0, 1, 0, 0),
    address: "Jl. Pendaki No. 1, Garut, Jawa Barat",
    bankName: "BCA",
    bankAccountNumber: "1234567890",
    bankAccountName: "Dede Inoen",
    status: "APPROVED",
  },
  {
    userKey: "panji",
    fullName: "Panji Petualang",
    nik: "3201010101010002",
    birthDate: utc(1985, 5, 15, 0, 0),
    address: "Jl. Adventure No. 7, Kuningan, Jawa Barat",
    bankName: "Mandiri",
    bankAccountNumber: "9876543210",
    bankAccountName: "Panji Petualang",
    status: "APPROVED",
  },
  {
    userKey: "fiersa",
    fullName: "Fiersa Besari",
    nik: "3201010101010003",
    birthDate: utc(1988, 2, 3, 0, 0),
    address: "Jl. Cisitu No. 99, Bandung, Jawa Barat",
    bankName: "BNI",
    bankAccountNumber: "5566778899",
    bankAccountName: "Fiersa Besari",
    status: "APPROVED",
  },
  // Demo admin queue: PENDING + REJECTED
  {
    userKey: "doni",
    fullName: "Doni Prasetyo",
    nik: "5101010202020001",
    birthDate: utc(1992, 8, 10, 0, 0),
    address: "Jl. Diving No. 12, Denpasar, Bali",
    bankName: "BCA",
    bankAccountNumber: "1112223334",
    bankAccountName: "Doni Prasetyo",
    status: "PENDING",
  },
  {
    userKey: "raka",
    fullName: "Raka Aditya",
    nik: "3201010101010099",
    birthDate: utc(2000, 11, 31, 0, 0),
    address: "Alamat tidak jelas",
    bankName: "Bank lain",
    bankAccountNumber: "0001",
    bankAccountName: "RAKA",
    status: "REJECTED",
    rejectionReason: "Foto KTP tidak terbaca, alamat tidak lengkap.",
  },
];

async function seedVerifications(users: UserMap, adminId: string) {
  const now = new Date();
  for (const v of SEED_VERIFICATIONS) {
    const owner = users[v.userKey];
    if (!owner) continue;

    const isApproved = v.status === "APPROVED";
    const isReviewed = v.status !== "PENDING";

    await prisma.organizerVerification.create({
      data: {
        userId: owner.id,
        fullName: v.fullName,
        nikEncrypted: encryptString(v.nik),
        nikHash: hmacHex(v.nik),
        birthDate: v.birthDate,
        address: v.address,
        ktpImageKey: `ktp/seed-${v.userKey}.jpg`,
        livenessKey: `liveness/seed-${v.userKey}.jpg`,
        bankName: v.bankName,
        bankAccountNumber: v.bankAccountNumber,
        bankAccountName: v.bankAccountName,
        status: v.status,
        rejectionReason: v.rejectionReason,
        reviewedAt: isReviewed ? now : null,
        reviewedById: isReviewed ? adminId : null,
        verifiedAt: isApproved ? now : null,
      },
    });
  }
}

// ============================================================================
// 4. Trips — mix masa depan (OPEN) & masa lalu (COMPLETED) + 1 CLOSED.
//    Vibe diisi supaya filter & matching demo-able.
//    Trip masa lalu jadi pondasi review + trust score.
// ============================================================================

interface SeedTripImage {
  url: string;
  caption: string;
}

interface SeedTrip {
  key: string;
  organizerKey: string;
  category: ActivityCategory;
  title: string;
  description: string;
  meetingPoint?: string;
  itinerary?: string;
  whatsIncluded?: string;
  whatsExcluded?: string;
  destination: string;
  location: string;
  date: Date;
  endDate: Date | null;
  maxParticipants: number;
  price: number;
  vibe: Vibe;
  status: "OPEN" | "FULL" | "CLOSED" | "COMPLETED";
  images: SeedTripImage[];
}

// 2026-05-10 = today (per CLAUDE.md). Trip masa lalu < hari ini, masa depan > hari ini.
const SEED_TRIPS: SeedTrip[] = [
  // ============ MASA LALU (sudah selesai — ada review) ============
  {
    key: "past_papandayan",
    organizerKey: "dede",
    category: "HIKING",
    title: "Open Trip Papandayan — Maret 2026",
    description: `Pendakian santai ke Gunung Papandayan, batch Maret. Cocok untuk pemula.`,
    meetingPoint: "Alun-alun Garut, 05:00 WIB",
    itinerary: ITIN_PAPANDAYAN,
    destination: "Gunung Papandayan",
    location: "Garut, Jawa Barat",
    date: utc(2026, 2, 14, 22, 0),
    endDate: utc(2026, 2, 15, 18, 0),
    maxParticipants: 10,
    price: 250000,
    vibe: "BALANCED",
    status: "COMPLETED",
    images: [
      { url: img("1554629947-334ff61d85dc"), caption: "Kawah Papandayan" },
      { url: img("1464822759023-fed622ff2c3b"), caption: "Track menuju puncak" },
    ],
  },
  {
    key: "past_pahawang",
    organizerKey: "panji",
    category: "SNORKELING",
    title: "Snorkeling Pulau Pahawang — Februari 2026",
    description: `Trip snorkeling batch Februari. Cuaca bersahabat, visibility 10m+.`,
    meetingPoint: "Dermaga Ketapang, Lampung Selatan, 07:00 WIB",
    itinerary: ITIN_PAHAWANG,
    destination: "Pulau Pahawang Kecil",
    location: "Lampung Selatan, Lampung",
    date: utc(2026, 1, 21, 0, 0),
    endDate: null,
    maxParticipants: 10,
    price: 380000,
    vibe: "CHILL",
    status: "COMPLETED",
    images: [
      { url: img("1583212292454-1fe6229603b7"), caption: "Snorkeling di Pahawang" },
    ],
  },
  {
    key: "past_culinary",
    organizerKey: "dede",
    category: "CULINARY",
    title: "Kulineran Street Food Bandung — April 2026",
    description: `Food tour batch April. 8 spot legend dilibas dalam satu hari.`,
    meetingPoint: "Stasiun Bandung pintu utara, 09:00 WIB",
    itinerary: ITIN_CULINARY,
    destination: "Street Food Tour Bandung",
    location: "Bandung, Jawa Barat",
    date: utc(2026, 3, 12, 0, 0),
    endDate: null,
    maxParticipants: 8,
    price: 175000,
    vibe: "CHILL",
    status: "COMPLETED",
    images: [
      { url: img("1565299624946-b28f40a0ae38"), caption: "Street food" },
    ],
  },
  {
    key: "past_workshop_cancelled",
    organizerKey: "panji",
    category: "WORKSHOP",
    title: "Workshop Astrofotografi Bromo — Januari 2026 (BATAL)",
    description: `Cuaca tidak mendukung. Trip dibatalkan H-3, peserta refund 100%.`,
    meetingPoint: "-",
    destination: "Astrofotografi Bromo",
    location: "Probolinggo, Jawa Timur",
    date: utc(2026, 0, 18, 22, 0),
    endDate: utc(2026, 0, 19, 12, 0),
    maxParticipants: 6,
    price: 950000,
    vibe: "HARDCORE",
    status: "CLOSED",
    images: [],
  },

  // ============ MASA DEPAN (OPEN — fitur join + bayar bisa di-test) ============
  {
    key: "open_papandayan",
    organizerKey: "dede",
    category: "HIKING",
    title: "Open Trip Papandayan Weekend",
    description: `Pendakian santai ke Gunung Papandayan, cocok untuk pemula!

⚠️ Bawa: Sleeping bag, jaket, headlamp, air 2L`,
    meetingPoint: "Alun-alun Garut, Sabtu 05:00 WIB — detail grup WA.",
    itinerary: ITIN_PAPANDAYAN,
    whatsIncluded: `• Transport PP Garut–basecamp
• Guide lokal
• Tenda tim
• Konsumsi 3x + snack`,
    whatsExcluded: `• Tiket masuk TN
• Sleeping bag pribadi
• Asuransi perjalanan`,
    destination: "Gunung Papandayan",
    location: "Garut, Jawa Barat",
    date: utc(2026, 5, 13, 22, 0),
    endDate: utc(2026, 5, 14, 18, 0),
    maxParticipants: 10,
    price: 250000,
    vibe: "BALANCED",
    status: "OPEN",
    images: [
      { url: img("1554629947-334ff61d85dc"), caption: "Kawah Papandayan" },
      { url: img("1464822759023-fed622ff2c3b"), caption: "Track menuju puncak" },
    ],
  },
  {
    key: "open_ciremai",
    organizerKey: "panji",
    category: "HIKING",
    title: "Pendakian Ciremai via Apuy",
    description: `Trip ke puncak tertinggi Jawa Barat! 🏔️

📍 Meeting Point: Stasiun Kuningan, 04:00 WIB
⚠️ Level: Menengah — perlu stamina baik`,
    meetingPoint: "Stasiun Kuningan, Sabtu 04:00 WIB",
    itinerary: ITIN_CIREMAI,
    destination: "Gunung Ciremai",
    location: "Kuningan, Jawa Barat",
    date: utc(2026, 5, 23, 4, 0),
    endDate: utc(2026, 5, 24, 18, 0),
    maxParticipants: 8,
    price: 350000,
    vibe: "HARDCORE",
    status: "OPEN",
    images: [
      { url: img("1480497490787-505ec076689f"), caption: "Puncak Ciremai 3.078 mdpl" },
      { url: img("1502085671122-2d218cd434e6"), caption: "Sunrise dari puncak" },
    ],
  },
  {
    key: "open_camping",
    organizerKey: "dede",
    category: "CAMPING",
    title: "Camping Santai di Ranca Upas",
    description: `Camping bareng di tengah hutan pinus dengan ditemani rusa-rusa! Cocok buat first-timer.

📍 Meeting Point: Lembang, Sabtu 13:00 WIB
🎒 Fasilitas: Tenda dome, sleeping bag, BBQ, api unggun
🔥 Bonus: Live music akustik malam hari`,
    meetingPoint: "Pertigaan Pasar Lembang, Sabtu 13:00 WIB",
    itinerary: ITIN_CAMPING,
    whatsIncluded: `• Tenda + sleeping bag + matras
• Logistik camp
• Makan malam BBQ + sarapan
• Tiket masuk lokasi`,
    whatsExcluded: `• Transport pribadi
• Snack tambahan`,
    destination: "Ranca Upas",
    location: "Bandung Selatan, Jawa Barat",
    date: utc(2026, 5, 16, 6, 0),
    endDate: utc(2026, 5, 17, 12, 0),
    maxParticipants: 12,
    price: 220000,
    vibe: "CHILL",
    status: "OPEN",
    images: [
      { url: img("1504280390367-361c6d9f38f4"), caption: "Tenda di hutan pinus" },
      { url: img("1517824806704-9040b037703b"), caption: "Sunset di camp" },
    ],
  },
  {
    key: "open_snorkel",
    organizerKey: "panji",
    category: "SNORKELING",
    title: "Snorkeling Pulau Pahawang",
    description: `Air kristal-jernih, ikan warna-warni, dan pasir putih lembut.

🤿 Pemula friendly — guide profesional
📷 Underwater photo session included`,
    meetingPoint: "Dermaga Ketapang, Lampung Selatan, 07:00 WIB",
    itinerary: ITIN_PAHAWANG,
    whatsIncluded: `• Boat PP
• Alat snorkel (masker, fin, life vest)
• Guide & pemandu underwater
• Konsumsi 2x`,
    whatsExcluded: `• Transport ke Lampung
• Penginapan Sabtu malam`,
    destination: "Pulau Pahawang Kecil",
    location: "Lampung Selatan, Lampung",
    date: utc(2026, 5, 30, 0, 0),
    endDate: null,
    maxParticipants: 10,
    price: 380000,
    vibe: "CHILL",
    status: "OPEN",
    images: [
      { url: img("1583212292454-1fe6229603b7"), caption: "Snorkeling di Pahawang" },
      { url: img("1559825481-12a05cc00344"), caption: "Pasir putih Pahawang Kecil" },
    ],
  },
  {
    key: "open_diving",
    organizerKey: "fiersa",
    category: "DIVING",
    title: "Fun Dive Tulamben — USS Liberty Wreck",
    description: `Dive trip ke USS Liberty Wreck.

⚠️ Sertifikasi minimal: Open Water (PADI/SSI)`,
    meetingPoint: "Dive shop Tulamben, 06:30 WITA",
    itinerary: ITIN_DIVING,
    whatsIncluded: `• 2x dive guided
• Full gear rental
• Tank & weight
• Konsumsi siang`,
    whatsExcluded: `• Transport ke Bali
• Penginapan
• Sertifikasi (cek validitas)`,
    destination: "USS Liberty Wreck",
    location: "Tulamben, Karangasem, Bali",
    date: utc(2026, 6, 4, 0, 0),
    endDate: utc(2026, 6, 5, 12, 0),
    maxParticipants: 6,
    price: 1850000,
    vibe: "HARDCORE",
    status: "OPEN",
    images: [
      { url: img("1544551763-46a013bb70d5"), caption: "Wreck dive Tulamben" },
      { url: img("1566024287286-457247b70310"), caption: "Reef Tulamben" },
    ],
  },
  {
    key: "open_islandhop",
    organizerKey: "panji",
    category: "ISLAND_HOPPING",
    title: "Karimun Jawa Island Hopping 3D2N",
    description: `Hopping 5 pulau favorit di Karimun Jawa.

🏝️ Cocok untuk solo traveler & couple`,
    meetingPoint: "Pelabuhan Kartini Jepara, Jumat 07:00 WIB",
    itinerary: ITIN_ISLANDHOP,
    whatsIncluded: `• Tiket kapal feri PP Jepara–Karimun
• Homestay 2 malam (twin sharing)
• Boat hopping 2 hari
• Alat snorkel
• Makan 6x`,
    whatsExcluded: `• Transport ke Jepara
• Tiket pesawat`,
    destination: "Kepulauan Karimun Jawa",
    location: "Jepara, Jawa Tengah",
    date: utc(2026, 6, 12, 0, 0),
    endDate: utc(2026, 6, 14, 18, 0),
    maxParticipants: 12,
    price: 1450000,
    vibe: "BALANCED",
    status: "OPEN",
    images: [
      { url: img("1507525428034-b723cf961d3e"), caption: "Pantai Karimun" },
      { url: img("1519046904884-53103b34b206"), caption: "Boat hopping" },
    ],
  },
  {
    key: "open_citytrip",
    organizerKey: "fiersa",
    category: "CITY_TRIP",
    title: "City Trip Jogja Hidden Gems",
    description: `Bukan Malioboro lagi. Trip jelajah Jogja sisi 'lokal'.

🚐 Mobil grup, bukan tour bus`,
    meetingPoint: "Stasiun Tugu Yogyakarta, Sabtu 08:00 WIB",
    itinerary: ITIN_CITYTRIP,
    whatsIncluded: `• Transport mobil grup 2 hari
• Tour leader lokal
• Makan 3x (kuliner lokal)
• Tiket masuk semua spot`,
    whatsExcluded: `• Transport ke Jogja
• Penginapan (rekomendasi disediakan)`,
    destination: "Yogyakarta",
    location: "Yogyakarta",
    date: utc(2026, 5, 22, 0, 0),
    endDate: utc(2026, 5, 23, 20, 0),
    maxParticipants: 8,
    price: 650000,
    vibe: "BALANCED",
    status: "OPEN",
    images: [
      { url: img("1596402184320-417e7178b2cd"), caption: "Tamansari" },
      { url: img("1583309217394-d191d747bc66"), caption: "Sudut Jogja" },
    ],
  },
  {
    key: "open_culinary",
    organizerKey: "dede",
    category: "CULINARY",
    title: "Kulineran Street Food Bandung",
    description: `Hopping 8 spot kuliner legend Bandung dalam satu hari.

🍜 Cocok buat foodie & first-timer`,
    meetingPoint: "Stasiun Bandung pintu utara, 09:00 WIB",
    itinerary: ITIN_CULINARY,
    whatsIncluded: `• Transport angkot/grup
• Tour leader food explorer
• Sample setiap spot (8 tempat)`,
    whatsExcluded: `• Pembelian extra di luar sample`,
    destination: "Street Food Tour Bandung",
    location: "Bandung, Jawa Barat",
    date: utc(2026, 5, 17, 0, 0),
    endDate: null,
    maxParticipants: 8,
    price: 175000,
    vibe: "CHILL",
    status: "OPEN",
    images: [
      { url: img("1565299624946-b28f40a0ae38"), caption: "Street food" },
    ],
  },
  {
    key: "open_concert",
    organizerKey: "fiersa",
    category: "CONCERT",
    title: "Nonton Coldplay Bareng — Music of the Spheres Jakarta",
    description: `Cari teman buat nonton Coldplay tapi gak mau nonton sendirian? Gabung grup ini.

🎤 Tiket BUKAN termasuk — peserta bawa tiket masing-masing
🤝 Grup hanya untuk koordinasi meet-up & after-party`,
    meetingPoint: "Plaza GBK, depan loket Cat 1, 17:00 WIB",
    itinerary: ITIN_CONCERT,
    whatsIncluded: `• Koordinasi grup
• Foto bareng pre-show
• After-party dinner di Senayan`,
    whatsExcluded: `• Tiket konser (bawa sendiri!)
• Transport ke GBK`,
    destination: "Coldplay — Music of the Spheres",
    location: "Stadion Utama GBK, Jakarta",
    date: utc(2026, 6, 20, 10, 0),
    endDate: null,
    maxParticipants: 6,
    price: 0, // Free trip — booking langsung PAID saat di-confirm
    vibe: "BALANCED",
    status: "OPEN",
    images: [
      { url: img("1470229722913-7c0e2dbbafd3"), caption: "Konser malam" },
    ],
  },
  {
    key: "open_workshop",
    organizerKey: "panji",
    category: "WORKSHOP",
    title: "Workshop Fotografi Lanskap — Pangalengan",
    description: `Belajar fotografi lanskap langsung di lapangan.

📷 Bawa kamera DSLR/mirrorless + tripod
👨‍🏫 Mentor: fotografer pro (10+ tahun pengalaman)`,
    meetingPoint: "Alun-alun Pangalengan, Sabtu 04:00 WIB",
    itinerary: ITIN_WORKSHOP,
    whatsIncluded: `• Materi workshop (briefing + on-field)
• Tour leader & mentor
• Penginapan villa 1 malam
• Konsumsi 3x`,
    whatsExcluded: `• Kamera & tripod (bawa sendiri)
• Transport ke Pangalengan`,
    destination: "Fotografi Lanskap",
    location: "Pangalengan, Bandung Selatan",
    date: utc(2026, 6, 6, 0, 0),
    endDate: utc(2026, 6, 7, 18, 0),
    maxParticipants: 6,
    price: 850000,
    vibe: "BALANCED",
    status: "OPEN",
    images: [
      { url: img("1452587925148-ce544e77e70d"), caption: "Sunrise kebun teh" },
      { url: img("1444080748397-f442aa95c3e5"), caption: "Workshop on-field" },
    ],
  },
  {
    key: "open_retreat",
    organizerKey: "fiersa",
    category: "RETREAT",
    title: "Mindfulness Retreat 3D — Ubud",
    description: `Retreat 3 hari di tengah sawah Ubud.

🧘 Untuk yang lagi burnout & butuh reset
👥 Grup kecil (max 8) — pengalaman akrab`,
    meetingPoint: "Villa Sawah Ubud (alamat dikirim H-3 via WA)",
    itinerary: ITIN_RETREAT,
    whatsIncluded: `• Penginapan villa 2 malam
• Yoga 4 sesi + meditasi 6 sesi
• Sound healing (1 sesi)
• Konsumsi vegan 6x
• Welcome kit (jurnal, herbal tea)`,
    whatsExcluded: `• Transport ke Ubud
• Treatment spa opsional`,
    destination: "Mindfulness Retreat Ubud",
    location: "Ubud, Gianyar, Bali",
    date: utc(2026, 6, 26, 0, 0),
    endDate: utc(2026, 6, 28, 14, 0),
    maxParticipants: 8,
    price: 2400000,
    vibe: "CHILL",
    status: "OPEN",
    images: [
      { url: img("1545389336-cf090694435e"), caption: "Yoga di sawah Ubud" },
      { url: img("1518609878373-06d740f60d8b"), caption: "Villa retreat" },
    ],
  },
];

type TripMap = Record<string, { id: string; price: number; status: string }>;

async function seedTrips(users: UserMap): Promise<TripMap> {
  const map: TripMap = {};
  for (const t of SEED_TRIPS) {
    const organizer = users[t.organizerKey];
    if (!organizer) {
      throw new Error(`Organizer ${t.organizerKey} tidak ditemukan`);
    }

    const created = await prisma.trip.create({
      data: {
        category: t.category,
        title: t.title,
        description: t.description,
        meetingPoint: t.meetingPoint,
        itinerary: t.itinerary,
        whatsIncluded: t.whatsIncluded,
        whatsExcluded: t.whatsExcluded,
        destination: t.destination,
        location: t.location,
        date: t.date,
        endDate: t.endDate,
        maxParticipants: t.maxParticipants,
        price: t.price,
        vibe: t.vibe,
        status: t.status,
        organizerId: organizer.id,
        images: t.images.length
          ? {
              create: t.images.map((im, order) => ({
                url: im.url,
                caption: im.caption,
                order,
              })),
            }
          : undefined,
      },
    });
    map[t.key] = { id: created.id, price: created.price, status: t.status };
  }
  return map;
}

// ============================================================================
// 5. Participants + Booking + Payment
//    Setiap baris = (tripKey, userKey, intent). `intent` mendeskripsikan
//    state akhir yang kita simulasikan, supaya UI menampilkan beragam kondisi.
//
//    Mapping intent → (Participant, Booking, Payment):
//    - "PENDING_REQUEST"  : Participant PENDING,        Booking PENDING,      no Payment
//    - "AWAITING_PAY"     : Participant CONFIRMED,      Booking AWAITING_PAY, no Payment
//    - "MARKED_PAID"      : Participant CONFIRMED,      Booking AWAITING_PAY, Payment AWAITING (peserta klik "sudah transfer")
//    - "PAID"             : Participant CONFIRMED,      Booking PAID,         Payment PAID (organizer sudah konfirmasi)
//    - "FREE_CONFIRMED"   : Participant CONFIRMED,      Booking PAID,         no Payment (trip gratis)
//    - "CANCELLED"        : Participant CANCELLED,      Booking CANCELLED,    no Payment
// ============================================================================

type Intent =
  | "PENDING_REQUEST"
  | "AWAITING_PAY"
  | "MARKED_PAID"
  | "PAID"
  | "FREE_CONFIRMED"
  | "CANCELLED";

interface SeedParticipant {
  tripKey: string;
  userKey: string;
  intent: Intent;
}

const SEED_PARTICIPANTS: SeedParticipant[] = [
  // ---------- TRIP MASA LALU (COMPLETED) — semua PAID, jadi pondasi review ----------
  { tripKey: "past_papandayan", userKey: "budi", intent: "PAID" },
  { tripKey: "past_papandayan", userKey: "sari", intent: "PAID" },
  { tripKey: "past_papandayan", userKey: "doni", intent: "PAID" },
  { tripKey: "past_papandayan", userKey: "maya", intent: "PAID" },

  { tripKey: "past_pahawang", userKey: "budi", intent: "PAID" },
  { tripKey: "past_pahawang", userKey: "maya", intent: "PAID" },
  { tripKey: "past_pahawang", userKey: "raka", intent: "PAID" },

  { tripKey: "past_culinary", userKey: "sari", intent: "PAID" },
  { tripKey: "past_culinary", userKey: "doni", intent: "PAID" },
  { tripKey: "past_culinary", userKey: "raka", intent: "CANCELLED" }, // batal H-1

  // CLOSED trip — peserta yang ke-refund (di-mark CANCELLED)
  { tripKey: "past_workshop_cancelled", userKey: "budi", intent: "CANCELLED" },
  { tripKey: "past_workshop_cancelled", userKey: "doni", intent: "CANCELLED" },

  // ---------- TRIP MASA DEPAN — mix state ----------
  // Papandayan — campur semua state biar dashboard organizer kaya
  { tripKey: "open_papandayan", userKey: "budi", intent: "PAID" },
  { tripKey: "open_papandayan", userKey: "sari", intent: "MARKED_PAID" },
  { tripKey: "open_papandayan", userKey: "doni", intent: "AWAITING_PAY" },
  { tripKey: "open_papandayan", userKey: "raka", intent: "PENDING_REQUEST" },

  // Ciremai — 2 confirmed paid
  { tripKey: "open_ciremai", userKey: "budi", intent: "PAID" },
  { tripKey: "open_ciremai", userKey: "maya", intent: "AWAITING_PAY" },

  // Camping — 5 peserta variasi
  { tripKey: "open_camping", userKey: "budi", intent: "PAID" },
  { tripKey: "open_camping", userKey: "sari", intent: "PAID" },
  { tripKey: "open_camping", userKey: "doni", intent: "MARKED_PAID" },
  { tripKey: "open_camping", userKey: "maya", intent: "AWAITING_PAY" },
  { tripKey: "open_camping", userKey: "raka", intent: "PENDING_REQUEST" },

  // Snorkeling
  { tripKey: "open_snorkel", userKey: "sari", intent: "PAID" },
  { tripKey: "open_snorkel", userKey: "maya", intent: "MARKED_PAID" },
  { tripKey: "open_snorkel", userKey: "raka", intent: "PENDING_REQUEST" },

  // Diving — mahal, sedikit peserta
  { tripKey: "open_diving", userKey: "doni", intent: "AWAITING_PAY" },

  // Island hop
  { tripKey: "open_islandhop", userKey: "budi", intent: "PAID" },
  { tripKey: "open_islandhop", userKey: "sari", intent: "PAID" },
  { tripKey: "open_islandhop", userKey: "maya", intent: "MARKED_PAID" },
  { tripKey: "open_islandhop", userKey: "raka", intent: "PENDING_REQUEST" },

  // City trip
  { tripKey: "open_citytrip", userKey: "budi", intent: "PAID" },
  { tripKey: "open_citytrip", userKey: "maya", intent: "PAID" },
  { tripKey: "open_citytrip", userKey: "sari", intent: "PENDING_REQUEST" },

  // Culinary — penuh
  { tripKey: "open_culinary", userKey: "budi", intent: "PAID" },
  { tripKey: "open_culinary", userKey: "sari", intent: "PAID" },
  { tripKey: "open_culinary", userKey: "doni", intent: "PAID" },
  { tripKey: "open_culinary", userKey: "maya", intent: "PAID" },
  { tripKey: "open_culinary", userKey: "raka", intent: "PAID" },

  // Concert (FREE) — Booking langsung PAID
  { tripKey: "open_concert", userKey: "maya", intent: "FREE_CONFIRMED" },
  { tripKey: "open_concert", userKey: "raka", intent: "FREE_CONFIRMED" },
  { tripKey: "open_concert", userKey: "sari", intent: "PENDING_REQUEST" },

  // Workshop
  { tripKey: "open_workshop", userKey: "doni", intent: "PAID" },
  { tripKey: "open_workshop", userKey: "sari", intent: "AWAITING_PAY" },

  // Retreat — niche
  { tripKey: "open_retreat", userKey: "maya", intent: "PENDING_REQUEST" },
];

interface BookingPlan {
  participantStatus: "PENDING" | "CONFIRMED" | "CANCELLED";
  bookingStatus: "PENDING" | "AWAITING_PAY" | "PAID" | "CANCELLED";
  payment: null | { status: "AWAITING" | "PAID" };
  markedPaidAt: Date | null;
  paymentConfirmedAt: Date | null;
}

function planFromIntent(intent: Intent, now: Date): BookingPlan {
  switch (intent) {
    case "PENDING_REQUEST":
      return {
        participantStatus: "PENDING",
        bookingStatus: "PENDING",
        payment: null,
        markedPaidAt: null,
        paymentConfirmedAt: null,
      };
    case "AWAITING_PAY":
      return {
        participantStatus: "CONFIRMED",
        bookingStatus: "AWAITING_PAY",
        payment: null,
        markedPaidAt: null,
        paymentConfirmedAt: null,
      };
    case "MARKED_PAID":
      return {
        participantStatus: "CONFIRMED",
        bookingStatus: "AWAITING_PAY",
        payment: { status: "AWAITING" },
        markedPaidAt: now,
        paymentConfirmedAt: null,
      };
    case "PAID":
      return {
        participantStatus: "CONFIRMED",
        bookingStatus: "PAID",
        payment: { status: "PAID" },
        markedPaidAt: now,
        paymentConfirmedAt: now,
      };
    case "FREE_CONFIRMED":
      return {
        participantStatus: "CONFIRMED",
        bookingStatus: "PAID",
        payment: null,
        markedPaidAt: null,
        paymentConfirmedAt: null,
      };
    case "CANCELLED":
      return {
        participantStatus: "CANCELLED",
        bookingStatus: "CANCELLED",
        payment: null,
        markedPaidAt: null,
        paymentConfirmedAt: null,
      };
  }
}

async function seedParticipants(trips: TripMap, users: UserMap) {
  const now = new Date();
  for (const sp of SEED_PARTICIPANTS) {
    const trip = trips[sp.tripKey];
    const user = users[sp.userKey];
    if (!trip || !user) continue;

    const plan = planFromIntent(sp.intent, now);

    const participant = await prisma.tripParticipant.create({
      data: {
        tripId: trip.id,
        userId: user.id,
        status: plan.participantStatus,
        markedPaidAt: plan.markedPaidAt,
        paymentConfirmedAt: plan.paymentConfirmedAt,
      },
    });

    const booking = await prisma.booking.create({
      data: {
        tripId: trip.id,
        userId: user.id,
        participantId: participant.id,
        amount: trip.price,
        status: plan.bookingStatus,
      },
    });

    if (plan.payment) {
      const data: Prisma.PaymentUncheckedCreateInput = {
        bookingId: booking.id,
        provider: "MANUAL",
        externalOrderId: `manual-${booking.id}`,
        amount: trip.price,
        status: plan.payment.status,
        method: "manual_transfer",
        paidAt: plan.payment.status === "PAID" ? now : null,
      };
      await prisma.payment.create({ data });
    }
  }
}

// ============================================================================
// 6. Reviews — hanya untuk trip COMPLETED, dari peserta CONFIRMED non-organizer.
// ============================================================================

interface SeedReview {
  tripKey: string;
  userKey: string;
  rating: number;
  comment: string;
}

const SEED_REVIEWS: SeedReview[] = [
  {
    tripKey: "past_papandayan",
    userKey: "budi",
    rating: 5,
    comment: "Trip-nya santai tapi tetep seru. Guide-nya sabar banget sama yang baru pertama mendaki.",
  },
  {
    tripKey: "past_papandayan",
    userKey: "sari",
    rating: 5,
    comment: "Worth it banget! Sunrise di Tegal Alun cakep, makanan juga oke.",
  },
  {
    tripKey: "past_papandayan",
    userKey: "doni",
    rating: 4,
    comment: "Trip aman dan terorganisir. Kurangin lama briefing pagi aja.",
  },
  {
    tripKey: "past_papandayan",
    userKey: "maya",
    rating: 5,
    comment: "Bang Dede bener-bener jaga energi grup. Highly recommended.",
  },
  {
    tripKey: "past_pahawang",
    userKey: "budi",
    rating: 4,
    comment: "Spot snorkeling-nya bagus, ikan rame. Kapal agak lama nunggu di dermaga.",
  },
  {
    tripKey: "past_pahawang",
    userKey: "maya",
    rating: 5,
    comment: "Pertama kali snorkel & gak takut karena guide-nya stand-by. Mantap!",
  },
  {
    tripKey: "past_pahawang",
    userKey: "raka",
    rating: 5,
    comment: "Sunset Pahawang Kecil top. Bakal ikut lagi.",
  },
  {
    tripKey: "past_culinary",
    userKey: "sari",
    rating: 4,
    comment: "8 spot dalam 1 hari, perut sampe penuh. Mie kocoknya juara.",
  },
  {
    tripKey: "past_culinary",
    userKey: "doni",
    rating: 3,
    comment: "Seru tapi rute pagi-siang kepadetan, jadwal molor 1 jam.",
  },
];

async function seedReviews(trips: TripMap, users: UserMap) {
  for (const r of SEED_REVIEWS) {
    const trip = trips[r.tripKey];
    const user = users[r.userKey];
    if (!trip || !user) continue;

    await prisma.tripReview.create({
      data: {
        tripId: trip.id,
        userId: user.id,
        rating: r.rating,
        comment: r.comment,
      },
    });
  }
}

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

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

  console.log("⏳ Cleanup tabel lama...");
  await cleanup();

  console.log("⏳ Seed users + profile...");
  const users = await seedUsers();

  const admin = users["admin"];
  if (!admin) throw new Error("Admin user gagal dibuat");

  console.log("⏳ Seed organizer verifications...");
  await seedVerifications(users, admin.id);

  console.log("⏳ Seed trips...");
  const trips = await seedTrips(users);

  console.log("⏳ Seed participants + bookings + payments...");
  await seedParticipants(trips, users);

  console.log("⏳ Seed reviews...");
  await seedReviews(trips, users);

  console.log(`
✅ Selesai. Ringkasan:
   ${SEED_USERS.length} users (1 admin, 3 organizer, ${SEED_USERS.length - 4} peserta)
   ${SEED_VERIFICATIONS.length} organizer verifications (3 APPROVED, 1 PENDING, 1 REJECTED)
   ${SEED_TRIPS.length} trips (3 COMPLETED + 1 CLOSED + ${SEED_TRIPS.filter((t) => t.status === "OPEN").length} OPEN)
   ${SEED_PARTICIPANTS.length} participants (mix PENDING/CONFIRMED/CANCELLED)
   ${SEED_REVIEWS.length} reviews

🔐 Login info:
   Admin     : admin@setrip.id
   Organizer : dede.inoen@setrip.id, panji@setrip.id, fiersa@setrip.id
   Peserta   : budi/sari/doni/maya/raka @gmail.com
   Password  : ${SEED_PASSWORD}
`);
}

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