/**
 * Database Seed Script
 *
 * Seeds the database with initial mock product data for development and testing.
 * Run with: pnpm db:seed
 */

import 'dotenv/config'
import { drizzle } from 'drizzle-orm/postgres-js'
import { and, eq } from 'drizzle-orm'
import postgres from 'postgres'
import * as schema from './schema'
import { products, roles, productRoleVisibility } from './schema'

/**
 * Standard roles for the system
 * MVP: All roles are created, but assignment is manual
 * Phase 2/3: educator and company roles require approval workflow
 */
const standardRoles = [
  {
    code: 'private' as const,
    displayName: 'Privatperson',
    description: 'Für private Besucher und Einzelpersonen',
    requiresApproval: false,
    sortOrder: 1,
    active: true,
  },
  {
    code: 'educator' as const,
    displayName: 'Pädagoge',
    description: 'Für Lehrer, Erzieher und pädagogische Fachkräfte',
    requiresApproval: true,
    sortOrder: 2,
    active: true,
  },
  {
    code: 'company' as const,
    displayName: 'Unternehmen',
    description: 'Für Firmenkunden und B2B-Partner',
    requiresApproval: true,
    sortOrder: 3,
    active: true,
  },
]

/**
 * Sample annual pass products for experimenta
 */
const mockProducts: Array<{
  navProductId: string
  name: string
  description: string
  price: string
  stockQuantity: number
  category: string
  active: boolean
  roles: Array<'private' | 'educator' | 'company'>
}> = [
  {
    navProductId: 'MSPACE-JK-2025',
    name: 'Makerspace Jahreskarte',
    description:
      'Unbegrenzter Zugang zum Makerspace für 365 Tage. Nutze modernste Werkzeuge, 3D-Drucker, Lasercutter und vieles mehr. Perfekt für Maker, Tüftler und kreative Köpfe.',
    price: '30.00',
    stockQuantity: 100,
    category: 'makerspace-annual-pass',
    active: true,
    roles: ['private', 'educator', 'company'],
  },
  {
    navProductId: 'EXPERIMENTA-JK-2025',
    name: 'experimenta Jahreskarte',
    description:
      'Erlebe die Ausstellungswelt der experimenta ein ganzes Jahr lang. Mit freiem Eintritt zu allen Ausstellungen, Science Dome Shows und Sonderausstellungen.',
    price: '49.00',
    stockQuantity: 200,
    category: 'annual-pass',
    active: true,
    roles: ['private', 'educator', 'company'],
  },
  {
    navProductId: 'PAEDAGOGEN-JK-2025',
    name: 'Pädagogen Jahreskarte',
    description:
      'Speziell für Lehrkräfte und Pädagogen. Mit exklusiven Fortbildungsangeboten, didaktischen Materialien und freiem Zugang zu allen Ausstellungen.',
    price: '0.00',
    stockQuantity: 99999,
    category: 'educator-annual-pass',
    active: true,
    roles: ['private', 'educator'],
  },
]

async function seed() {
  // Get database connection from environment
  const connectionString = process.env.DATABASE_URL
  if (!connectionString) {
    throw new Error('DATABASE_URL environment variable is not set')
  }

  console.log('🌱 Starting database seed...')

  // Create database connection with schema
  const client = postgres(connectionString)
  const db = drizzle(client, { schema })

  try {
    // 1. Insert/Update Roles
    console.log(`👥 Inserting ${standardRoles.length} roles...`)
    const insertedRoles = []
    for (const roleData of standardRoles) {
      const [role] = await db
        .insert(roles)
        .values(roleData)
        .onConflictDoUpdate({
          target: roles.code,
          set: {
            displayName: roleData.displayName,
            description: roleData.description,
            requiresApproval: roleData.requiresApproval,
            sortOrder: roleData.sortOrder,
            active: roleData.active,
            updatedAt: new Date(),
          },
        })
        .returning()
      insertedRoles.push(role)
    }

    console.log(`✅ Successfully inserted/updated ${insertedRoles.length} roles:`)
    insertedRoles.forEach((role) => {
      console.log(
        `   - ${role.displayName} (${role.code}) ${role.requiresApproval ? '[requires approval]' : '[auto-approved]'}`
      )
    })

    // 2. Insert/Update Products
    console.log(`\n📦 Inserting ${mockProducts.length} products...`)
    const insertedProducts = []
    for (const productData of mockProducts) {
      const [product] = await db
        .insert(products)
        .values(productData)
        .onConflictDoUpdate({
          target: products.navProductId,
          set: {
            name: productData.name,
            description: productData.description,
            price: productData.price,
            stockQuantity: productData.stockQuantity,
            category: productData.category,
            active: productData.active,
            updatedAt: new Date(),
          },
        })
        .returning()
      insertedProducts.push(product)
    }

    console.log(`✅ Successfully inserted/updated ${insertedProducts.length} products:`)
    insertedProducts.forEach((product) => {
      console.log(`   - ${product.name} (${product.navProductId}) - €${product.price}`)
    })

    // 3. Assign Roles to Products (using roles array from mock data)
    console.log(`\n🔗 Assigning roles to products...`)

    let assignmentCount = 0
    for (let i = 0; i < insertedProducts.length; i++) {
      const product = insertedProducts[i]
      const productData = mockProducts[i]
      const roleCodes = productData.roles || []

      for (const roleCode of roleCodes) {
        // Find role display name for logging
        const role = insertedRoles.find((r) => r.code === roleCode)
        if (!role) {
          console.warn(`   ⚠️  Role '${roleCode}' not found for product ${product.name}`)
          continue
        }

        // Check if assignment already exists
        const existing = await db.query.productRoleVisibility.findFirst({
          where: and(
            eq(productRoleVisibility.productId, product.id),
            eq(productRoleVisibility.roleCode, roleCode)
          ),
        })

        if (!existing) {
          await db.insert(productRoleVisibility).values({
            productId: product.id,
            roleCode, // Direct reference to roles.code (PK)
          })
          assignmentCount++
          console.log(`   - ${product.name} → ${role.displayName}`)
        }
      }
    }

    console.log(`✅ Created ${assignmentCount} product-role assignments`)

    console.log('\n✨ Database seed completed successfully!')
  } catch (error) {
    console.error('❌ Error seeding database:', error)
    throw error
  } finally {
    // Close database connection
    await client.end()
  }
}

// Run seed function
seed()
  .then(() => {
    process.exit(0)
  })
  .catch((error) => {
    console.error('Fatal error:', error)
    process.exit(1)
  })
