import bcrypt from "bcryptjs";
import { drizzle } from "drizzle-orm/postgres-js";
import { sql } from "drizzle-orm";
import postgres from "postgres";
import * as schema from "../src/server/db/schema";
import { createHash, randomUUID } from "crypto";

// Database connection
const connectionString = process.env.DATABASE_URL!;
const connection = postgres(connectionString);
const db = drizzle(connection, { schema });

// --- NAO6 Plugin Definitions ---
import * as fs from "fs";
import * as path from "path";

// Function to load plugin definition (Local first -> Remote fallback)
async function loadNaoPluginDef() {
  const LOCAL_PATH = path.join(
    __dirname,
    "../robot-plugins/plugins/nao6-ros2.json",
  );
  const REMOTE_URL = "https://repo.hristudio.com/plugins/nao6-ros2.json";

  // Always load from local file first (has latest fixes)
  try {
    console.log(`📁 Loading plugin definition from local file...`);
    const rawPlugin = fs.readFileSync(LOCAL_PATH, "utf-8");
    console.log("✅ Successfully loaded local plugin definition.");
    return JSON.parse(rawPlugin);
  } catch (err) {
    console.warn(
      `⚠️ Local file load failed. Falling back to remote: ${REMOTE_URL}`,
    );
    const response = await fetch(REMOTE_URL, {
      signal: AbortSignal.timeout(5000),
    });
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    const data = await response.json();
    console.log("✅ Successfully fetched plugin definition from remote.");
    return data;
  }
}

// Global variable to hold the loaded definition
let NAO_PLUGIN_DEF: any;
let CORE_PLUGIN_DEF: any;
let WOZ_PLUGIN_DEF: any;

function loadSystemPlugin(filename: string) {
  const LOCAL_PATH = path.join(
    __dirname,
    `../src/plugins/definitions/${filename}`,
  );
  try {
    const raw = fs.readFileSync(LOCAL_PATH, "utf-8");
    return JSON.parse(raw);
  } catch (err) {
    console.error(`❌ Failed to load system plugin ${filename}:`, err);
    process.exit(1);
  }
}

async function main() {
  console.log("🌱 Starting realistic seed script...");

  try {
    NAO_PLUGIN_DEF = await loadNaoPluginDef();
    CORE_PLUGIN_DEF = loadSystemPlugin("hristudio-core.json");
    WOZ_PLUGIN_DEF = loadSystemPlugin("hristudio-woz.json");

    // Ensure legacy 'actions' property maps to 'actionDefinitions' if needed, though schema supports both if we map it
    if (NAO_PLUGIN_DEF.actions && !NAO_PLUGIN_DEF.actionDefinitions) {
      NAO_PLUGIN_DEF.actionDefinitions = NAO_PLUGIN_DEF.actions;
    }

    // 1. Clean existing data (Full Wipe)
    console.log("🧹 Cleaning existing data...");
    await db.delete(schema.sessions).where(sql`1=1`);
    await db.delete(schema.accounts).where(sql`1=1`);
    await db.delete(schema.verificationTokens).where(sql`1=1`);
    await db.delete(schema.mediaCaptures).where(sql`1=1`);
    await db.delete(schema.trialEvents).where(sql`1=1`);
    await db.delete(schema.trials).where(sql`1=1`);
    await db.delete(schema.actions).where(sql`1=1`);
    await db.delete(schema.steps).where(sql`1=1`);
    await db.delete(schema.experiments).where(sql`1=1`);
    await db.delete(schema.participants).where(sql`1=1`);
    await db.delete(schema.studyPlugins).where(sql`1=1`);
    await db.delete(schema.studyMembers).where(sql`1=1`);
    await db.delete(schema.formResponses).where(sql`1=1`);
    await db.delete(schema.forms).where(sql`1=1`);
    await db.delete(schema.studies).where(sql`1=1`);
    await db.delete(schema.plugins).where(sql`1=1`);
    await db.delete(schema.pluginRepositories).where(sql`1=1`);
    await db.delete(schema.userSystemRoles).where(sql`1=1`);
    await db.delete(schema.users).where(sql`1=1`);
    await db.delete(schema.robots).where(sql`1=1`);

    // 2. Create Users (Better Auth manages credentials)
    console.log("👥 Creating users...");
    const hashedPassword = await bcrypt.hash("password123", 12);

    const gravatarUrl = (email: string) =>
      `https://www.gravatar.com/avatar/${createHash("md5").update(email.toLowerCase().trim()).digest("hex")}?d=identicon`;

    // Generate text IDs (Better Auth uses text-based IDs)
    const adminId = `admin_${randomUUID()}`;
    const researcherId = `researcher_${randomUUID()}`;

    const [adminUser] = await db
      .insert(schema.users)
      .values({
        id: adminId,
        name: "Sean O'Connor",
        email: "sean@soconnor.dev",
        emailVerified: true,
        image: gravatarUrl("sean@soconnor.dev"),
      })
      .returning();

    const [researcherUser] = await db
      .insert(schema.users)
      .values({
        id: researcherId,
        name: "Dr. Felipe Perrone",
        email: "felipe.perrone@bucknell.edu",
        emailVerified: true,
        image: "https://api.dicebear.com/7.x/avataaars/svg?seed=Felipe",
      })
      .returning();

    if (!adminUser) throw new Error("Failed to create admin user");

    // Create credential accounts for Better Auth (accountId = userId for credential provider)
    await db.insert(schema.accounts).values({
      id: `acc_${randomUUID()}`,
      userId: adminUser.id,
      providerId: "credential",
      accountId: adminUser.id,
      password: hashedPassword,
    });

    if (researcherUser) {
      await db.insert(schema.accounts).values({
        id: `acc_${randomUUID()}`,
        userId: researcherUser.id,
        providerId: "credential",
        accountId: researcherUser.id,
        password: hashedPassword,
      });

      await db
        .insert(schema.userSystemRoles)
        .values({ userId: researcherUser.id, role: "researcher" });
    }

    await db
      .insert(schema.userSystemRoles)
      .values({ userId: adminUser.id, role: "administrator" });

    // 3. Create Robots & Plugins
    console.log("🤖 Creating robots and plugins...");
    const [naoRobot] = await db
      .insert(schema.robots)
      .values({
        name: "NAO6",
        manufacturer: "SoftBank Robotics",
        model: "NAO V6",
        description: "Humanoid robot for social interaction studies.",
        capabilities: ["speech", "vision", "bipedal_walking", "gestures"],
        communicationProtocol: "ros2",
      })
      .returning();

    const [naoRepo] = await db
      .insert(schema.pluginRepositories)
      .values({
        name: "HRIStudio Official Plugins",
        url: "https://github.com/hristudio/plugins",
        description: "Official verified plugins",
        trustLevel: "official",
        isEnabled: true,
        isOfficial: true,
        createdBy: adminUser.id,
      })
      .returning();

    const [naoPlugin] = await db
      .insert(schema.plugins)
      .values({
        robotId: naoRobot!.id,
        identifier: NAO_PLUGIN_DEF.robotId,
        name: NAO_PLUGIN_DEF.name,
        version: NAO_PLUGIN_DEF.version,
        description: NAO_PLUGIN_DEF.description,
        author: "HRIStudio Team",
        repositoryUrl: "https://github.com/hristudio/plugins/tree/main/nao6",
        trustLevel: "verified",
        actionDefinitions: NAO_PLUGIN_DEF.actionDefinitions,
        metadata: NAO_PLUGIN_DEF,
        status: "active",
        createdAt: new Date(),
      })
      .returning();

    // 4. Create Study & Experiment - Comparative WoZ Study
    console.log("📚 Creating 'Comparative WoZ Study'...");
    const [study] = await db
      .insert(schema.studies)
      .values({
        name: "Comparative WoZ Study",
        description:
          "Comparison of HRIStudio vs Choregraphe for The Interactive Storyteller scenario.",
        institution: "Bucknell University",
        irbProtocol: "2024-HRI-COMP",
        status: "active",
        createdBy: adminUser.id,
      })
      .returning();

    await db.insert(schema.studyMembers).values([
      { studyId: study!.id, userId: adminUser.id, role: "owner" },
      { studyId: study!.id, userId: researcherUser!.id, role: "researcher" },
    ]);

    // Create Forms & Templates
    console.log("📝 Creating forms and templates...");
    
    // Templates (system-wide templates)
    const [consentTemplate] = await db
      .insert(schema.forms)
      .values({
        studyId: study!.id,
        type: "consent",
        title: "Standard Informed Consent",
        description: "A comprehensive informed consent document template for HRI research studies.",
        isTemplate: true,
        templateName: "Informed Consent",
        version: 100,
        fields: [
          { id: "1", type: "text", label: "Study Title", required: true },
          { id: "2", type: "text", label: "Principal Investigator Name", required: true },
          { id: "3", type: "text", label: "Institution", required: true },
          { id: "4", type: "textarea", label: "Purpose of the Study", required: true },
          { id: "5", type: "textarea", label: "Procedures", required: true },
          { id: "6", type: "textarea", label: "Risks and Benefits", required: true },
          { id: "7", type: "textarea", label: "Confidentiality", required: true },
          { id: "8", type: "yes_no", label: "I consent to participate in this study", required: true },
          { id: "9", type: "signature", label: "Participant Signature", required: true },
        ],
        settings: {},
        createdBy: adminUser.id,
      })
      .returning();

    const [surveyTemplate] = await db
      .insert(schema.forms)
      .values({
        studyId: study!.id,
        type: "survey",
        title: "Post-Session Questionnaire",
        description: "Standard questionnaire to collect participant feedback after HRI sessions.",
        isTemplate: true,
        templateName: "Post-Session Survey",
        version: 101,
        fields: [
          { id: "1", type: "rating", label: "How engaging was the robot?", required: true, settings: { scale: 5 } },
          { id: "2", type: "rating", label: "How understandable was the robot's speech?", required: true, settings: { scale: 5 } },
          { id: "3", type: "rating", label: "How natural did the interaction feel?", required: true, settings: { scale: 5 } },
          { id: "4", type: "multiple_choice", label: "Did the robot respond appropriately to your actions?", required: true, options: ["Yes, always", "Yes, mostly", "Sometimes", "Rarely", "No"] },
          { id: "5", type: "textarea", label: "What did you like most about the interaction?", required: false },
          { id: "6", type: "textarea", label: "What could be improved?", required: false },
        ],
        settings: {},
        createdBy: adminUser.id,
      })
      .returning();

    const [questionnaireTemplate] = await db
      .insert(schema.forms)
      .values({
        studyId: study!.id,
        type: "questionnaire",
        title: "Demographics Form",
        description: "Basic demographic information collection form.",
        isTemplate: true,
        templateName: "Demographics",
        version: 102,
        fields: [
          { id: "1", type: "text", label: "Age", required: true },
          { id: "2", type: "multiple_choice", label: "Gender", required: true, options: ["Male", "Female", "Non-binary", "Prefer not to say"] },
          { id: "3", type: "multiple_choice", label: "Experience with robots", required: true, options: ["None", "A little", "Moderate", "Extensive"] },
          { id: "4", type: "multiple_choice", label: "Experience with HRI research", required: true, options: ["Never participated", "Participated once", "Participated several times"] },
        ],
        settings: {},
        createdBy: adminUser.id,
      })
      .returning();

    // Study-specific form (not a template)
    const [consentForm] = await db
      .insert(schema.forms)
      .values({
        studyId: study!.id,
        type: "consent",
        title: "Interactive Storyteller Consent",
        description: "Consent form for the Comparative WoZ Study - Interactive Storyteller scenario.",
        version: 1,
        active: true,
        fields: [
          { id: "1", type: "text", label: "Participant Name", required: true },
          { id: "2", type: "date", label: "Date", required: true },
          { id: "3", type: "textarea", label: "I understand that I will interact with a robot storyteller and may be asked to respond to questions.", required: true },
          { id: "4", type: "yes_no", label: "I consent to participate in this study", required: true },
          { id: "5", type: "signature", label: "Signature", required: true },
        ],
        settings: {},
        createdBy: adminUser.id,
      })
      .returning();

    // Insert System Plugins
    const [corePlugin] = await db
      .insert(schema.plugins)
      .values({
        identifier: CORE_PLUGIN_DEF.id,
        name: CORE_PLUGIN_DEF.name,
        version: CORE_PLUGIN_DEF.version,
        description: CORE_PLUGIN_DEF.description,
        author: CORE_PLUGIN_DEF.author,
        trustLevel: "official",
        actionDefinitions: CORE_PLUGIN_DEF.actionDefinitions,
        robotId: null, // System Plugin
        metadata: { ...CORE_PLUGIN_DEF, id: CORE_PLUGIN_DEF.id },
        status: "active",
      })
      .returning();

    const [wozPlugin] = await db
      .insert(schema.plugins)
      .values({
        identifier: WOZ_PLUGIN_DEF.id,
        name: WOZ_PLUGIN_DEF.name,
        version: WOZ_PLUGIN_DEF.version,
        description: WOZ_PLUGIN_DEF.description,
        author: WOZ_PLUGIN_DEF.author,
        trustLevel: "official",
        actionDefinitions: WOZ_PLUGIN_DEF.actionDefinitions,
        robotId: null, // System Plugin
        metadata: { ...WOZ_PLUGIN_DEF, id: WOZ_PLUGIN_DEF.id },
        status: "active",
      })
      .returning();

    await db.insert(schema.studyPlugins).values([
      {
        studyId: study!.id,
        pluginId: naoPlugin!.id,
        configuration: { robotIp: "10.0.0.42" },
        installedBy: adminUser.id,
      },
      {
        studyId: study!.id,
        pluginId: corePlugin!.id,
        configuration: {},
        installedBy: adminUser.id,
      },
      {
        studyId: study!.id,
        pluginId: wozPlugin!.id,
        configuration: {},
        installedBy: adminUser.id,
      },
    ]);

    const [experiment] = await db
      .insert(schema.experiments)
      .values({
        studyId: study!.id,
        name: "The Interactive Storyteller",
        description:
          "A storytelling scenario where the robot tells a story and asks questions to the participant.",
        version: 1,
        status: "ready",
        robotId: naoRobot!.id,
        createdBy: adminUser.id,
        // visualDesign will be auto-generated by designer from DB steps
      })
      .returning();

    // 5. Create Steps & Actions (The Interactive Storyteller Protocol)
    console.log("🎬 Creating experiment steps (Interactive Storyteller)...");

    // Pre-create steps that will be referenced before they're defined
    // --- Step 5: Story Continues (Convergence point for both branches) ---
    const [step5] = await db
      .insert(schema.steps)
      .values({
        experimentId: experiment!.id,
        name: "Story Continues",
        description: "Both branches converge here",
        type: "robot",
        orderIndex: 5,
        required: true,
        durationEstimate: 15,
      })
      .returning();

    // --- Step 6: Conclusion ---
    const [step6] = await db
      .insert(schema.steps)
      .values({
        experimentId: experiment!.id,
        name: "Conclusion",
        description: "End the story and thank participant",
        type: "robot",
        orderIndex: 6,
        required: true,
        durationEstimate: 25,
      })
      .returning();

    // --- Step 1: The Hook ---
    const [step1] = await db
      .insert(schema.steps)
      .values({
        experimentId: experiment!.id,
        name: "The Hook",
        description: "Initial greeting and story introduction",
        type: "robot",
        orderIndex: 0,
        required: true,
        durationEstimate: 25,
      })
      .returning();

    await db.insert(schema.actions).values([
      {
        stepId: step1!.id,
        name: "Say Text",
        type: "nao6-ros2.say_text",
        orderIndex: 0,
        parameters: {
          text: "Hello. I have a story to tell you about a space traveler. Are you ready?",
        },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "interaction",
        retryable: true,
      },
      {
        stepId: step1!.id,
        name: "Move Arm",
        type: "nao6-ros2.move_arm",
        orderIndex: 1,
        // Open hand/welcome position
        parameters: {
          arm: "right",
          shoulder_pitch: 1.0,
          shoulder_roll: -0.2,
          elbow_yaw: 0.5,
          elbow_roll: -0.4,
          speed: 0.4,
        },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "movement",
        retryable: true,
      },
    ]);

    // --- Step 2: The Narrative ---
    const [step2] = await db
      .insert(schema.steps)
      .values({
        experimentId: experiment!.id,
        name: "The Narrative",
        description: "Robot tells the space traveler story with gaze behavior",
        type: "robot",
        orderIndex: 1,
        required: true,
        durationEstimate: 45,
      })
      .returning();

    await db.insert(schema.actions).values([
      {
        stepId: step2!.id,
        name: "Tell Story",
        type: "nao6-ros2.say_text",
        orderIndex: 0,
        parameters: {
          text: "The traveler flew to Mars. He found a red rock that glowed in the dark. He put it in his pocket.",
        },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "interaction",
        retryable: true,
      },
      {
        stepId: step2!.id,
        name: "Turn Head",
        type: "nao6-ros2.turn_head",
        orderIndex: 1,
        parameters: { yaw: 1.5, pitch: 0.0, speed: 0.3 },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "movement",
        retryable: true,
      },
      {
        stepId: step2!.id,
        name: "Turn Head",
        type: "nao6-ros2.turn_head",
        orderIndex: 2,
        parameters: { yaw: 0.0, pitch: -0.1, speed: 0.4 },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "movement",
        retryable: true,
      },
    ]);

    // --- Step 4a: Correct Response Branch ---
    const [step4a] = await db
      .insert(schema.steps)
      .values({
        experimentId: experiment!.id,
        name: "Branch A: Correct Response",
        description: "Response when participant says 'Red'",
        type: "robot",
        orderIndex: 3,
        required: false,
        durationEstimate: 20,
        conditions: {
          nextStepId: step5!.id, // Jump to Story Continues after completing
        },
      })
      .returning();

    // --- Step 4b: Incorrect Response Branch ---
    const [step4b] = await db
      .insert(schema.steps)
      .values({
        experimentId: experiment!.id,
        name: "Branch B: Incorrect Response",
        description: "Response when participant gives wrong answer",
        type: "robot",
        orderIndex: 4,
        required: false,
        durationEstimate: 20,
        conditions: {
          nextStepId: step5!.id, // Jump to Story Continues after completing
        },
      })
      .returning();

    // --- Step 3: Comprehension Check (Wizard Decision Point) ---
    const [step3] = await db
      .insert(schema.steps)
      .values({
        experimentId: experiment!.id,
        name: "Comprehension Check",
        description:
          "Ask participant about rock color and wait for wizard input",
        type: "conditional",
        orderIndex: 2,
        required: true,
        durationEstimate: 30,
        conditions: {
          variable: "last_wizard_response",
          options: [
            {
              label: "Correct Response (Red)",
              value: "Correct",
              nextStepId: step4a!.id,
              variant: "default",
            },
            {
              label: "Incorrect Response",
              value: "Incorrect",
              nextStepId: step4b!.id,
              variant: "destructive",
            },
          ],
        },
      })
      .returning();

    await db.insert(schema.actions).values([
      {
        stepId: step3!.id,
        name: "Say Text",
        type: "nao6-ros2.say_text",
        orderIndex: 0,
        parameters: { text: "What color was the rock the traveler found?" },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "interaction",
        retryable: true,
      },
      {
        stepId: step3!.id,
        name: "Wait for Choice",
        type: "wizard_wait_for_response",
        orderIndex: 1,
        parameters: {
          prompt_text: "Did participant answer 'Red' correctly?",
          options: [
            { label: "Correct", value: "Correct", nextStepId: step4a!.id },
            { label: "Incorrect", value: "Incorrect", nextStepId: step4b!.id },
          ],
        },
        sourceKind: "core",
        pluginId: "hristudio-woz", // Explicit link
        category: "wizard",
      },
      {
        stepId: step3!.id,
        name: "Branch Decision",
        type: "branch",
        orderIndex: 2,
        parameters: {},
        sourceKind: "core",
        pluginId: "hristudio-core", // Explicit link
        category: "control",
      },
    ]);

    await db.insert(schema.actions).values([
      {
        stepId: step4a!.id,
        name: "Say Text with Emotion",
        type: "nao6-ros2.say_with_emotion",
        orderIndex: 0,
        parameters: {
          text: "Yes! It was a glowing red rock.",
          emotion: "happy",
          speed: 1.0,
        },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "interaction",
        retryable: true,
      },
      {
        stepId: step4a!.id,
        name: "Turn Head",
        type: "nao6-ros2.turn_head",
        orderIndex: 1,
        parameters: { yaw: 0.0, pitch: -0.3, speed: 0.5 },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "movement",
        retryable: true,
      },
      {
        stepId: step4a!.id,
        name: "Turn Head",
        type: "nao6-ros2.turn_head",
        orderIndex: 2,
        parameters: { yaw: 0.0, pitch: 0.0, speed: 0.4 },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "movement",
        retryable: true,
      },
    ]);

    await db.insert(schema.actions).values([
      {
        stepId: step4b!.id,
        name: "Correct Participant",
        type: "nao6-ros2.say_text",
        orderIndex: 0,
        parameters: { text: "Actually, it was red." },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "interaction",
        retryable: true,
      },
      {
        stepId: step4b!.id,
        name: "Turn Head",
        type: "nao6-ros2.turn_head",
        orderIndex: 1,
        parameters: { yaw: -0.5, pitch: 0.0, speed: 0.5 },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "movement",
        retryable: true,
      },
      {
        stepId: step4b!.id,
        name: "Turn Head",
        type: "nao6-ros2.turn_head",
        orderIndex: 2,
        parameters: { yaw: 0.5, pitch: 0.0, speed: 0.5 },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "movement",
        retryable: true,
      },
      {
        stepId: step4b!.id,
        name: "Turn Head",
        type: "nao6-ros2.turn_head",
        orderIndex: 3,
        parameters: { yaw: 0.0, pitch: 0.0, speed: 0.4 },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "movement",
        retryable: true,
      },
    ]);

    // --- Step 5 actions: Story Continues ---
    await db.insert(schema.actions).values([
      {
        stepId: step5!.id,
        name: "Excited Continuation",
        type: "nao6-ros2.say_with_emotion",
        orderIndex: 0,
        parameters: {
          text: "And so the adventure continues! The traveler kept the glowing rock as a precious treasure.",
          emotion: "excited",
          speed: 1.1,
        },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "interaction",
        retryable: true,
      },
      {
        stepId: step5!.id,
        name: "Wave Goodbye",
        type: "nao6-ros2.wave_goodbye",
        orderIndex: 1,
        parameters: {
          text: "See you later!",
        },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "interaction",
        retryable: true,
      },
    ]);

    // --- Step 6 actions: Conclusion ---
    await db.insert(schema.actions).values([
      {
        stepId: step6!.id,
        name: "End Story",
        type: "nao6-ros2.say_text",
        orderIndex: 0,
        parameters: { text: "The End. Thank you for listening." },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "interaction",
        retryable: true,
      },
      {
        stepId: step6!.id,
        name: "Bow Gesture",
        type: "nao6-ros2.move_arm",
        orderIndex: 1,
        parameters: {
          arm: "right",
          shoulder_pitch: 1.8,
          shoulder_roll: 0.1,
          elbow_yaw: 0.0,
          elbow_roll: -0.3,
          speed: 0.3,
        },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "movement",
        retryable: true,
      },
    ]);

    // 5b. Create "Control Flow Demo" Experiment
    console.log("🧩 Creating 'Control Flow Demo' experiment...");
    const [controlDemoExp] = await db
      .insert(schema.experiments)
      .values({
        studyId: study!.id,
        name: "Control Flow Demo",
        description:
          "Demonstration of enhanced control flow actions: Parallel, Wait, Loop, Branch.",
        version: 2,
        status: "draft",
        robotId: naoRobot!.id,
        createdBy: adminUser.id,
      })
      .returning();

    // Step 1: Introduction (Parallel)
    const [cdStep1] = await db
      .insert(schema.steps)
      .values({
        experimentId: controlDemoExp!.id,
        name: "1. Introduction (Parallel)",
        description: "Parallel execution demonstration",
        type: "robot",
        orderIndex: 0,
        required: true,
        durationEstimate: 30,
      })
      .returning();

    // Step 5: Conclusion - Defined early for ID reference (Convergence point)
    const [cdStep5] = await db
      .insert(schema.steps)
      .values({
        experimentId: controlDemoExp!.id,
        name: "5. Conclusion",
        description: "Convergence point",
        type: "robot",
        orderIndex: 4,
        required: true,
        durationEstimate: 15,
      })
      .returning();

    // Step 4: Path B (Wait) - Defined early for ID reference
    const [cdStep4] = await db
      .insert(schema.steps)
      .values({
        experimentId: controlDemoExp!.id,
        name: "4. Path B (Wait)",
        description: "Wait action demonstration",
        type: "robot",
        orderIndex: 3,
        required: true,
        durationEstimate: 10,
      })
      .returning();

    // Step 3: Path A (Loop) - Defined early for ID reference
    const [cdStep3] = await db
      .insert(schema.steps)
      .values({
        experimentId: controlDemoExp!.id,
        name: "3. Path A (Loop)",
        description: "Looping demonstration",
        type: "robot",
        orderIndex: 2,
        required: true,
        durationEstimate: 45,
        conditions: { nextStepId: cdStep5!.id },
      })
      .returning();

    // Step 2: Branch Decision
    const [cdStep2] = await db
      .insert(schema.steps)
      .values({
        experimentId: controlDemoExp!.id,
        name: "2. Branch Decision",
        description: "Choose between Loop (3) or Wait (4)",
        type: "conditional",
        orderIndex: 1,
        required: true,
        durationEstimate: 30,
        conditions: {
          variable: "demo_branch_choice",
          options: [
            {
              label: "Go to Loop (Step 3)",
              value: "loop",
              nextStepId: cdStep3!.id,
              variant: "default",
            },
            {
              label: "Go to Wait (Step 4)",
              value: "wait",
              nextStepId: cdStep4!.id,
              variant: "secondary",
            },
          ],
        },
      })
      .returning();

    // --- Step 1 Actions (Parallel) ---
    await db.insert(schema.actions).values({
      stepId: cdStep1!.id,
      name: "Parallel Intro",
      type: "parallel",
      orderIndex: 0,
      parameters: {
        children: [
          {
            id: randomUUID(),
            name: "Say Text",
            type: "nao6-ros2.say_text",
            parameters: { text: "Starting control flow demonstration." },
            pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
            pluginVersion: "2.2.0",
            category: "interaction",
          },
          {
            id: randomUUID(),
            name: "Move Arm",
            type: "nao6-ros2.move_arm",
            parameters: { arm: "right", shoulder_roll: -0.5 },
            pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
            pluginVersion: "2.2.0",
            category: "movement",
          },
        ],
      },
      pluginId: "hristudio-core",
      category: "control",
      sourceKind: "core",
    });

    // --- Step 2 Actions (Branch) ---
    await db.insert(schema.actions).values([
      {
        stepId: cdStep2!.id,
        name: "Say Text",
        type: "nao6-ros2.say_text",
        orderIndex: 0,
        parameters: { text: "Should I loop or wait?" },
        pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
        pluginVersion: "2.2.0",
        category: "interaction",
      },
      {
        stepId: cdStep2!.id,
        name: "Wizard Decision",
        type: "wizard_wait_for_response",
        orderIndex: 1,
        parameters: {
          prompt_text: "Choose the next path:",
          options: [
            { label: "Loop Path", value: "loop", nextStepId: cdStep3!.id },
            { label: "Wait Path", value: "wait", nextStepId: cdStep4!.id },
          ],
        },
        pluginId: "hristudio-woz",
        category: "wizard",
        sourceKind: "core",
      },
      {
        stepId: cdStep2!.id,
        name: "Execute Branch",
        type: "branch",
        orderIndex: 2,
        parameters: {},
        pluginId: "hristudio-core",
        category: "control",
        sourceKind: "core",
      },
    ]);

    // --- Step 3 Actions (Loop) ---
    await db.insert(schema.actions).values({
      stepId: cdStep3!.id,
      name: "Loop 3 Times",
      type: "loop",
      orderIndex: 0,
      parameters: {
        iterations: 3,
        children: [
          {
            id: randomUUID(),
            name: "Say Text",
            type: "nao6-ros2.say_text",
            parameters: { text: "I am looping." },
            pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
            pluginVersion: "2.2.0",
            category: "interaction",
          },
        ],
      },
      pluginId: "hristudio-core",
      category: "control",
      sourceKind: "core",
    });

    // --- Step 4 Actions (Wait) ---
    await db.insert(schema.actions).values({
      stepId: cdStep4!.id,
      name: "Wait 3 Seconds",
      type: "wait",
      orderIndex: 0,
      parameters: { duration: 3 },
      pluginId: "hristudio-core",
      category: "control",
      sourceKind: "core",
    });

    // --- Step 5 Actions (Conclusion) ---
    await db.insert(schema.actions).values({
      stepId: cdStep5!.id,
      name: "Say Text",
      type: "nao6-ros2.say_text",
      orderIndex: 0,
      parameters: { text: "Demonstration complete. Returning to start." },
      pluginId: NAO_PLUGIN_DEF.robotId || "nao6-ros2",
      pluginVersion: "2.2.0",
      category: "interaction",
    });

    // 6. Participants (N=20 for study)
    console.log("👤 Creating 20 participants for N=20 study...");
    const participants = [];
    for (let i = 1; i <= 20; i++) {
      participants.push({
        studyId: study!.id,
        participantCode: `P${100 + i}`,
        name: `Participant ${100 + i}`,
        consentGiven: true,
        consentGivenAt: new Date(),
        notes: i % 2 === 0 ? "Condition: HRIStudio" : "Condition: Choregraphe",
      });
    }
    const insertedParticipants = await db
      .insert(schema.participants)
      .values(participants)
      .returning();

    // 7. Pre-create a pending trial for immediate testing
    console.log("🧪 Creating a pre-seeded pending trial for testing...");
    const p001 = insertedParticipants.find((p) => p.participantCode === "P101");

    const [pendingTrial] = await db
      .insert(schema.trials)
      .values({
        experimentId: experiment!.id,
        participantId: p001?.id,
        status: "scheduled",
        scheduledAt: new Date(),
      })
      .returning();

    console.log(`   Created pending trial: ${pendingTrial?.id}`);

    console.log("\n✅ Database seeded successfully!");
    console.log(`Summary:`);
    console.log(`- 1 Admin User (sean@soconnor.dev)`);
    console.log(`- Study: 'Comparative WoZ Study'`);
    console.log(
      `- Experiment: 'The Interactive Storyteller' (6 steps created)`,
    );
    console.log(`  - Step 1: The Hook (greeting + welcome gesture)`);
    console.log(`  - Step 2: The Narrative (story + gaze sequence)`);
    console.log(`  - Step 3: Comprehension Check (question + wizard wait)`);
    console.log(`  - Step 4a: Branch A - Correct Response (affirmation + nod)`);
    console.log(
      `  - Step 4b: Branch B - Incorrect Response (correction + head shake)`,
    );
    console.log(`  - Step 5: Conclusion (ending + bow)`);
    console.log(`- ${insertedParticipants.length} Participants`);

    // 7. Seed a COMPLETED trial with rich analytics data for testing
    console.log("📊 Seeding completed trial with analytics data...");

    // Pick participant P101
    const p101 = insertedParticipants.find((p) => p.participantCode === "P101");
    if (!p101) throw new Error("P101 not found");

    const startTime = new Date();
    startTime.setMinutes(startTime.getMinutes() - 10); // Started 10 mins ago
    const endTime = new Date(); // Ended just now

    const [analyticsTrial] = await db
      .insert(schema.trials)
      .values({
        experimentId: experiment!.id,
        participantId: p101.id,
        status: "completed",
        startedAt: startTime,
        completedAt: endTime,
      })
      .returning();

    // Create a series of events
    const timelineEvents = [];
    let currentTime = new Date(startTime);

    // Helper to advance time
    const advance = (seconds: number) => {
      currentTime = new Date(currentTime.getTime() + seconds * 1000);
      return currentTime;
    };

    // 1. Trial Started
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "trial_started",
      timestamp: new Date(currentTime),
      data: { experimentId: experiment!.id, participantId: p101.id },
    });

    // 2. Step 1: The Hook
    advance(2);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "step_changed",
      timestamp: new Date(currentTime),
      data: { stepId: step1!.id, stepName: "The Hook" },
    });

    advance(1);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "action_executed",
      timestamp: new Date(currentTime),
      data: { actionName: "Say Text", text: "Hello..." },
    });

    advance(5);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "action_executed",
      timestamp: new Date(currentTime),
      data: { actionName: "Move Arm", arm: "right" },
    });

    // 3. Step 2: The Narrative
    advance(20);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "step_changed",
      timestamp: new Date(currentTime),
      data: { stepId: step2!.id, stepName: "The Narrative" },
    });

    advance(2);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "action_executed",
      timestamp: new Date(currentTime),
      data: { actionName: "Tell Story" },
    });

    // Simulate an intervention/wizard action
    advance(15);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "intervention",
      timestamp: new Date(currentTime),
      data: { type: "pause", reason: "participant_distracted" },
    });

    advance(10); // Paused for 10s
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "intervention",
      timestamp: new Date(currentTime),
      data: { type: "resume" },
    });

    advance(2);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "action_executed",
      timestamp: new Date(currentTime),
      data: { actionName: "Turn Head", yaw: 1.5 },
    });

    // 4. Step 3: Comprehension Check
    advance(30);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "step_changed",
      timestamp: new Date(currentTime),
      data: { stepId: step3!.id, stepName: "Comprehension Check" },
    });

    advance(1);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "action_executed",
      timestamp: new Date(currentTime),
      data: { actionName: "Say Text", text: "What color..." },
    });

    advance(5);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "wizard_action",
      timestamp: new Date(currentTime),
      data: { action: "wait_for_response", prompt: "Did they answer Red?" },
    });

    // Wizard selects "Correct"
    advance(8);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "wizard_response",
      timestamp: new Date(currentTime),
      data: { response: "Correct", variable: "last_wizard_response" },
    });

    // 5. Branch A
    advance(1);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "step_changed",
      timestamp: new Date(currentTime),
      data: { stepId: step4a!.id, stepName: "Branch A: Correct" },
    });

    advance(1);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "action_executed",
      timestamp: new Date(currentTime),
      data: { actionName: "Say Text with Emotion", emotion: "happy" },
    });

    // 6. Conclusion
    advance(15);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "step_changed",
      timestamp: new Date(currentTime),
      data: { stepId: step6!.id, stepName: "Conclusion" },
    });

    advance(2);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "action_executed",
      timestamp: new Date(currentTime),
      data: { actionName: "End Story" },
    });

    // Trial Complete
    advance(5);
    timelineEvents.push({
      trialId: analyticsTrial!.id,
      eventType: "trial_completed",
      timestamp: new Date(currentTime),
      data: {
        durationSeconds: (currentTime.getTime() - startTime.getTime()) / 1000,
      },
    });

    await db.insert(schema.trialEvents).values(timelineEvents);
    console.log(
      "✅ Seeded 1 completed trial with " + timelineEvents.length + " events.",
    );
  } catch (error) {
    console.error("❌ Seeding failed:", error);
    process.exit(1);
  } finally {
    await connection.end();
  }
}

main();
