import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import {
  addCopilotAutoAllowedToolContract,
  removeCopilotAutoAllowedToolContract,
} from '@/lib/api/contracts/copilot'
import { parseRequest } from '@/lib/api/server'
import { getSession } from '@/lib/auth'
import { TraceAttr } from '@/lib/copilot/generated/trace-attributes-v1'
import { fetchGo } from '@/lib/copilot/request/go/fetch'
import { getMothershipBaseURL } from '@/lib/copilot/server/agent-url'
import { env } from '@/lib/core/config/env'
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'

const logger = createLogger('CopilotAutoAllowedToolsAPI')

/** Headers for server-to-server calls to the copilot backend. */
function copilotHeaders(): Record<string, string> {
  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
  }
  if (env.COPILOT_API_KEY) {
    headers['x-api-key'] = env.COPILOT_API_KEY
  }
  return headers
}

/**
 * GET - Fetch user's auto-allowed integration tools
 */
export const GET = withRouteHandler(async () => {
  try {
    const session = await getSession()

    if (!session?.user?.id) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    const userId = session.user.id
    const mothershipBaseURL = await getMothershipBaseURL({ userId })

    const res = await fetchGo(
      `${mothershipBaseURL}/api/tool-preferences/auto-allowed?userId=${encodeURIComponent(userId)}`,
      {
        method: 'GET',
        headers: copilotHeaders(),
        spanName: 'sim → go /api/tool-preferences/auto-allowed',
        operation: 'list_auto_allowed_tools',
        attributes: { [TraceAttr.UserId]: userId },
      }
    )

    if (!res.ok) {
      logger.warn('Copilot returned error for list auto-allowed', { status: res.status })
      return NextResponse.json({ autoAllowedTools: [] })
    }

    const payload = await res.json()
    return NextResponse.json({ autoAllowedTools: payload?.autoAllowedTools || [] })
  } catch (error) {
    logger.error('Failed to fetch auto-allowed tools', { error })
    return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
  }
})

/**
 * POST - Add a tool to the auto-allowed list
 */
export const POST = withRouteHandler(async (request: NextRequest) => {
  try {
    const session = await getSession()

    if (!session?.user?.id) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    const userId = session.user.id
    const mothershipBaseURL = await getMothershipBaseURL({ userId })
    const parsed = await parseRequest(
      addCopilotAutoAllowedToolContract,
      request,
      {},
      {
        validationErrorResponse: () =>
          NextResponse.json({ error: 'toolId must be a string' }, { status: 400 }),
        invalidJsonResponse: () =>
          NextResponse.json({ error: 'toolId must be a string' }, { status: 400 }),
      }
    )
    if (!parsed.success) return parsed.response
    const { toolId } = parsed.data.body

    const res = await fetchGo(`${mothershipBaseURL}/api/tool-preferences/auto-allowed`, {
      method: 'POST',
      headers: copilotHeaders(),
      body: JSON.stringify({ userId, toolId }),
      spanName: 'sim → go /api/tool-preferences/auto-allowed',
      operation: 'add_auto_allowed_tool',
      attributes: { [TraceAttr.UserId]: userId, [TraceAttr.ToolId]: toolId },
    })

    if (!res.ok) {
      logger.warn('Copilot returned error for add auto-allowed', { status: res.status })
      return NextResponse.json({ error: 'Failed to add tool' }, { status: 500 })
    }

    const payload = await res.json()
    return NextResponse.json({
      success: true,
      autoAllowedTools: payload?.autoAllowedTools || [],
    })
  } catch (error) {
    logger.error('Failed to add auto-allowed tool', { error })
    return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
  }
})

/**
 * DELETE - Remove a tool from the auto-allowed list
 */
export const DELETE = withRouteHandler(async (request: NextRequest) => {
  try {
    const session = await getSession()

    if (!session?.user?.id) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    const userId = session.user.id
    const mothershipBaseURL = await getMothershipBaseURL({ userId })
    const parsed = await parseRequest(
      removeCopilotAutoAllowedToolContract,
      request,
      {},
      {
        validationErrorResponse: () =>
          NextResponse.json({ error: 'toolId query parameter is required' }, { status: 400 }),
      }
    )
    if (!parsed.success) return parsed.response
    const { toolId } = parsed.data.query

    const res = await fetchGo(
      `${mothershipBaseURL}/api/tool-preferences/auto-allowed?userId=${encodeURIComponent(userId)}&toolId=${encodeURIComponent(toolId)}`,
      {
        method: 'DELETE',
        headers: copilotHeaders(),
        spanName: 'sim → go /api/tool-preferences/auto-allowed',
        operation: 'remove_auto_allowed_tool',
        attributes: { [TraceAttr.UserId]: userId, [TraceAttr.ToolId]: toolId },
      }
    )

    if (!res.ok) {
      logger.warn('Copilot returned error for remove auto-allowed', { status: res.status })
      return NextResponse.json({ error: 'Failed to remove tool' }, { status: 500 })
    }

    const payload = await res.json()
    return NextResponse.json({
      success: true,
      autoAllowedTools: payload?.autoAllowedTools || [],
    })
  } catch (error) {
    logger.error('Failed to remove auto-allowed tool', { error })
    return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
  }
})
