/**
 * Review Questions API — flat questions list from the user's general template
 * GET  - List all questions for this user (flat, normalized with id/type/sortOrder)
 * POST - Add a single question to the general template
 */

import { NextRequest, NextResponse } from "next/server";
import { z } from "zod";
import { createId } from "@paralleldrive/cuid2";
import { auth } from "@/lib/auth";
import { getAuthenticatedUser } from "@/lib/utils/auth-helpers.util";
import { getEffectiveOwnerId } from "@/lib/utils/organization-data";
import { reviewQuestionTemplatesAdapter } from "@/lib/adapters/reviews";
import { logger } from "@/lib/logger";
import { getDataSource } from "@/lib/data-source";

const log = logger.scope("ReviewQuestionsAPI");

const GENERAL_INDUSTRY = "general";

const DEFAULT_QUESTIONS = [
  {
    questionEn: "How would you rate your overall experience?",
    questionAr: "كيف تقيّم تجربتك بشكل عام؟",
    type: "rating",
  },
  {
    questionEn: "Was the staff helpful and professional?",
    questionAr: "هل كان الموظفون مفيدين ومحترفين؟",
    type: "text",
  },
  {
    questionEn: "Would you recommend us to others?",
    questionAr: "هل تنصح الآخرين بنا؟",
    type: "yesno",
  },
];

type QuestionRecord = {
  id: string;
  questionEn: string;
  questionAr: string;
  type: string;
  sortOrder: number;
};

type ConvexTemplate = {
  _id: string;
  industry: string;
  questions?: QuestionRecord[];
};

function normalizeQuestions(
  raw: Array<Record<string, unknown>>,
): QuestionRecord[] {
  return raw.map((q, i) => ({
    id: typeof q.id === "string" && q.id ? q.id : createId(),
    questionEn: typeof q.questionEn === "string" ? q.questionEn : "",
    questionAr: typeof q.questionAr === "string" ? q.questionAr : "",
    type: typeof q.type === "string" ? q.type : "text",
    sortOrder: typeof q.sortOrder === "number" ? q.sortOrder : i,
  }));
}

async function getOrCreateGeneralTemplate(userId: string) {
  const existing = await reviewQuestionTemplatesAdapter.findUnique({
    where: { userId_industry: { userId, industry: GENERAL_INDUSTRY } },
  });

  if (existing) {
    const raw = (existing.questions ?? []) as Array<Record<string, unknown>>;
    const normalized = normalizeQuestions(raw);
    // Persist IDs if any were missing
    const needsSave = raw.some((q) => typeof q.id !== "string" || !q.id);
    if (needsSave) {
      await reviewQuestionTemplatesAdapter.update({
        where: { id: existing.id },
        data: { questions: normalized as unknown },
      });
    }
    return { templateId: existing.id, questions: normalized };
  }

  // Create with defaults
  const defaultQs = DEFAULT_QUESTIONS.map((q, i) => ({
    ...q,
    id: createId(),
    sortOrder: i,
  }));
  const created = await reviewQuestionTemplatesAdapter.create({
    data: {
      id: createId(),
      userId,
      industry: GENERAL_INDUSTRY,
      questions: defaultQs as unknown,
      isDefault: true,
    },
  });

  return { templateId: created.id, questions: defaultQs };
}

export async function GET(request: NextRequest) {
  try {
    const user = await getAuthenticatedUser(request, auth);
    if (!user) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    const effectiveUserId = await getEffectiveOwnerId(user.userId);

    if (getDataSource("reviews") === "convex") {
      try {
        const { convexQuery } = await import("@/lib/convex-client");
        const templates = await convexQuery(
          "reviews/queries:getQuestionTemplates",
          {
            userId: effectiveUserId,
          },
        );
        if (templates !== null) {
          // Find the general template's questions
          const generalTemplate = (templates as ConvexTemplate[]).find(
            (t) => t.industry === GENERAL_INDUSTRY,
          );
          const questions: QuestionRecord[] = generalTemplate?.questions ?? [];
          const flat = questions
            .sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0))
            .map((q) => ({ ...q, industry: GENERAL_INDUSTRY }));
          return NextResponse.json({ success: true, questions: flat });
        }
      } catch {
        // Fall through to Prisma
      }
    }

    const { questions } = await getOrCreateGeneralTemplate(effectiveUserId);

    const flat = questions
      .sort((a, b) => a.sortOrder - b.sortOrder)
      .map((q) => ({ ...q, industry: GENERAL_INDUSTRY }));

    return NextResponse.json({ success: true, questions: flat });
  } catch (error) {
    log.error("Failed to list questions", error);
    return NextResponse.json(
      { success: false, error: "Internal server error" },
      { status: 500 },
    );
  }
}

const AddQuestionSchema = z.object({
  questionEn: z.string().min(1).max(500),
  questionAr: z.string().min(0).max(500).default(""),
  type: z.enum(["rating", "text", "yesno"]).default("text"),
  sortOrder: z.number().int().optional(),
});

export async function POST(request: NextRequest) {
  try {
    const user = await getAuthenticatedUser(request, auth);
    if (!user) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    const effectiveUserId = await getEffectiveOwnerId(user.userId);
    const body = await request.json();
    const parsed = AddQuestionSchema.safeParse(body);

    if (!parsed.success) {
      return NextResponse.json(
        { success: false, error: parsed.error.flatten() },
        { status: 400 },
      );
    }

    if (getDataSource("reviews") === "convex") {
      try {
        const { convexQuery, convexMutation } =
          await import("@/lib/convex-client");

        // Get existing template to append the new question
        const templates = await convexQuery(
          "reviews/queries:getQuestionTemplates",
          {
            userId: effectiveUserId,
          },
        );
        const generalTemplate = templates
          ? (templates as ConvexTemplate[]).find(
              (t) => t.industry === GENERAL_INDUSTRY,
            )
          : null;

        const existingQuestions: QuestionRecord[] =
          generalTemplate?.questions ?? [];
        const newQuestion: QuestionRecord = {
          id: createId(),
          questionEn: parsed.data.questionEn,
          questionAr: parsed.data.questionAr,
          type: parsed.data.type,
          sortOrder: parsed.data.sortOrder ?? existingQuestions.length,
        };

        const updatedQuestions = [...existingQuestions, newQuestion].sort(
          (a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0),
        );

        if (generalTemplate) {
          // Update existing template
          await convexMutation("reviews/mutations:updateQuestionTemplate", {
            userId: effectiveUserId,
            templateId: generalTemplate._id,
            questions: updatedQuestions,
          });
        } else {
          // Create new general template
          await convexMutation("reviews/mutations:createQuestionTemplate", {
            userId: effectiveUserId,
            industry: GENERAL_INDUSTRY,
            questions: updatedQuestions,
            isDefault: true,
          });
        }

        return NextResponse.json(
          {
            success: true,
            question: { ...newQuestion, industry: GENERAL_INDUSTRY },
          },
          { status: 201 },
        );
      } catch {
        // Fall through to Prisma
      }
    }

    const { templateId, questions } =
      await getOrCreateGeneralTemplate(effectiveUserId);

    const newQuestion: QuestionRecord = {
      id: createId(),
      questionEn: parsed.data.questionEn,
      questionAr: parsed.data.questionAr,
      type: parsed.data.type,
      sortOrder: parsed.data.sortOrder ?? questions.length,
    };

    const updated = [...questions, newQuestion].sort(
      (a, b) => a.sortOrder - b.sortOrder,
    );

    await reviewQuestionTemplatesAdapter.update({
      where: { id: templateId },
      data: { questions: updated as unknown },
    });

    return NextResponse.json(
      {
        success: true,
        question: { ...newQuestion, industry: GENERAL_INDUSTRY },
      },
      { status: 201 },
    );
  } catch (error) {
    log.error("Failed to add question", error);
    return NextResponse.json(
      { success: false, error: "Internal server error" },
      { status: 500 },
    );
  }
}
