import { NextRequest, NextResponse } from "next/server";
import { auth } from "@clerk/nextjs/server";
import { getDatabase } from "@/lib/database";
import log from "@/lib/logger";
import {
  legacyRecommendationSchema,
  recommendationUpdateRequestSchema,
} from "@/lib/validation/schemas";
import {
  validateRequestBody,
  validationErrorResponse,
} from "@/lib/validation/helpers";
import {
  successResponse,
  unauthorizedResponse,
  forbiddenResponse,
  badRequestResponse,
  internalErrorResponse,
} from "@/lib/api/responses";
import { getRecommendationsByGym } from "@/lib/gym-context";
import { ensureUserSynced } from "@/lib/sync-user";

export async function GET(request: NextRequest) {
  try {
    const { userId: currentUserId } = await auth();
    if (!currentUserId) {
      return unauthorizedResponse();
    }

    const db = await getDatabase();
    const currentUser = await ensureUserSynced(currentUserId, db);

    if (!currentUser) {
      return forbiddenResponse("User not found");
    }

    const { searchParams } = new URL(request.url);
    const targetUserId = searchParams.get("userId");

    // If no userId provided, staff gets gym-scoped recommendations
    if (!targetUserId) {
      const isStaff =
        currentUser.role === "admin" ||
        currentUser.role === "superAdmin" ||
        currentUser.role === "trainer";

      if (!isStaff) {
        return badRequestResponse("User ID is required");
      }

      // Get target gym based on role
      const targetGymId =
        currentUser.role === "superAdmin"
          ? (searchParams.get("gymId") ?? undefined)
          : (currentUser.gymId ?? undefined);

      // Get recommendations filtered by gym
      const recommendations = targetGymId
        ? await getRecommendationsByGym(targetGymId)
        : await db.getAllRecommendations();

      return successResponse({ recommendations });
    }

    // Check permissions: Users can view their own, Admins/Trainers can view anyone's in their gym
    const isStaff =
      currentUser.role === "admin" ||
      currentUser.role === "superAdmin" ||
      currentUser.role === "trainer";

    if (currentUserId !== targetUserId) {
      if (!isStaff) {
        return forbiddenResponse();
      }

      // Staff need to verify target user is in same gym
      if (currentUser.role !== "superAdmin") {
        const targetUser = await db.getUserById(targetUserId);
        if (!targetUser || targetUser.gymId !== currentUser.gymId) {
          return forbiddenResponse("Cannot access users from other gyms");
        }
      }
    }

    let recommendations = await db.getRecommendationsByUserId(targetUserId);

    // Non-staff users should only see approved recommendations
    if (!isStaff) {
      recommendations = recommendations.filter(
        (rec: any) => rec.status === "approved",
      );
    }

    return successResponse(recommendations);
  } catch (error) {
    console.error("Error fetching recommendations:", error);
    return internalErrorResponse();
  }
}

export async function POST(request: NextRequest) {
  try {
    const { userId: currentUserId } = await auth();
    if (!currentUserId) {
      return unauthorizedResponse();
    }

    const db = await getDatabase();
    const currentUser = await db.getUserById(currentUserId);
    const isStaff =
      currentUser?.role === "admin" ||
      currentUser?.role === "superAdmin" ||
      currentUser?.role === "trainer";

    if (!isStaff) {
      return forbiddenResponse();
    }

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

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

    const {
      userId,
      fitnessProfileId,
      recommendationText,
      activityPlan,
      dietPlan,
      status,
      type,
      content,
    } = validation.data;

    // Handle AI Plan (Legacy/Specific)
    if (recommendationText && activityPlan && dietPlan && fitnessProfileId) {
      const recommendation = await db.createRecommendation({
        id: crypto.randomUUID(),
        userId,
        fitnessProfileId,
        type: "ai_plan",
        recommendationText: recommendationText,
        activityPlan,
        dietPlan,
        status: status || "pending",
      } as any);
      return successResponse(recommendation);
    }

    // Handle User Goal (Generic)
    if (type && content) {
      const recommendation = await db.createRecommendation({
        id: crypto.randomUUID(),
        userId,
        type,
        recommendationText: content,
        status: status || "pending",
      } as any);
      return successResponse(recommendation);
    }

    return badRequestResponse("Missing required fields");
  } catch (error) {
    log.error("Failed to create recommendation", error);
    return internalErrorResponse();
  }
}

export async function PUT(request: NextRequest) {
  try {
    const { userId: currentUserId } = await auth();
    if (!currentUserId) {
      return unauthorizedResponse();
    }

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

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

    const { id, status, recommendationText, activityPlan, dietPlan, content } =
      validation.data;

    const db = await getDatabase();

    const updated = await db.updateRecommendation(id, {
      ...(status && { status }),
      ...(recommendationText && { recommendationText }),
      ...(content && { recommendationText: content }),
      ...(activityPlan && { activityPlan }),
      ...(dietPlan && { dietPlan }),
    } as any);

    return successResponse(updated);
  } catch (error) {
    log.error("Failed to update recommendation", error);
    return internalErrorResponse();
  }
}
