import { db } from '@sim/db'
import { chat } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { and, eq, isNull } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { chatSSOContract } from '@/lib/api/contracts/chats'
import { parseRequest } from '@/lib/api/server'
import type { TokenBucketConfig } from '@/lib/core/rate-limiter'
import { RateLimiter } from '@/lib/core/rate-limiter'
import { isEmailAllowed } from '@/lib/core/security/deployment'
import { generateRequestId, getClientIp } from '@/lib/core/utils/request'
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils'

const logger = createLogger('ChatSSOAPI')

export const dynamic = 'force-dynamic'
export const runtime = 'nodejs'

const rateLimiter = new RateLimiter()

const SSO_IP_RATE_LIMIT: TokenBucketConfig = {
  maxTokens: 20,
  refillRate: 20,
  refillIntervalMs: 15 * 60_000,
}

export const POST = withRouteHandler(
  async (request: NextRequest, context: { params: Promise<{ identifier: string }> }) => {
    const requestId = generateRequestId()

    const ip = getClientIp(request)
    const ipRateLimit = await rateLimiter.checkRateLimitDirect(
      `chat-sso:ip:${ip}`,
      SSO_IP_RATE_LIMIT
    )
    if (!ipRateLimit.allowed) {
      logger.warn(`[${requestId}] SSO eligibility rate limit exceeded from ${ip}`)
      const retryAfter = Math.ceil(
        (ipRateLimit.retryAfterMs ?? SSO_IP_RATE_LIMIT.refillIntervalMs) / 1000
      )
      const response = createErrorResponse('Too many requests. Please try again later.', 429)
      response.headers.set('Retry-After', String(retryAfter))
      return response
    }

    const parsed = await parseRequest(chatSSOContract, request, context)
    if (!parsed.success) return parsed.response

    const { identifier } = parsed.data.params
    const { email } = parsed.data.body

    const [deployment] = await db
      .select({
        authType: chat.authType,
        allowedEmails: chat.allowedEmails,
        isActive: chat.isActive,
      })
      .from(chat)
      .where(and(eq(chat.identifier, identifier), isNull(chat.archivedAt)))
      .limit(1)

    if (!deployment || !deployment.isActive) {
      logger.warn(`[${requestId}] SSO check on missing/inactive chat: ${identifier}`)
      return createErrorResponse('Chat not found', 404)
    }

    if (deployment.authType !== 'sso') {
      return createErrorResponse('Chat is not configured for SSO authentication', 400)
    }

    const eligible = isEmailAllowed(email, (deployment.allowedEmails as string[]) || [])

    return createSuccessResponse({ eligible })
  }
)
