import { type NextRequest, NextResponse } from "next/server"
import { safeQuery } from "@/lib/database"

type ManagedTypeKind = "field" | "department" | "team"

type AdminScope = {
  role: string
  field?: string | null
  department?: string | null
  team?: string | null
}

const getAdminScope = async (adminId?: string) => {
  if (!adminId) {
    return { ok: false, response: NextResponse.json({ error: "Missing admin id." }, { status: 400 }) }
  }

  const adminRows = (await safeQuery("SELECT role, field, department, team FROM users WHERE national_id = ?", [
    adminId,
  ])) as AdminScope[]
  if (adminRows.length === 0) {
    return { ok: false, response: NextResponse.json({ error: "Admin not found." }, { status: 404 }) }
  }

  return { ok: true as const, admin: adminRows[0] }
}

const canManageType = async (admin: AdminScope, managedType: { type: ManagedTypeKind; name: string; parentId: number | null }) => {
  if (admin.role === "global_admin") return true
  if (admin.role === "field_admin") {
    if (managedType.type === "field") return managedType.name === admin.field
    if (managedType.type === "department") {
      const fieldRows = (await safeQuery("SELECT id FROM managed_types WHERE type = 'field' AND name = ?", [
        admin.field,
      ])) as Array<{ id: number }>
      return fieldRows.length > 0 && managedType.parentId === fieldRows[0].id
    }
    if (managedType.type === "team") {
      const departmentRows = (await safeQuery(
        "SELECT parent_id AS parentId FROM managed_types WHERE id = ? AND type = 'department'",
        [managedType.parentId],
      )) as Array<{ parentId: number | null }>
      if (departmentRows.length === 0) return false
      const fieldRows = (await safeQuery("SELECT id FROM managed_types WHERE type = 'field' AND name = ?", [
        admin.field,
      ])) as Array<{ id: number }>
      return fieldRows.length > 0 && departmentRows[0].parentId === fieldRows[0].id
    }
  }
  if (admin.role === "department_admin") {
    if (managedType.type === "department") return managedType.name === admin.department
    if (managedType.type === "team") {
      const departmentRows = (await safeQuery(
        "SELECT id FROM managed_types WHERE type = 'department' AND name = ?",
        [admin.department],
      )) as Array<{ id: number }>
      return departmentRows.length > 0 && managedType.parentId === departmentRows[0].id
    }
  }
  return false
}

export async function DELETE(request: NextRequest, { params }: { params: { id: string } }) {
  try {
    const { adminId } = await request.json()

    const adminCheck = await getAdminScope(adminId)
    if (!adminCheck.ok) {
      return adminCheck.response
    }

    const typeRows = (await safeQuery("SELECT id, type, name, parent_id AS parentId FROM managed_types WHERE id = ?", [
      params.id,
    ])) as Array<{ id: number; type: ManagedTypeKind; name: string; parentId: number | null }>

    if (typeRows.length === 0) {
      return NextResponse.json({ error: "Managed type not found." }, { status: 404 })
    }

    const managedType = typeRows[0]
    const column = managedType.type

    if (!(await canManageType(adminCheck.admin, managedType))) {
      return NextResponse.json({ error: "Insufficient permissions." }, { status: 403 })
    }

    const childRows = (await safeQuery("SELECT COUNT(*) as count FROM managed_types WHERE parent_id = ?", [
      managedType.id,
    ])) as Array<{ count: number }>
    if ((childRows[0]?.count || 0) > 0) {
      return NextResponse.json({ error: "Remove child items first." }, { status: 409 })
    }

    const usageRows = (await safeQuery(`SELECT COUNT(*) as count FROM users WHERE ${column} = ?`, [
      managedType.name,
    ])) as Array<{ count: number }>

    if ((usageRows[0]?.count || 0) > 0) {
      return NextResponse.json({ error: "Value is still assigned to users." }, { status: 409 })
    }

    await safeQuery("DELETE FROM managed_types WHERE id = ?", [managedType.id])

    return NextResponse.json({ success: true })
  } catch (error) {
    console.error("Managed types delete error:", error)
    return NextResponse.json({ error: "Failed to delete managed type." }, { status: 500 })
  }
}

export async function PATCH(request: NextRequest, { params }: { params: { id: string } }) {
  try {
    const { adminId, name } = await request.json()

    const adminCheck = await getAdminScope(adminId)
    if (!adminCheck.ok) {
      return adminCheck.response
    }

    const trimmedName = typeof name === "string" ? name.trim() : ""
    if (!trimmedName) {
      return NextResponse.json({ error: "Name is required." }, { status: 400 })
    }

    const typeRows = (await safeQuery("SELECT id, type, name, parent_id AS parentId FROM managed_types WHERE id = ?", [
      params.id,
    ])) as Array<{ id: number; type: ManagedTypeKind; name: string; parentId: number | null }>

    if (typeRows.length === 0) {
      return NextResponse.json({ error: "Managed type not found." }, { status: 404 })
    }

    const managedType = typeRows[0]
    if (!(await canManageType(adminCheck.admin, managedType))) {
      return NextResponse.json({ error: "Insufficient permissions." }, { status: 403 })
    }

    await safeQuery("UPDATE managed_types SET name = ? WHERE id = ?", [trimmedName, managedType.id])

    const column = managedType.type
    await safeQuery(`UPDATE users SET ${column} = ? WHERE ${column} = ?`, [trimmedName, managedType.name])

    return NextResponse.json({ success: true })
  } catch (error: any) {
    if (error?.code === "ER_DUP_ENTRY") {
      return NextResponse.json({ error: "Value already exists." }, { status: 409 })
    }
    console.error("Managed types rename error:", error)
    return NextResponse.json({ error: "Failed to rename managed type." }, { status: 500 })
  }
}
