import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@/lib/db'
import { getSession } from '@/lib/auth'

async function ensureTables() {
  await prisma.$executeRawUnsafe(`
    CREATE TABLE IF NOT EXISTS tenant_symbols (
      id TEXT PRIMARY KEY DEFAULT gen_random_uuid(),
      "isActive" BOOLEAN NOT NULL DEFAULT true,
      "tenantId" TEXT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
      "iconId" TEXT REFERENCES icon_assets(id) ON DELETE SET NULL,
      "name" TEXT,
      "svgPath" TEXT,
      "isUploaded" BOOLEAN NOT NULL DEFAULT false,
      "categoryId" TEXT,
      "migratedFromIconId" TEXT,
      "customName" TEXT,
      "sortOrder" INTEGER,
      "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
      "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
    )
  `)
  await prisma.$executeRawUnsafe(`
    CREATE TABLE IF NOT EXISTS tenant_categories (
      id TEXT PRIMARY KEY DEFAULT gen_random_uuid(),
      "name" TEXT NOT NULL,
      "description" TEXT,
      "sortOrder" INTEGER NOT NULL DEFAULT 0,
      "isActive" BOOLEAN NOT NULL DEFAULT true,
      "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
      "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
      "tenantId" TEXT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE
    )
  `)

  const symbolCols = [
    `ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "name" TEXT`,
    `ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "svgPath" TEXT`,
    `ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "isUploaded" BOOLEAN NOT NULL DEFAULT false`,
    `ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "categoryId" TEXT`,
    `ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "migratedFromIconId" TEXT`,
    `ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "customName" TEXT`,
    `ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "sortOrder" INTEGER`,
    `ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP`,
    `ALTER TABLE tenant_symbols ADD COLUMN IF NOT EXISTS "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP`,
  ]
  for (const sql of symbolCols) {
    try { await prisma.$executeRawUnsafe(sql) } catch (e) { /* ignore */ }
  }

  const catCols = [
    `ALTER TABLE tenant_categories ADD COLUMN IF NOT EXISTS "description" TEXT`,
    `ALTER TABLE tenant_categories ADD COLUMN IF NOT EXISTS "sortOrder" INTEGER NOT NULL DEFAULT 0`,
    `ALTER TABLE tenant_categories ADD COLUMN IF NOT EXISTS "isActive" BOOLEAN NOT NULL DEFAULT true`,
    `ALTER TABLE tenant_categories ADD COLUMN IF NOT EXISTS "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP`,
    `ALTER TABLE tenant_categories ADD COLUMN IF NOT EXISTS "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP`,
  ]
  for (const sql of catCols) {
    try { await prisma.$executeRawUnsafe(sql) } catch (e) { /* ignore */ }
  }
}

export async function GET() {
  /* ─── 1. Global library (legacy IconAsset) ─── */
  let categoriesWithUrls: any[] = []
  try {
    const user = await getSession()
    const tenantId = user?.tenantId

    const categories = await prisma.$queryRawUnsafe(
      `SELECT * FROM icon_categories WHERE "tenantId" IS NULL OR "tenantId" = $1 ORDER BY "sortOrder" ASC`,
      tenantId || null
    ) as any[]

    let hiddenIconIds: string[] = []
    if (tenantId) {
      const tenant = await prisma.$queryRawUnsafe(
        `SELECT "hiddenIconIds" FROM tenants WHERE id = $1 LIMIT 1`,
        tenantId
      ) as any[]
      hiddenIconIds = tenant[0]?.hiddenIconIds || []
    }

    for (const cat of categories) {
      const icons = await prisma.$queryRawUnsafe(
        `SELECT * FROM icon_assets WHERE "categoryId" = $1 AND "isActive" = true AND ("tenantId" IS NULL OR "tenantId" = $2) ORDER BY name ASC`,
        cat.id, tenantId || null
      ) as any[]
      const filteredIcons = icons
        .filter((icon: any) => !hiddenIconIds.includes(icon.id))
        .map((icon: any) => ({
          ...icon,
          url: `/api/icons/${icon.id}/image`,
        }))
      if (filteredIcons.length > 0) {
        categoriesWithUrls.push({
          ...cat,
          icons: filteredIcons,
        })
      }
    }
  } catch (err) {
    console.error('Error fetching legacy icon categories:', err)
    categoriesWithUrls = []
  }

  /* ─── 2. Tenant symbols (Phase 1 architecture) ─── */
  let tenantSymbolGroups: any[] = []
  let flatTenantSymbols: any[] = []

  try {
    const user = await getSession()
    const tenantId = user?.tenantId

    if (tenantId) {
      await ensureTables()

      const tenantSymbols = await prisma.$queryRawUnsafe(
        `SELECT ts.*, tc.id as "catId", tc.name as "catName"
         FROM tenant_symbols ts
         LEFT JOIN tenant_categories tc ON ts."categoryId" = tc.id
         WHERE ts."tenantId" = $1 AND (ts."isActive" IS NULL OR ts."isActive" = true)
         ORDER BY COALESCE(tc."sortOrder", 9999) ASC, COALESCE(ts."sortOrder", 9999) ASC`,
        tenantId
      ) as any[]

      flatTenantSymbols = tenantSymbols.map((ts: any) => ({
        id: ts.id,
        name: ts.customName || ts.name,
        customName: ts.customName,
        categoryId: ts.categoryId,
        categoryName: ts.catName || null,
        isUploaded: ts.isUploaded,
        migratedFromIconId: ts.migratedFromIconId,
        imageUrl: ts.isUploaded
          ? `/api/tenant/symbols/${ts.id}/image`
          : ts.migratedFromIconId
            ? `/api/icons/${ts.migratedFromIconId}/image`
            : `/api/icons/${ts.id}/image`,
      }))

      const groups = new Map<string | null, any[]>()
      for (const sym of flatTenantSymbols) {
        const key = sym.categoryId || '__none__'
        if (!groups.has(key)) groups.set(key, [])
        groups.get(key)!.push(sym)
      }

      const catIds = Array.from(groups.keys()).filter(k => k !== '__none__') as string[]
      let tenantCategories: any[] = []
      if (catIds.length > 0) {
        tenantCategories = await prisma.$queryRawUnsafe(
          `SELECT * FROM tenant_categories WHERE id = ANY($1) AND "tenantId" = $2 ORDER BY "sortOrder" ASC`,
          catIds, tenantId
        ) as any[]
      }

      const catMap = new Map(tenantCategories.map((c: any) => [c.id, c]))

      tenantSymbolGroups = Array.from(groups.entries()).map(([catId, symbols]) => {
        const cat = catId !== '__none__' ? catMap.get(catId) : null
        return {
          category: cat ? { id: cat.id, name: cat.name } : null,
          symbols,
        }
      })
    }
  } catch (err) {
    console.error('Error fetching tenant symbols:', err)
    tenantSymbolGroups = []
    flatTenantSymbols = []
  }

  /* ─── 3. Legacy mySymbols (keep for old clients during transition) ─── */
  let mySymbolsLegacy: any[] = []
  try {
    const user = await getSession()
    const tenantId = user?.tenantId

    if (tenantId) {
      const legacy = await prisma.$queryRawUnsafe(
        `SELECT ts.*, ia.id as "iconId", ia.name as "iconName", ia."mimeType", ia."iconType"
         FROM tenant_symbols ts
         JOIN icon_assets ia ON ts."iconId" = ia.id
         WHERE ts."tenantId" = $1 AND ts."iconId" IS NOT NULL
         ORDER BY COALESCE(ts."sortOrder", 9999) ASC`,
        tenantId
      ) as any[]
      mySymbolsLegacy = legacy.map((ts: any) => ({
        id: ts.iconId,
        tenantSymbolId: ts.id,
        name: ts.customName || ts.iconName,
        customName: ts.customName,
        mimeType: ts.mimeType,
        iconType: ts.iconType,
        url: `/api/icons/${ts.iconId}/image`,
      }))
    }
  } catch (err) {
    console.error('Error fetching legacy mySymbols:', err)
    mySymbolsLegacy = []
  }

  return NextResponse.json({
    categories: categoriesWithUrls,
    mySymbols: mySymbolsLegacy,
    tenantSymbols: flatTenantSymbols,
    tenantSymbolGroups,
  })
}
