#!/usr/bin/env node
/**
 * Seed Demo Data Script
 * Creates 20 realistic bills across 8 categories for demo purposes.
 * Idempotent: can be run multiple times safely.
 */

const path = require('path');

// Use DB_PATH from env or default to db/bills.db
const DB_PATH = process.env.DB_PATH || path.join(__dirname, '..', 'db', 'bills.db');

// Import database helper
const { getDb, ensureUserDefaultCategories } = require('../db/database');

const CATEGORIES = [
  'Utilities',
  'Housing',
  'Insurance',
  'Subscriptions',
  'Transportation',
  'Healthcare',
  'Finance',
  'Entertainment',
];

// Real-world bill names with realistic data
const BILLS = [
  { name: 'Electric Company', category: 'Utilities', amount: 85, dueDay: 15, cycle: 'monthly', autopay: true, interestRate: 0 },
  { name: 'City Water Dept', category: 'Utilities', amount: 45, dueDay: 20, cycle: 'monthly', autopay: true, interestRate: 0 },
  { name: 'Rent/Mortgage', category: 'Housing', amount: 1200, dueDay: 1, cycle: 'monthly', autopay: true, interestRate: 0 },
  { name: 'Car Insurance', category: 'Insurance', amount: 120, dueDay: 5, cycle: 'quarterly', autopay: true, interestRate: 0 },
  { name: 'Netflix', category: 'Subscriptions', amount: 15.99, dueDay: 22, cycle: 'monthly', autopay: true, interestRate: 0 },
  { name: 'Gym Membership', category: 'Subscriptions', amount: 45, dueDay: 10, cycle: 'monthly', autopay: true, interestRate: 0 },
  { name: 'Internet Provider', category: 'Utilities', amount: 70, dueDay: 18, cycle: 'monthly', autopay: true, interestRate: 0 },
  { name: 'Cell Phone', category: 'Utilities', amount: 65, dueDay: 25, cycle: 'monthly', autopay: true, interestRate: 0 },
  { name: 'Health Insurance', category: 'Healthcare', amount: 200, dueDay: 1, cycle: 'quarterly', autopay: true, interestRate: 0 },
  { name: 'Credit Card', category: 'Finance', amount: 150, dueDay: 28, cycle: 'monthly', autopay: true, interestRate: 19.99 },
  { name: 'Student Loan', category: 'Finance', amount: 250, dueDay: 15, cycle: 'monthly', autopay: true, interestRate: 5.5 },
  { name: 'Gas Utility', category: 'Utilities', amount: 35, dueDay: 12, cycle: 'monthly', autopay: true, interestRate: 0 },
  { name: 'Trash Service', category: 'Utilities', amount: 25, dueDay: 28, cycle: 'monthly', autopay: true, interestRate: 0 },
  { name: 'Homeowners Insurance', category: 'Insurance', amount: 300, dueDay: 10, cycle: 'annually', autopay: false, interestRate: 0 },
  { name: 'Car Payment', category: 'Finance', amount: 350, dueDay: 22, cycle: 'monthly', autopay: true, interestRate: 4.5 },
  { name: 'Spotify', category: 'Entertainment', amount: 9.99, dueDay: 14, cycle: 'monthly', autopay: true, interestRate: 0 },
  { name: 'Adobe Creative Cloud', category: 'Subscriptions', amount: 54.99, dueDay: 8, cycle: 'monthly', autopay: true, interestRate: 0 },
  { name: 'Amazon Prime', category: 'Subscriptions', amount: 14.99, dueDay: 1, cycle: 'annually', autopay: true, interestRate: 0 },
  { name: 'Grocery Delivery', category: 'Entertainment', amount: 30, dueDay: 3, cycle: 'irregular', autopay: false, interestRate: 0 },
  { name: 'Dental Insurance', category: 'Healthcare', amount: 40, dueDay: 15, cycle: 'quarterly', autopay: true, interestRate: 0 },
];

/**
 * Get or create a category by name for a user
 */
function getCategoryByName(db, userId, name) {
  let category = db.prepare('SELECT id FROM categories WHERE user_id = ? AND LOWER(name) = LOWER(?)').get(userId, name);
  if (!category) {
    const result = db.prepare('INSERT INTO categories (user_id, name) VALUES (?, ?)').run(userId, name);
    category = { id: result.lastInsertRowid };
  }
  return category;
}

/**
 * Generate realistic random amounts based on type
 */
function getRandomAmount(min, max) {
  const range = max - min;
  const randomValue = Math.random() * range + min;
  return Math.round(randomValue * 100) / 100;
}

/**
 * Main seed function
 * @param {number} [userId] - User ID to seed data for. If not provided, uses the first admin user.
 */
function seedDemoData(userId = null) {
  const db = getDb();

  // Check if data already exists for this user (if userId provided) or globally
  let existingCheck;
  if (userId !== null) {
    existingCheck = db.prepare('SELECT COUNT(*) AS count FROM bills WHERE user_id = ?').get(userId);
  } else {
    existingCheck = db.prepare('SELECT COUNT(*) AS count FROM bills').get();
  }

  if (existingCheck.count > 0) {
    console.log(`⚠️  Found ${existingCheck.count} existing bills. Skipping seed to prevent duplicates.`);
    console.log('   Run again with --force to overwrite.');
    return { billsCreated: 0, categoriesCreated: 0, message: 'Data already exists' };
  }

  // Get user (or admin if userId not provided)
  let targetUser;
  if (userId !== null) {
    targetUser = db.prepare('SELECT id FROM users WHERE id = ?').get(userId);
  } else {
    targetUser = db.prepare('SELECT id FROM users WHERE role = ? ORDER BY id LIMIT 1', 'admin').get();
  }

  if (!targetUser) {
    throw new Error('User not found. Please create a user first.');
  }

  const targetUserId = targetUser.id;
  console.log(`📝 Seeding demo data for user: ${targetUserId}`);

  // Ensure default categories exist for this user
  ensureUserDefaultCategories(targetUserId);

  // Create our 8 demo categories if they don't exist
  const categoriesMap = {};
  let categoriesCreated = 0;

  for (const categoryName of CATEGORIES) {
    const category = getCategoryByName(db, targetUserId, categoryName);
    categoriesMap[categoryName] = category.id;
    // Tag seeded categories
    db.prepare('UPDATE categories SET is_seeded = 1 WHERE id = ?').run(category.id);
    if (category.id > (db.prepare('SELECT id FROM categories WHERE user_id = ? AND name = ?').get(targetUserId, categoryName)?.id || 0)) {
      categoriesCreated++;
    }
  }

  // Create bills
  let billsCreated = 0;
  const insertBill = db.prepare(`
    INSERT INTO bills (user_id, name, category_id, due_day, billing_cycle,
                      expected_amount, autopay_enabled, interest_rate, active, is_seeded)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1, 1)
  `);

  for (const billData of BILLS) {
    const category = categoriesMap[billData.category];

    // Use provided amount or generate random within range
    const amount = billData.amount || getRandomAmount(15, 2500);

    try {
      insertBill.run(
        userId,
        billData.name,
        category,
        billData.dueDay || Math.floor(Math.random() * 28) + 1,
        billData.cycle || 'monthly',
        amount,
        billData.autopay !== undefined ? (billData.autopay ? 1 : 0) : Math.random() > 0.5 ? 1 : 0,
        billData.interestRate || (Math.random() > 0.7 ? Math.round(Math.random() * 15 * 100) / 100 : 0)
      );
      billsCreated++;
    } catch (err) {
      console.error(`Failed to create bill "${billData.name}":`, err.message);
    }
  }

  console.log(`✅ Created ${billsCreated} demo bills`);
  console.log(`✅ Created ${categoriesCreated} demo categories`);

  return { billsCreated, categoriesCreated };
}

// Run seed if called directly
if (require.main === module) {
  try {
    const result = seedDemoData();
    console.log('\nSeed complete:', result);
    process.exit(0);
  } catch (err) {
    console.error('Seed failed:', err.message);
    process.exit(1);
  }
}

module.exports = { seedDemoData };
