import { NextRequest } from "next/server";
import { LiveChatStatus, SupportMessageSender } from "@prisma/client";
import { z } from "zod";
import { prisma } from "@/server/db";
import { AppError } from "@/server/errors";
import { fail, ok, parseJson } from "@/server/http";
import { requireUser } from "@/server/security/auth";
import { liveChatConversationInclude } from "@/server/support/includes";
import { getSupportAvailability } from "@/server/support/schedule";
import { serializeLiveChatConversation } from "@/server/support/serializers";

const startChatSchema = z.object({
  message: z.string().trim().max(1000).optional()
});

export const dynamic = "force-dynamic";

export async function GET(request: NextRequest) {
  try {
    const { user } = await requireUser(request);
    const [availability, conversation] = await Promise.all([
      getSupportAvailability(),
      prisma.liveChatConversation.findFirst({
        where: { userId: user.id },
        include: liveChatConversationInclude(),
        orderBy: { lastMessageAt: "desc" }
      })
    ]);

    return ok({ availability, conversation: conversation ? serializeLiveChatConversation(conversation) : null });
  } catch (error) {
    return fail(error);
  }
}

export async function POST(request: NextRequest) {
  try {
    const { user } = await requireUser(request);
    const input = await parseJson(request, startChatSchema);
    const availability = await getSupportAvailability();
    if (!availability.liveChatOnline) {
      throw new AppError("Le livechat est hors ligne. Vous pouvez ouvrir un ticket.", 409, "LIVECHAT_OFFLINE");
    }

    const existingOpenConversation = await prisma.liveChatConversation.findFirst({
      where: { userId: user.id, status: LiveChatStatus.OPEN },
      include: liveChatConversationInclude(),
      orderBy: { lastMessageAt: "desc" }
    });

    if (existingOpenConversation) {
      return ok({ conversation: serializeLiveChatConversation(existingOpenConversation) });
    }

    const conversation = await prisma.liveChatConversation.create({
      data: {
        userId: user.id,
        messages: input.message?.trim()
          ? {
              create: {
                senderUserId: user.id,
                senderRole: SupportMessageSender.USER,
                body: input.message.trim()
              }
            }
          : undefined
      },
      include: liveChatConversationInclude()
    });

    return ok({ conversation: serializeLiveChatConversation(conversation) });
  } catch (error) {
    return fail(error);
  }
}
