import { NextRequest, NextResponse } from "next/server";
import { auth } from "@clerk/nextjs/server";
import Database from "better-sqlite3";
import { randomBytes } from "crypto";
import log from "@/lib/logger";
import { fitnessProfileSchema } from "@/lib/validation/schemas";
import {
  validateRequestBody,
  validationErrorResponse,
} from "@/lib/validation/helpers";

const db = new Database("./data/fitai.db");

// GET - Fetch fitness profile for the authenticated user
export async function GET(request: NextRequest) {
  try {
    const { userId } = await auth();

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

    const profile = db
      .prepare(`SELECT * FROM fitness_profiles WHERE user_id = ?`)
      .get(userId);

    if (profile) {
      const p = profile as any;
      // Parse JSON fields
      try {
        p.fitnessGoals = JSON.parse(p.fitnessGoals || "[]");
      } catch (e) {
        p.fitnessGoals = [];
      }
    }

    return NextResponse.json({ profile: profile || null });
  } catch (error) {
    log.error("Failed to fetch fitness profile", error);
    return NextResponse.json(
      { error: "Failed to fetch fitness profile" },
      { status: 500 },
    );
  }
}

// POST - Create or update fitness profile for the authenticated user
export async function POST(request: NextRequest) {
  try {
    const { userId } = await auth();

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

    // Validate request body
    const validation = await validateRequestBody(request, fitnessProfileSchema);

    if (!validation.success) {
      log.warn("Fitness profile validation failed", {
        errors: validation.errors,
      });
      return validationErrorResponse(validation.errors);
    }

    const {
      height,
      weight,
      age,
      gender,
      fitnessGoals,
      activityLevel,
      medicalConditions,
      allergies,
      injuries,
      preferences,
    } = validation.data;

    // Check if profile exists
    const existingProfile = db
      .prepare(`SELECT user_id FROM fitness_profiles WHERE user_id = ?`)
      .get(userId) as { user_id: string } | undefined;

    const now = new Date().toISOString();
    const fitnessGoalsJson = JSON.stringify(fitnessGoals || []);

    if (existingProfile) {
      // Update existing profile
      db.prepare(
        `UPDATE fitness_profiles
         SET height = ?,
             weight = ?,
             age = ?,
             gender = ?,
             fitness_goals = ?,
             activity_level = ?,
             medical_conditions = ?,
             allergies = ?,
             injuries = ?,
             updated_at = ?
         WHERE user_id = ?`,
      ).run(
        height,
        weight,
        age,
        gender || null,
        fitnessGoalsJson,
        activityLevel || null,
        medicalConditions || null,
        allergies || null,
        injuries || null,
        now,
        userId,
      );

      return NextResponse.json({
        message: "Fitness profile updated successfully",
        userId: userId,
      });
    } else {
      // Create new profile
      const profileId = `fp_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;

      db.prepare(
        `INSERT INTO fitness_profiles
         (id, user_id, height, weight, age, gender, fitness_goals, activity_level,
          medical_conditions, allergies, injuries, created_at, updated_at)
         VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
      ).run(
        profileId,
        userId,
        height,
        weight,
        age,
        gender || null,
        fitnessGoalsJson,
        activityLevel || null,
        medicalConditions || null,
        allergies || null,
        injuries || null,
        now,
        now,
      );

      return NextResponse.json(
        {
          message: "Fitness profile created successfully",
          userId,
        },
        { status: 201 },
      );
    }
  } catch (error) {
    log.error("Failed to save fitness profile", error);
    return NextResponse.json(
      { error: "Failed to save fitness profile" },
      { status: 500 },
    );
  }
}
