/**
 * Demo Data Generator for ParentFlow
 * Generates realistic activity data for demo user's children from birth to present
 */

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

// Child data from database
const ALICE = {
  id: 'chd_xr7ymrde3vf0',
  name: 'Alice',
  birthDate: new Date('2020-07-09'),
  gender: 'female',
  ageMonths: 64, // ~5 years 4 months
};

const ROBERT = {
  id: 'chd_8b58nlkopebg',
  name: 'Robert',
  birthDate: new Date('2025-02-04'),
  gender: 'male',
  ageMonths: 8,
};

const FAMILY_ID = 'fam_vpusjt4fhsxu';

// Helper: Random between min and max
const random = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min;

// Helper: Random choice from array
const choice = <T>(arr: T[]): T => arr[random(0, arr.length - 1)];

// Helper: Add days to date
const addDays = (date: Date, days: number) => {
  const result = new Date(date);
  result.setDate(result.getDate() + days);
  return result;
};

// Helper: Add hours to date
const addHours = (date: Date, hours: number) => {
  const result = new Date(date);
  result.setHours(result.getHours() + hours);
  return result;
};

// Helper: Add minutes to date
const addMinutes = (date: Date, minutes: number) => {
  const result = new Date(date);
  result.setMinutes(result.getMinutes() + minutes);
  return result;
};

// Generate feeding activities
async function generateFeedingActivities(childId: string, birthDate: Date, ageMonths: number) {
  console.log(`Generating feeding activities for ${childId}...`);
  const activities = [];
  const today = new Date();
  let currentDate = new Date(birthDate);

  while (currentDate < today) {
    const currentAgeMonths = Math.floor((currentDate.getTime() - birthDate.getTime()) / (1000 * 60 * 60 * 24 * 30));

    // Feeding frequency changes with age
    let feedingsPerDay = 8; // Newborn
    if (currentAgeMonths >= 3) feedingsPerDay = 6;
    if (currentAgeMonths >= 6) feedingsPerDay = 5;
    if (currentAgeMonths >= 12) feedingsPerDay = 4; // 3 meals + 1 snack
    if (currentAgeMonths >= 24) feedingsPerDay = 4; // 3 meals + 1 snack

    for (let i = 0; i < feedingsPerDay; i++) {
      const hour = currentAgeMonths < 6
        ? random(0, 23) // Newborns eat around the clock
        : [7, 10, 13, 17, 19][i] || random(8, 18); // Older kids have schedule

      const timestamp = new Date(currentDate);
      timestamp.setHours(hour, random(0, 59), 0, 0);

      let type = 'breast';
      let amount = null;
      let duration = null;
      let notes = '';

      if (currentAgeMonths < 6) {
        // 0-6 months: mainly breast/bottle
        type = choice(['breast', 'bottle']);
        if (type === 'breast') {
          duration = random(15, 40); // minutes
        } else {
          amount = random(60, 180); // ml
        }
      } else if (currentAgeMonths < 12) {
        // 6-12 months: introducing solids
        type = choice(['breast', 'bottle', 'solid', 'solid']);
        if (type === 'breast') {
          duration = random(10, 25);
        } else if (type === 'bottle') {
          amount = random(120, 240);
        } else {
          notes = choice(['Puréed vegetables', 'Banana mash', 'Rice cereal', 'Oatmeal', 'Puréed chicken', 'Sweet potato']);
        }
      } else {
        // 12+ months: mostly solids
        type = 'solid';
        const meals = [
          'Scrambled eggs and toast',
          'Oatmeal with berries',
          'Yogurt and fruit',
          'Mac and cheese',
          'Chicken nuggets and veggies',
          'Pasta with tomato sauce',
          'Grilled cheese sandwich',
          'Rice and beans',
          'Fish sticks and peas',
          'Pancakes',
          'Quesadilla',
          'Soup and crackers',
        ];
        notes = choice(meals);
      }

      activities.push({
        id: `act_feed_${childId}_${timestamp.getTime()}`,
        child_id: childId,
        family_id: FAMILY_ID,
        type: 'feeding',
        timestamp,
        data: {
          feedingType: type,
          amount,
          duration,
          side: type === 'breast' ? choice(['left', 'right', 'both']) : null,
          notes,
        },
        created_at: timestamp,
        updated_at: timestamp,
      });
    }

    currentDate = addDays(currentDate, 1);
  }

  return activities;
}

// Generate sleep activities
async function generateSleepActivities(childId: string, birthDate: Date, ageMonths: number) {
  console.log(`Generating sleep activities for ${childId}...`);
  const activities = [];
  const today = new Date();
  let currentDate = new Date(birthDate);

  while (currentDate < today) {
    const currentAgeMonths = Math.floor((currentDate.getTime() - birthDate.getTime()) / (1000 * 60 * 60 * 24 * 30));

    // Sleep patterns change with age
    let napsPerDay = 4; // Newborn
    let nightSleepHours = 8;

    if (currentAgeMonths >= 3) { napsPerDay = 3; nightSleepHours = 10; }
    if (currentAgeMonths >= 6) { napsPerDay = 2; nightSleepHours = 11; }
    if (currentAgeMonths >= 12) { napsPerDay = 1; nightSleepHours = 11; }
    if (currentAgeMonths >= 18) { napsPerDay = 1; nightSleepHours = 11; }
    if (currentAgeMonths >= 36) { napsPerDay = 0; nightSleepHours = 10; }

    // Night sleep
    const bedtime = new Date(currentDate);
    bedtime.setHours(currentAgeMonths < 12 ? random(19, 21) : random(20, 22), random(0, 59), 0, 0);

    const wakeTime = addHours(bedtime, nightSleepHours + random(-1, 1));

    activities.push({
      id: `act_sleep_night_${childId}_${bedtime.getTime()}`,
      child_id: childId,
      family_id: FAMILY_ID,
      type: 'sleep',
      timestamp: bedtime,
      data: {
        startedAt: bedtime.toISOString(),
        endedAt: wakeTime.toISOString(),
        duration: Math.floor((wakeTime.getTime() - bedtime.getTime()) / (1000 * 60)),
        sleepType: 'night',
        quality: choice(['excellent', 'good', 'good', 'fair']),
        notes: '',
      },
      created_at: bedtime,
      updated_at: wakeTime,
    });

    // Naps
    for (let i = 0; i < napsPerDay; i++) {
      const napHour = currentAgeMonths < 6
        ? random(9, 16)
        : [9, 13, 16][i] || 13;

      const napStart = new Date(currentDate);
      napStart.setHours(napHour, random(0, 59), 0, 0);

      const napDuration = currentAgeMonths < 6
        ? random(30, 120) // Newborns: 30min-2h
        : currentAgeMonths < 18
        ? random(60, 120) // Babies: 1-2h
        : random(60, 90); // Toddlers: 1-1.5h

      const napEnd = addMinutes(napStart, napDuration);

      activities.push({
        id: `act_sleep_nap_${childId}_${napStart.getTime()}`,
        child_id: childId,
        family_id: FAMILY_ID,
        type: 'sleep',
        timestamp: napStart,
        data: {
          startedAt: napStart.toISOString(),
          endedAt: napEnd.toISOString(),
          duration: napDuration,
          sleepType: 'nap',
          quality: choice(['excellent', 'good', 'good', 'fair']),
          notes: '',
        },
        created_at: napStart,
        updated_at: napEnd,
      });
    }

    currentDate = addDays(currentDate, 1);
  }

  return activities;
}

// Generate diaper activities
async function generateDiaperActivities(childId: string, birthDate: Date, ageMonths: number) {
  console.log(`Generating diaper activities for ${childId}...`);
  const activities = [];
  const today = new Date();
  let currentDate = new Date(birthDate);

  while (currentDate < today) {
    const currentAgeMonths = Math.floor((currentDate.getTime() - birthDate.getTime()) / (1000 * 60 * 60 * 24 * 30));

    // Stop generating diapers after 30 months (potty trained)
    if (currentAgeMonths >= 30) {
      currentDate = addDays(currentDate, 1);
      continue;
    }

    // Diaper frequency changes with age
    let changesPerDay = 8; // Newborn
    if (currentAgeMonths >= 3) changesPerDay = 6;
    if (currentAgeMonths >= 6) changesPerDay = 5;
    if (currentAgeMonths >= 12) changesPerDay = 4;
    if (currentAgeMonths >= 24) changesPerDay = 3;

    for (let i = 0; i < changesPerDay; i++) {
      const hour = random(6, 20);
      const timestamp = new Date(currentDate);
      timestamp.setHours(hour, random(0, 59), 0, 0);

      const wetOnly = random(1, 10) <= 6; // 60% wet only
      const poopOnly = random(1, 10) <= 1; // 10% poop only
      const both = !wetOnly && !poopOnly; // 30% both

      activities.push({
        id: `act_diaper_${childId}_${timestamp.getTime()}`,
        child_id: childId,
        family_id: FAMILY_ID,
        type: 'diaper',
        timestamp,
        data: {
          isWet: wetOnly || both,
          isPoopy: poopOnly || both,
          rash: random(1, 100) <= 5, // 5% chance of rash
          notes: '',
        },
        created_at: timestamp,
        updated_at: timestamp,
      });
    }

    currentDate = addDays(currentDate, 1);
  }

  return activities;
}

// Generate growth measurements
async function generateGrowthMeasurements(childId: string, birthDate: Date, ageMonths: number, gender: string) {
  console.log(`Generating growth measurements for ${childId}...`);
  const measurements = [];

  // WHO growth standards (approximate)
  const getExpectedWeight = (months: number, gender: string) => {
    // Birth weight ~3.5kg, doubles by 5 months, triples by 12 months
    if (months === 0) return 3.5 + random(-5, 5) / 10;
    if (months <= 6) return 3.5 + (months * 0.7) + random(-3, 3) / 10;
    if (months <= 12) return 7 + (months - 6) * 0.3 + random(-3, 3) / 10;
    if (months <= 24) return 10 + (months - 12) * 0.2 + random(-3, 3) / 10;
    return 12.5 + (months - 24) * 0.15 + random(-5, 5) / 10;
  };

  const getExpectedHeight = (months: number) => {
    // Birth ~50cm, ~75cm at 12 months, ~86cm at 24 months
    if (months === 0) return 50 + random(-2, 2);
    if (months <= 12) return 50 + (months * 2.1) + random(-2, 2);
    if (months <= 24) return 75 + (months - 12) * 0.9 + random(-2, 2);
    return 86 + (months - 24) * 0.4 + random(-2, 2);
  };

  const getExpectedHeadCircumference = (months: number) => {
    // Birth ~35cm, increases rapidly first year
    if (months === 0) return 35 + random(-1, 1);
    if (months <= 12) return 35 + (months * 1.2) + random(-1, 1);
    if (months <= 24) return 47 + (months - 12) * 0.3 + random(-1, 1);
    return 50 + (months - 24) * 0.1 + random(-1, 1);
  };

  // Measurements at birth, 2 weeks, 1 month, then monthly for first year, then every 3 months
  const measurementSchedule = [0, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63];

  for (const month of measurementSchedule) {
    if (month > ageMonths) break;

    const measurementDate = addDays(birthDate, month * 30);

    measurements.push({
      id: `act_growth_${childId}_${measurementDate.getTime()}`,
      child_id: childId,
      family_id: FAMILY_ID,
      type: 'growth',
      timestamp: measurementDate,
      data: {
        weight: getExpectedWeight(month, gender),
        height: getExpectedHeight(month),
        headCircumference: month <= 24 ? getExpectedHeadCircumference(month) : null,
        notes: month === 0 ? 'Birth measurements' : `${month} month checkup`,
      },
      created_at: measurementDate,
      updated_at: measurementDate,
    });
  }

  return measurements;
}

// Generate medicine/vaccination records
async function generateMedicineActivities(childId: string, birthDate: Date, ageMonths: number) {
  console.log(`Generating medicine/vaccination activities for ${childId}...`);
  const activities = [];

  // CDC vaccination schedule
  const vaccinations = [
    { ageMonths: 0, name: 'Hepatitis B (1st dose)', type: 'vaccine' },
    { ageMonths: 1, name: 'Hepatitis B (2nd dose)', type: 'vaccine' },
    { ageMonths: 2, name: 'DTaP, IPV, Hib, PCV13, Rotavirus (1st doses)', type: 'vaccine' },
    { ageMonths: 4, name: 'DTaP, IPV, Hib, PCV13, Rotavirus (2nd doses)', type: 'vaccine' },
    { ageMonths: 6, name: 'DTaP, IPV, Hib, PCV13, Rotavirus (3rd doses)', type: 'vaccine' },
    { ageMonths: 6, name: 'Influenza (annual)', type: 'vaccine' },
    { ageMonths: 12, name: 'MMR, Varicella, Hepatitis A (1st doses)', type: 'vaccine' },
    { ageMonths: 15, name: 'DTaP (4th dose)', type: 'vaccine' },
    { ageMonths: 18, name: 'Hepatitis A (2nd dose)', type: 'vaccine' },
    { ageMonths: 18, name: 'Influenza (annual)', type: 'vaccine' },
    { ageMonths: 30, name: 'Influenza (annual)', type: 'vaccine' },
    { ageMonths: 42, name: 'Influenza (annual)', type: 'vaccine' },
    { ageMonths: 54, name: 'Influenza (annual)', type: 'vaccine' },
  ];

  for (const vacc of vaccinations) {
    if (vacc.ageMonths > ageMonths) continue;

    const vaccDate = addDays(birthDate, vacc.ageMonths * 30);

    activities.push({
      id: `act_medicine_${childId}_${vaccDate.getTime()}`,
      child_id: childId,
      family_id: FAMILY_ID,
      type: 'medicine',
      timestamp: vaccDate,
      data: {
        medicationType: vacc.type,
        name: vacc.name,
        dosage: '',
        notes: 'Well-child visit',
      },
      created_at: vaccDate,
      updated_at: vaccDate,
    });
  }

  // Occasional fever medication (1-2 times per year after 6 months)
  const feverMedicineMonths = [];
  for (let month = 6; month <= ageMonths; month += random(4, 8)) {
    feverMedicineMonths.push(month);
  }

  for (const month of feverMedicineMonths) {
    const medicineDate = addDays(birthDate, month * 30 + random(0, 29));

    activities.push({
      id: `act_medicine_fever_${childId}_${medicineDate.getTime()}`,
      child_id: childId,
      family_id: FAMILY_ID,
      type: 'medicine',
      timestamp: medicineDate,
      data: {
        medicationType: 'medication',
        name: choice(['Infant Tylenol', 'Infant Ibuprofen']),
        dosage: '2.5ml',
        notes: 'Fever reducer',
      },
      created_at: medicineDate,
      updated_at: medicineDate,
    });
  }

  return activities;
}

// Main execution
async function main() {
  try {
    console.log('Starting demo data generation for ParentFlow...\n');

    // Generate data for Alice (5 years old)
    console.log('=== Generating data for Alice (5 years old) ===');
    const aliceFeeding = await generateFeedingActivities(ALICE.id, ALICE.birthDate, ALICE.ageMonths);
    const aliceSleep = await generateSleepActivities(ALICE.id, ALICE.birthDate, ALICE.ageMonths);
    const aliceDiaper = await generateDiaperActivities(ALICE.id, ALICE.birthDate, ALICE.ageMonths);
    const aliceGrowth = await generateGrowthMeasurements(ALICE.id, ALICE.birthDate, ALICE.ageMonths, ALICE.gender);
    const aliceMedicine = await generateMedicineActivities(ALICE.id, ALICE.birthDate, ALICE.ageMonths);

    console.log(`\nAlice activities generated:
  - Feeding: ${aliceFeeding.length}
  - Sleep: ${aliceSleep.length}
  - Diaper: ${aliceDiaper.length}
  - Growth: ${aliceGrowth.length}
  - Medicine: ${aliceMedicine.length}
  - Total: ${aliceFeeding.length + aliceSleep.length + aliceDiaper.length + aliceGrowth.length + aliceMedicine.length}
`);

    // Generate data for Robert (8 months old)
    console.log('\n=== Generating data for Robert (8 months old) ===');
    const robertFeeding = await generateFeedingActivities(ROBERT.id, ROBERT.birthDate, ROBERT.ageMonths);
    const robertSleep = await generateSleepActivities(ROBERT.id, ROBERT.birthDate, ROBERT.ageMonths);
    const robertDiaper = await generateDiaperActivities(ROBERT.id, ROBERT.birthDate, ROBERT.ageMonths);
    const robertGrowth = await generateGrowthMeasurements(ROBERT.id, ROBERT.birthDate, ROBERT.ageMonths, ROBERT.gender);
    const robertMedicine = await generateMedicineActivities(ROBERT.id, ROBERT.birthDate, ROBERT.ageMonths);

    console.log(`\nRobert activities generated:
  - Feeding: ${robertFeeding.length}
  - Sleep: ${robertSleep.length}
  - Diaper: ${robertDiaper.length}
  - Growth: ${robertGrowth.length}
  - Medicine: ${robertMedicine.length}
  - Total: ${robertFeeding.length + robertSleep.length + robertDiaper.length + robertGrowth.length + robertMedicine.length}
`);

    // Combine all activities
    const allActivities = [
      ...aliceFeeding, ...aliceSleep, ...aliceDiaper, ...aliceGrowth, ...aliceMedicine,
      ...robertFeeding, ...robertSleep, ...robertDiaper, ...robertGrowth, ...robertMedicine,
    ];

    console.log(`\n=== Total activities to insert: ${allActivities.length} ===\n`);

    // Save to JSON file for SQL import
    const fs = require('fs');
    fs.writeFileSync(
      '/root/maternal-app/scripts/demo-data.json',
      JSON.stringify(allActivities, null, 2)
    );

    console.log('Demo data saved to /root/maternal-app/scripts/demo-data.json');
    console.log('\nRun the SQL import script to insert this data into the database.');

  } catch (error) {
    console.error('Error generating demo data:', error);
    process.exit(1);
  } finally {
    await prisma.$disconnect();
  }
}

main();
