import { NextRequest, NextResponse } from "next/server";
import { auth } from "~/lib/auth";
import { db } from "~/server/db";
import { studyMembers } from "~/server/db/schema";
import { and, eq } from "drizzle-orm";
import { exec } from "child_process";
import { promisify } from "util";

const execAsync = promisify(exec);

export async function POST(request: NextRequest) {
  try {
    const session = await auth.api.getSession({
      headers: request.headers,
    });

    if (!session?.user) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const body = await request.json();
    const { action, studyId, robotId, parameters } = body;

    const robotIp =
      process.env.NAO_ROBOT_IP || process.env.NAO_IP || "134.82.159.168";
    const password = process.env.NAO_PASSWORD || "robolab";

    switch (action) {
      case "initialize": {
        // Requires study membership
        const membership = await db.query.studyMembers.findFirst({
          where: and(
            eq(studyMembers.studyId, studyId),
            eq(studyMembers.userId, session.user.id),
          ),
        });

        if (!membership || !["owner", "researcher"].includes(membership.role)) {
          return NextResponse.json(
            { error: "Insufficient permissions" },
            { status: 403 },
          );
        }

        console.log(`[Robots API] Initializing robot at ${robotIp}`);

        const disableAlCmd = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "python2 -c \\"import sys; sys.path.append('/opt/aldebaran/lib/python2.7/site-packages'); import naoqi; al = naoqi.ALProxy('ALAutonomousLife', '127.0.0.1', 9559); al.setState('disabled')\\""`;

        const wakeUpCmd = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "python2 -c \\"import sys; sys.path.append('/opt/aldebaran/lib/python2.7/site-packages'); import naoqi; m = naoqi.ALProxy('ALMotion', '127.0.0.1', 9559); m.wakeUp()\\""`;

        await execAsync(disableAlCmd).catch((e) =>
          console.warn("AL disable failed (non-critical/already disabled):", e),
        );

        await execAsync(wakeUpCmd);

        return NextResponse.json({ success: true });
      }

      case "executeSystemAction": {
        // Requires study membership
        const membership = await db.query.studyMembers.findFirst({
          where: and(
            eq(studyMembers.studyId, studyId),
            eq(studyMembers.userId, session.user.id),
          ),
        });

        if (!membership || !["owner", "researcher"].includes(membership.role)) {
          return NextResponse.json(
            { error: "Insufficient permissions" },
            { status: 403 },
          );
        }

        const { id, parameters: actionParams } = parameters ?? {};
        console.log(`[Robots API] Executing system action ${id}`);

        let command = "";

        switch (id) {
          case "say_with_emotion":
          case "say_text_with_emotion": {
            const text = String(actionParams?.text || "Hello");
            const emotion = String(actionParams?.emotion || "happy");
            const tag =
              emotion === "happy"
                ? "^joyful"
                : emotion === "sad"
                  ? "^sad"
                  : emotion === "thinking"
                    ? "^thoughtful"
                    : "^joyful";

            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "python2 -c \\"import sys; sys.path.append('/opt/aldebaran/lib/python2.7/site-packages'); import naoqi; s = naoqi.ALProxy('ALAnimatedSpeech', '127.0.0.1', 9559); s.say('${tag} ${text.replace(/'/g, "\\'")}')\\""`;
            break;
          }

          case "wake_up":
            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "python2 -c \\"import sys; sys.path.append('/opt/aldebaran/lib/python2.7/site-packages'); import naoqi; m = naoqi.ALProxy('ALMotion', '127.0.0.1', 9559); m.wakeUp()\\""`;
            break;

          case "rest":
            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "python2 -c \\"import sys; sys.path.append('/opt/aldebaran/lib/python2.7/site-packages'); import naoqi; m = naoqi.ALProxy('ALMotion', '127.0.0.1', 9559); m.rest()\\""`;
            break;

          case "play_animation_bow":
            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "qicli call ALAnimationPlayer.run 'animations/Stand/Gestures/BowShort_1'"`;
            break;

          case "play_animation_hey":
            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "qicli call ALAnimationPlayer.run 'animations/Stand/Gestures/Hey_1'"`;
            break;

          case "play_animation_show_floor":
            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "qicli call ALAnimationPlayer.run 'animations/Stand/Gestures/ShowFloor_1'"`;
            break;

          case "play_animation_enthusiastic":
            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "qicli call ALAnimationPlayer.run 'animations/Stand/Gestures/Enthusiastic_4'"`;
            break;

          case "play_animation_yes":
            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "qicli call ALAnimationPlayer.run 'animations/Stand/Gestures/Yes_1'"`;
            break;

          case "play_animation_no":
            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "qicli call ALAnimationPlayer.run 'animations/Stand/Gestures/No_3'"`;
            break;

          case "play_animation_idontknow":
            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "qicli call ALAnimationPlayer.run 'animations/Stand/Gestures/IDontKnow_1'"`;
            break;

          case "stand":
            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "qicli call ALRobotPosture.goToPosture Stand 0.5"`;
            break;

          case "stand_init":
            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "qicli call ALRobotPosture.goToPosture StandInit 0.5"`;
            break;

          case "sit":
            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "qicli call ALRobotPosture.goToPosture Sit 0.5"`;
            break;

          case "crouch":
            command = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no "nao@${robotIp}" "qicli call ALRobotPosture.goToPosture Crouch 0.5"`;
            break;

          default:
            return NextResponse.json(
              { error: `System action ${id} not implemented` },
              { status: 400 },
            );
        }

        await execAsync(command);
        return NextResponse.json({ success: true });
      }

      case "executeSSH": {
        // Session auth is sufficient — no studyId needed
        // command may be top-level in body or nested under parameters
        const { command } = parameters ?? body;
        if (!command) {
          return NextResponse.json(
            { error: "Missing command parameter" },
            { status: 400 },
          );
        }

        console.log(`[Robots API] Executing SSH command: ${command}`);

        const sshCmd = `sshpass -p "${password}" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 "nao@${robotIp}" "${command}"`;

        try {
          const { stdout, stderr } = await execAsync(sshCmd);
          if (stderr && !stderr.includes("null") && stderr.trim()) {
            console.warn(`[Robots API] SSH stderr: ${stderr}`);
          }
          console.log(`[Robots API] SSH result: ${stdout}`);
          return NextResponse.json({ success: true, stdout, stderr });
        } catch (error) {
          console.error(`[Robots API] SSH command failed:`, error);
          return NextResponse.json(
            { error: error instanceof Error ? error.message : "SSH command failed" },
            { status: 500 },
          );
        }
      }

      default:
        return NextResponse.json(
          { error: `Unknown action: ${action}` },
          { status: 400 },
        );
    }
  } catch (error) {
    console.error("[Robots API] Error:", error);
    return NextResponse.json(
      {
        error: error instanceof Error ? error.message : "Internal server error",
      },
      { status: 500 },
    );
  }
}
