import { NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { queryJobPanelDb, initializeJobPanelDatabase } from '@/lib/job-panel-db'
import { getJobByName, getJobEmployees } from '@/lib/services/job-adapter'
import { prisma } from '@/lib/db'
import type { RowDataPacket } from 'mysql2'

// GET - Get panel details
export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const session = await getSession()
    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    const { id } = await params

    // Initialize database if needed
    try {
      await initializeJobPanelDatabase()
    } catch (initError) {
      console.error('[JobPanel] Failed to initialize database:', initError)
    }

    // Get panel
    let panels: RowDataPacket[] = []
    try {
      panels = await queryJobPanelDb<RowDataPacket[]>(
        'SELECT * FROM job_panels WHERE id = ?',
        [id]
      )
    } catch (e) {
      console.error('[JobPanel] Failed to query panel:', e)
      return NextResponse.json({ error: 'Database error' }, { status: 500 })
    }

    if (panels.length === 0) {
      return NextResponse.json({ error: 'Panel not found' }, { status: 404 })
    }

    const panel = panels[0]

    // Check access (superadmin or admin have full access)
    if (session.role !== 'SUPERADMIN' && session.role !== 'ADMIN') {
      try {
        const accessMembers = await queryJobPanelDb<RowDataPacket[]>(
          'SELECT * FROM job_panel_members WHERE panel_id = ? AND discord_id = ?',
          [id, session.discordId]
        )
        if (accessMembers.length === 0) {
          return NextResponse.json({ error: 'Access denied' }, { status: 403 })
        }
      } catch (e) {
        // Table doesn't exist yet - allow access for now
        console.error('[JobPanel] Failed to check access:', e)
      }
    }

    // Get features - with fallback for missing table
    let features: RowDataPacket[] = []
    try {
      features = await queryJobPanelDb<RowDataPacket[]>(
        'SELECT * FROM job_panel_features WHERE panel_id = ?',
        [id]
      )
    } catch (e) {
      console.error('[JobPanel] Failed to fetch features:', e)
    }

    // Get members (leaders) - with fallback for missing table
    let members: RowDataPacket[] = []
    try {
      members = await queryJobPanelDb<RowDataPacket[]>(
        'SELECT * FROM job_panel_members WHERE panel_id = ? ORDER BY role, assigned_at',
        [id]
      )
    } catch (e) {
      console.error('[JobPanel] Failed to fetch members:', e)
    }

    // Get rank permissions - with fallback for missing table
    let rankPermissions: RowDataPacket[] = []
    try {
      rankPermissions = await queryJobPanelDb<RowDataPacket[]>(
        'SELECT * FROM job_panel_rank_permissions WHERE panel_id = ? ORDER BY rank_grade',
        [id]
      )
    } catch (e) {
      console.error('[JobPanel] Failed to fetch rank permissions:', e)
    }

    // Get webhooks - with fallback for missing table
    let webhooks: RowDataPacket[] = []
    try {
      webhooks = await queryJobPanelDb<RowDataPacket[]>(
        'SELECT * FROM job_panel_webhooks WHERE panel_id = ?',
        [id]
      )
    } catch (e) {
      console.error('[JobPanel] Failed to fetch webhooks:', e)
    }

    // Get job info and employees from game database
    let jobInfo = null
    let employees: any[] = []
    
    try {
      jobInfo = await getJobByName(panel.job_name)
      const rawEmployees = await getJobEmployees(panel.job_name)
      
      // Check which employees are registered in UCP
      // Get all UCP users (they register via Discord OAuth)
      const ucpUsers = await prisma.user.findMany({
        select: {
          id: true,
          username: true,
          discordId: true,
        }
      })
      
      // Build a map of discordId -> UCP user for fast lookup
      const discordIdToUser = new Map<string, { id: string; username: string; discordId: string | null }>()
      for (const user of ucpUsers) {
        if (user.discordId) {
          discordIdToUser.set(user.discordId, user)
        }
      }
      
      // Match employees with UCP users
      // The matching depends on how your FiveM server stores identifiers
      // QBCore stores license field which often contains "discord:123456789" or the license identifier
      const employeesWithUcp = rawEmployees.map((emp) => {
        let ucpUser = null
        
        // Try matching via license field first (QBCore stores discord here)
        if (emp.license && !ucpUser) {
          // Pattern 1: license contains "discord:123456789"
          const discordMatch = emp.license.match(/discord:(\d+)/)
          if (discordMatch) {
            const discordId = discordMatch[1]
            ucpUser = discordIdToUser.get(discordId) || null
          }
          
          // Pattern 2: Direct match with discordId
          if (!ucpUser) {
            for (const [discordId, user] of discordIdToUser) {
              if (emp.license.includes(discordId)) {
                ucpUser = user
                break
              }
            }
          }
        }
        
        // Try matching via citizenId if license didn't match
        if (emp.citizenId && !ucpUser) {
          // Pattern 3: citizenId is "discord:123456789"
          if (emp.citizenId.startsWith('discord:')) {
            const discordId = emp.citizenId.replace('discord:', '')
            ucpUser = discordIdToUser.get(discordId) || null
          }
          
          // Pattern 4: citizenId contains discord ID somewhere
          if (!ucpUser) {
            for (const [discordId, user] of discordIdToUser) {
              if (emp.citizenId.includes(discordId)) {
                ucpUser = user
                break
              }
            }
          }
        }
        
        return {
          ...emp,
          ucpRegistered: !!ucpUser,
          ucpUserId: ucpUser?.id || null,
          ucpUsername: ucpUser?.username || null,
        }
      })
      
      employees = employeesWithUcp
    } catch (e) {
      console.error('[JobPanel] Failed to fetch job info from game DB:', e)
      // Return empty data if game DB is not available
      jobInfo = { name: panel.job_name, label: panel.job_label, grades: [] }
    }

    return NextResponse.json({
      panel: {
        id: panel.id,
        jobName: panel.job_name,
        jobLabel: panel.job_label,
        panelName: panel.panel_name,
        description: panel.description,
        icon: panel.icon,
        isActive: panel.is_active === 1,
        createdAt: panel.created_at,
        createdBy: panel.created_by,
        createdByName: panel.created_by_name,
      },
      features: features.map(f => ({
        key: f.feature_key,
        isEnabled: f.is_enabled === 1,
        config: f.config ? JSON.parse(f.config) : null,
      })),
      members: members.map(m => ({
        id: m.id,
        userId: m.user_id,
        discordId: m.discord_id,
        username: m.username,
        role: m.role,
        assignedAt: m.assigned_at,
      })),
      rankPermissions: rankPermissions.map(rp => ({
        rankGrade: rp.rank_grade,
        rankName: rp.rank_name,
        permissions: rp.permissions ? JSON.parse(rp.permissions) : {},
      })),
      webhooks: webhooks.length > 0 ? {
        factionWebhookEnabled: webhooks[0].faction_webhook_enabled === 1,
        adminWebhookEnabled: webhooks[0].admin_webhook_enabled === 1,
        hasFactionWebhook: !!webhooks[0].faction_webhook_url,
        hasAdminWebhook: !!webhooks[0].admin_webhook_url,
      } : null,
      jobInfo,
      employees,
    })
  } catch (error) {
    console.error('[JobPanels] GET detail error:', error)
    return NextResponse.json({ error: 'Failed to fetch panel' }, { status: 500 })
  }
}

// PUT - Update panel
export async function PUT(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const session = await getSession()
    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    const { id } = await params
    const body = await request.json()

    // Check if user is superadmin or panel leader
    let canEdit = session.role === 'SUPERADMIN'
    if (!canEdit) {
      const members = await queryJobPanelDb<RowDataPacket[]>(
        'SELECT * FROM job_panel_members WHERE panel_id = ? AND discord_id = ? AND role IN ("LEADER", "CO_LEADER")',
        [id, session.discordId]
      )
      canEdit = members.length > 0
    }

    if (!canEdit) {
      return NextResponse.json({ error: 'Access denied' }, { status: 403 })
    }

    const { panelName, description, icon, isActive, features, rankPermissions, webhooks } = body

    // Update panel info
    if (panelName || description !== undefined || icon || isActive !== undefined) {
      const updates: string[] = []
      const values: unknown[] = []

      if (panelName) {
        updates.push('panel_name = ?')
        values.push(panelName)
      }
      if (description !== undefined) {
        updates.push('description = ?')
        values.push(description)
      }
      if (icon) {
        updates.push('icon = ?')
        values.push(icon)
      }
      if (isActive !== undefined) {
        updates.push('is_active = ?')
        values.push(isActive)
      }

      if (updates.length > 0) {
        values.push(id)
        await queryJobPanelDb(
          `UPDATE job_panels SET ${updates.join(', ')} WHERE id = ?`,
          values
        )
      }
    }

    // Update features (superadmin only)
    if (features && session.role === 'SUPERADMIN') {
      for (const feature of features) {
        await queryJobPanelDb(
          'UPDATE job_panel_features SET is_enabled = ?, config = ? WHERE panel_id = ? AND feature_key = ?',
          [feature.isEnabled, feature.config ? JSON.stringify(feature.config) : null, id, feature.key]
        )
      }
    }

    // Update rank permissions
    if (rankPermissions) {
      for (const rp of rankPermissions) {
        const existing = await queryJobPanelDb<RowDataPacket[]>(
          'SELECT id FROM job_panel_rank_permissions WHERE panel_id = ? AND rank_grade = ?',
          [id, rp.rankGrade]
        )

        if (existing.length > 0) {
          await queryJobPanelDb(
            'UPDATE job_panel_rank_permissions SET rank_name = ?, permissions = ? WHERE panel_id = ? AND rank_grade = ?',
            [rp.rankName, JSON.stringify(rp.permissions), id, rp.rankGrade]
          )
        } else {
          await queryJobPanelDb(
            'INSERT INTO job_panel_rank_permissions (id, panel_id, rank_grade, rank_name, permissions) VALUES (?, ?, ?, ?, ?)',
            [uuidv4(), id, rp.rankGrade, rp.rankName, JSON.stringify(rp.permissions)]
          )
        }
      }
    }

    // Update webhooks (superadmin only)
    if (webhooks && session.role === 'SUPERADMIN') {
      await queryJobPanelDb(
        `UPDATE job_panel_webhooks SET 
          faction_webhook_url = ?,
          faction_webhook_enabled = ?,
          admin_webhook_url = ?,
          admin_webhook_enabled = ?
         WHERE panel_id = ?`,
        [
          webhooks.factionWebhookUrl || null,
          webhooks.factionWebhookEnabled || false,
          webhooks.adminWebhookUrl || null,
          webhooks.adminWebhookEnabled || false,
          id,
        ]
      )
    }

    // Log the update
    await logJobPanel('PANEL_UPDATED', {
      panelId: id,
      changes: {
        panelName: panelName || undefined,
        isActive: isActive !== undefined ? isActive : undefined,
        featuresChanged: features ? features.length : 0,
        rankPermissionsChanged: rankPermissions ? rankPermissions.length : 0,
      },
    })

    return NextResponse.json({ success: true, message: 'Panel updated successfully' })
  } catch (error) {
    console.error('[JobPanels] PUT error:', error)
    return NextResponse.json({ error: 'Failed to update panel' }, { status: 500 })
  }
}

// DELETE - Delete panel
export async function DELETE(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const session = await getSession()
    if (!session || session.role !== 'SUPERADMIN') {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    const { id } = await params

    // Get panel info before deletion
    const panels = await queryJobPanelDb<RowDataPacket[]>(
      'SELECT panel_name, job_name FROM job_panels WHERE id = ?',
      [id]
    )
    const panelInfo = panels[0]

    // Delete panel (cascades to all related tables)
    await queryJobPanelDb('DELETE FROM job_panels WHERE id = ?', [id])

    // Log the deletion
    await logJobPanel('PANEL_DELETED', {
      panelId: id,
      panelName: panelInfo?.panel_name,
      jobName: panelInfo?.job_name,
    })

    return NextResponse.json({ success: true, message: 'Panel deleted successfully' })
  } catch (error) {
    console.error('[JobPanels] DELETE error:', error)
    return NextResponse.json({ error: 'Failed to delete panel' }, { status: 500 })
  }
}
