/**
 * API de Preferências de Notificação
 * GET - Retorna preferências do usuário
 * PUT - Atualiza preferências do usuário
 */

import { NextRequest, NextResponse } from "next/server"
import { getServerSession } from "@/lib/auth-server"
import { prisma } from "@/lib/prisma"
import {
  NOTIFICATION_TYPES,
  canCollaboratorDisable,
  isRequiredNotification,
  type NotificationType,
} from "@/server/email"

// Tipos de notificação que colaboradores podem ver
const COLLABORATOR_VISIBLE_TYPES: NotificationType[] = [
  "ticket_created",
  "ticket_assigned",
  "ticket_resolved",
  "ticket_reopened",
  "ticket_status_changed",
  "ticket_priority_changed",
  "comment_public",
  "security_password_reset",
  "security_email_verify",
  "security_email_change",
  "security_new_login",
]

export async function GET(_request: NextRequest) {
  try {
    const session = await getServerSession()

    if (!session?.user?.id) {
      return NextResponse.json(
        { error: "Não autorizado" },
        { status: 401 }
      )
    }

    const userId = session.user.id
    const userRole = session.user.role as string
    const isStaff = ["ADMIN", "MANAGER", "AGENT"].includes(userRole)

    // Busca preferências existentes
    let prefs = await prisma.notificationPreferences.findUnique({
      where: { userId },
    })

    // Se não existir, cria com valores padrão
    if (!prefs) {
      const user = await prisma.user.findFirst({
        where: { email: session.user.email },
        select: { tenantId: true },
      })

      if (!user) {
        return NextResponse.json(
          { error: "Usuário não encontrado" },
          { status: 404 }
        )
      }

      prefs = await prisma.notificationPreferences.create({
        data: {
          userId,
          tenantId: user.tenantId,
          emailEnabled: true,
          digestFrequency: "immediate",
          typePreferences: "{}",
          categoryPreferences: "{}",
        },
      })
    }

    // Filtra tipos disponíveis baseado no role
    const availableTypes = isStaff
      ? Object.keys(NOTIFICATION_TYPES)
      : COLLABORATOR_VISIBLE_TYPES

    // Parse JSON strings
    const typePrefs: Record<string, boolean> = prefs!.typePreferences
      ? JSON.parse(prefs!.typePreferences as string)
      : {}
    const catPrefs = prefs!.categoryPreferences
      ? JSON.parse(prefs!.categoryPreferences as string)
      : {}

    // Monta resposta com configuração de cada tipo
    const typeConfigs = availableTypes.map((type) => {
      const config = NOTIFICATION_TYPES[type as NotificationType]
      const enabled = typePrefs[type] ?? config.defaultEnabled

      return {
        type,
        label: config.label,
        enabled,
        required: config.required ?? false,
        canDisable: isStaff
          ? !config.required
          : canCollaboratorDisable(type as NotificationType),
      }
    })

    return NextResponse.json({
      emailEnabled: prefs.emailEnabled,
      quietHoursStart: prefs.quietHoursStart,
      quietHoursEnd: prefs.quietHoursEnd,
      timezone: prefs.timezone,
      digestFrequency: prefs.digestFrequency,
      types: typeConfigs,
      categoryPreferences: catPrefs,
      isStaff,
    })
  } catch (error) {
    console.error("[notifications/preferences] Erro ao buscar preferências:", error)
    const errorMessage = error instanceof Error ? error.message : "Erro desconhecido"
    return NextResponse.json(
      { error: "Erro interno do servidor", details: errorMessage },
      { status: 500 }
    )
  }
}

export async function PUT(request: NextRequest) {
  try {
    const session = await getServerSession()

    if (!session?.user?.id) {
      return NextResponse.json(
        { error: "Não autorizado" },
        { status: 401 }
      )
    }

    const userId = session.user.id
    const userRole = session.user.role as string
    const isStaff = ["ADMIN", "MANAGER", "AGENT"].includes(userRole)

    const body = await request.json()
    const {
      emailEnabled,
      quietHoursStart,
      quietHoursEnd,
      timezone,
      digestFrequency,
      typePreferences,
      categoryPreferences,
    } = body

    // Valida typePreferences
    const validatedTypePrefs: Record<string, boolean> = {}

    if (typePreferences && typeof typePreferences === "object") {
      for (const [type, enabled] of Object.entries(typePreferences)) {
        // Verifica se é um tipo válido
        if (!(type in NOTIFICATION_TYPES)) continue

        // Verifica se o tipo é obrigatório
        if (isRequiredNotification(type as NotificationType)) {
          validatedTypePrefs[type] = true // Força true para obrigatórios
          continue
        }

        // Para colaboradores, verifica se pode desativar
        if (!isStaff && !canCollaboratorDisable(type as NotificationType)) {
          continue // Ignora tipos que colaboradores não podem modificar
        }

        validatedTypePrefs[type] = Boolean(enabled)
      }
    }

    // Busca preferências existentes
    const existingPrefs = await prisma.notificationPreferences.findUnique({
      where: { userId },
    })

    if (!existingPrefs) {
      // Busca tenantId do usuário
      const user = await prisma.user.findFirst({
        where: { email: session.user.email },
        select: { tenantId: true },
      })

      if (!user) {
        return NextResponse.json(
          { error: "Usuário não encontrado" },
          { status: 404 }
        )
      }

      // Cria novas preferências
      await prisma.notificationPreferences.create({
        data: {
          userId,
          tenantId: user.tenantId,
          emailEnabled: emailEnabled ?? true,
          quietHoursStart: quietHoursStart ?? null,
          quietHoursEnd: quietHoursEnd ?? null,
          timezone: timezone ?? "America/Sao_Paulo",
          digestFrequency: digestFrequency ?? "immediate",
          typePreferences: JSON.stringify(validatedTypePrefs),
          categoryPreferences: JSON.stringify(categoryPreferences ?? {}),
        },
      })
    } else {
      // Parse existing JSON strings
      const existingTypePrefs = existingPrefs.typePreferences
        ? JSON.parse(existingPrefs.typePreferences as string)
        : {}
      const existingCatPrefs = existingPrefs.categoryPreferences
        ? JSON.parse(existingPrefs.categoryPreferences as string)
        : {}

      // Atualiza preferências existentes
      await prisma.notificationPreferences.update({
        where: { userId },
        data: {
          emailEnabled: emailEnabled ?? existingPrefs.emailEnabled,
          quietHoursStart: quietHoursStart !== undefined ? quietHoursStart : existingPrefs.quietHoursStart,
          quietHoursEnd: quietHoursEnd !== undefined ? quietHoursEnd : existingPrefs.quietHoursEnd,
          timezone: timezone ?? existingPrefs.timezone,
          digestFrequency: digestFrequency ?? existingPrefs.digestFrequency,
          typePreferences: JSON.stringify({
            ...existingTypePrefs,
            ...validatedTypePrefs,
          }),
          categoryPreferences: JSON.stringify(categoryPreferences ?? existingCatPrefs),
        },
      })
    }

    return NextResponse.json({
      success: true,
      message: "Preferências atualizadas com sucesso",
    })
  } catch (error) {
    console.error("[notifications/preferences] Erro ao atualizar preferências:", error)
    const errorMessage = error instanceof Error ? error.message : "Erro desconhecido"
    return NextResponse.json(
      { error: "Erro interno do servidor", details: errorMessage },
      { status: 500 }
    )
  }
}
