import { headers } from 'next/headers'
import { NextResponse } from 'next/server'
import { workspaceMemberRepo, type WorkspaceAuthDetail } from '@/lib/database/repositories/workspace-member.repo'
import { GLOBAL_WORKSPACE_ID, ensureUserGlobalClaudeDir } from '@/lib/workspace-fs'
import { auth } from './index'
import {
  getEffectiveWorkspaceRole,
  roleAllowsAccess,
  type WorkspaceAccess,
  type WorkspaceRole,
} from './workspace-access'

export async function getCurrentUser() {
  const session = await auth.api.getSession({
    headers: await headers(),
  })
  return session?.user ?? null
}

export async function requireUser() {
  const user = await getCurrentUser()
  if (!user) {
    throw new Response(JSON.stringify({ error: 'Unauthorized' }), {
      status: 401,
      headers: { 'Content-Type': 'application/json' },
    })
  }
  return user
}

export function jsonAuthError(message: string, status: 401 | 403 | 404) {
  return new Response(JSON.stringify({ error: message }), {
    status,
    headers: { 'Content-Type': 'application/json' },
  })
}

export function notFound(message = 'Not found') {
  return NextResponse.json({ error: message }, { status: 404 })
}

export type AuthorizedWorkspace = {
  id: string
  path: string
  owner_user_id: string
  isGlobal: boolean
  role: WorkspaceRole
}


export async function requireWorkspaceAccess(workspaceId: string, minimumAccess: WorkspaceAccess = 'read'): Promise<{
  user: NonNullable<Awaited<ReturnType<typeof getCurrentUser>>>
  workspace: AuthorizedWorkspace
}> {
  const user = await requireUser()

  if (workspaceId === GLOBAL_WORKSPACE_ID) {
    const globalPath = ensureUserGlobalClaudeDir(user.id)
    return {
      user,
      workspace: {
        id: GLOBAL_WORKSPACE_ID,
        path: globalPath,
        owner_user_id: user.id,
        isGlobal: true,
        role: 'owner',
      },
    }
  }

  const workspace: WorkspaceAuthDetail | undefined = workspaceMemberRepo.findDetailForAuth(workspaceId)

  if (!workspace) {
    throw jsonAuthError('Workspace not found', 404)
  }

  const directRole = workspaceMemberRepo.findRoleByWorkspaceAndUser(workspace.id, user.id) ?? null
  const role = getEffectiveWorkspaceRole({
    userId: user.id,
    workspaceOwnerUserId: workspace.ownerUserId,
    workspaceDirectRole: directRole,
  })

  if (!role) {
    throw jsonAuthError('Workspace not found', 404)
  }
  if (!roleAllowsAccess(role, minimumAccess)) {
    throw jsonAuthError('Forbidden', 403)
  }

  return {
    user,
    workspace: {
      id: workspace.id,
      path: workspace.path,
      owner_user_id: workspace.ownerUserId,
      isGlobal: false,
      role,
    },
  }
}

export function requireWorkspaceReadAccess(workspaceId: string) {
  return requireWorkspaceAccess(workspaceId, 'read')
}

export function requireWorkspaceWriteAccess(workspaceId: string) {
  return requireWorkspaceAccess(workspaceId, 'write')
}

export function requireWorkspaceAdminAccess(workspaceId: string) {
  return requireWorkspaceAccess(workspaceId, 'admin')
}

export function unauthorized() {
  return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}

export function forbidden() {
  return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
}

export async function requireAdmin() {
  const user = await requireUser()
  if (String(user.role || '') !== 'admin') {
    throw jsonAuthError('Forbidden', 403)
  }
  return user
}

export function isAuthError(error: unknown): error is Response {
  return error instanceof Response
}
