/**
 * API de Avaliação de Ticket
 * GET - Registra avaliação via link do e-mail
 * POST - Registra avaliação com comentário opcional
 */

import { NextRequest, NextResponse } from "next/server"
import { prisma } from "@/lib/prisma"
import { validateAccessToken, markTokenAsUsed, hasScope } from "@/server/notification"

export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url)
    const token = searchParams.get("token")
    const ratingStr = searchParams.get("rating")

    if (!token) {
      return NextResponse.redirect(new URL("/error?message=token_missing", request.url))
    }

    if (!ratingStr) {
      return NextResponse.redirect(new URL("/error?message=rating_missing", request.url))
    }

    const rating = parseInt(ratingStr, 10)

    if (isNaN(rating) || rating < 1 || rating > 5) {
      return NextResponse.redirect(new URL("/error?message=rating_invalid", request.url))
    }

    // Valida o token
    const validatedToken = await validateAccessToken(token)

    if (!validatedToken) {
      return NextResponse.redirect(new URL("/error?message=token_expired", request.url))
    }

    // Verifica se o token tem escopo de avaliação
    if (!hasScope(validatedToken.scope, "rate")) {
      return NextResponse.redirect(new URL("/error?message=token_scope_invalid", request.url))
    }

    // Busca o ticket
    const ticket = await prisma.ticket.findUnique({
      where: { id: validatedToken.ticketId },
      select: {
        id: true,
        tenantId: true,
        reference: true,
        subject: true,
        status: true,
        requesterId: true,
        rating: true,
      },
    })

    if (!ticket) {
      return NextResponse.redirect(new URL("/error?message=ticket_not_found", request.url))
    }

    // Verifica se o usuário é o solicitante
    if (ticket.requesterId !== validatedToken.userId) {
      return NextResponse.redirect(new URL("/error?message=access_denied", request.url))
    }

    // Verifica se já existe avaliação
    if (ticket.rating) {
      // Redireciona para página de confirmação mostrando que já foi avaliado
      return NextResponse.redirect(
        new URL(`/rate/${token}?already_rated=true&existing_rating=${ticket.rating.rating}`, request.url)
      )
    }

    // Registra a avaliação
    await prisma.ticketRating.create({
      data: {
        tenantId: ticket.tenantId,
        ticketId: ticket.id,
        userId: validatedToken.userId,
        rating,
      },
    })

    // Marca o token como usado
    await markTokenAsUsed(token)

    // Redireciona para página de confirmação com opção de adicionar comentário
    return NextResponse.redirect(
      new URL(`/rate/${token}?success=true&rating=${rating}`, request.url)
    )
  } catch (error) {
    console.error("[tickets/rate] Erro ao registrar avaliação:", error)
    return NextResponse.redirect(new URL("/error?message=server_error", request.url))
  }
}

export async function POST(request: NextRequest) {
  try {
    const body = await request.json()
    const { token, rating, comment } = body

    if (!token) {
      return NextResponse.json(
        { error: "Token é obrigatório" },
        { status: 400 }
      )
    }

    if (!rating || typeof rating !== "number" || rating < 1 || rating > 5) {
      return NextResponse.json(
        { error: "Avaliação deve ser um número entre 1 e 5" },
        { status: 400 }
      )
    }

    // Valida o token
    const validatedToken = await validateAccessToken(token)

    if (!validatedToken) {
      return NextResponse.json(
        { error: "Token inválido ou expirado" },
        { status: 401 }
      )
    }

    // Verifica se o token tem escopo de avaliação
    if (!hasScope(validatedToken.scope, "rate")) {
      return NextResponse.json(
        { error: "Token não permite avaliação" },
        { status: 403 }
      )
    }

    // Busca o ticket
    const ticket = await prisma.ticket.findUnique({
      where: { id: validatedToken.ticketId },
      select: {
        id: true,
        tenantId: true,
        requesterId: true,
        rating: true,
      },
    })

    if (!ticket) {
      return NextResponse.json(
        { error: "Chamado não encontrado" },
        { status: 404 }
      )
    }

    // Verifica se o usuário é o solicitante
    if (ticket.requesterId !== validatedToken.userId) {
      return NextResponse.json(
        { error: "Acesso negado" },
        { status: 403 }
      )
    }

    // Verifica se já existe avaliação
    if (ticket.rating) {
      // Atualiza o comentário se já existe avaliação
      await prisma.ticketRating.update({
        where: { ticketId: ticket.id },
        data: {
          rating,
          comment: comment ?? null,
        },
      })

      return NextResponse.json({
        success: true,
        message: "Avaliação atualizada com sucesso",
        updated: true,
      })
    }

    // Registra a avaliação
    await prisma.ticketRating.create({
      data: {
        tenantId: ticket.tenantId,
        ticketId: ticket.id,
        userId: validatedToken.userId,
        rating,
        comment: comment ?? null,
      },
    })

    // Marca o token como usado
    await markTokenAsUsed(token)

    return NextResponse.json({
      success: true,
      message: "Avaliação registrada com sucesso",
    })
  } catch (error) {
    console.error("[tickets/rate] Erro ao registrar avaliação:", error)
    return NextResponse.json(
      { error: "Erro interno do servidor" },
      { status: 500 }
    )
  }
}
