import { queryJobPanelDb } from '@/lib/job-panel-db'
import { v4 as uuidv4 } from 'uuid'
import type { RowDataPacket } from 'mysql2'

export type WebhookType = 'FACTION' | 'ADMIN'
export type LogCategory = 'FACTION' | 'ADMIN' | 'SYSTEM'

export interface WebhookEmbed {
  title: string
  description?: string
  color?: number
  fields?: { name: string; value: string; inline?: boolean }[]
  footer?: { text: string; icon_url?: string }
  timestamp?: string
  thumbnail?: { url: string }
  author?: { name: string; icon_url?: string; url?: string }
}

export interface WebhookPayload {
  username?: string
  avatar_url?: string
  content?: string
  embeds?: WebhookEmbed[]
}

// Color constants for embeds
export const EMBED_COLORS = {
  INFO: 0x3498db,     // Blue
  SUCCESS: 0x2ecc71,  // Green
  WARNING: 0xf39c12,  // Orange
  ERROR: 0xe74c3c,    // Red
  NEUTRAL: 0x95a5a6,  // Gray
  ADMIN: 0x9b59b6,    // Purple
}

/**
 * Get webhook URLs for a panel
 */
async function getWebhookUrls(panelId: string): Promise<{
  factionUrl: string | null
  factionEnabled: boolean
  adminUrl: string | null
  adminEnabled: boolean
}> {
  const webhooks = await queryJobPanelDb<RowDataPacket[]>(
    'SELECT * FROM job_panel_webhooks WHERE panel_id = ?',
    [panelId]
  )

  if (webhooks.length === 0) {
    return { factionUrl: null, factionEnabled: false, adminUrl: null, adminEnabled: false }
  }

  return {
    factionUrl: webhooks[0].faction_webhook_url,
    factionEnabled: webhooks[0].faction_webhook_enabled === 1,
    adminUrl: webhooks[0].admin_webhook_url,
    adminEnabled: webhooks[0].admin_webhook_enabled === 1,
  }
}

/**
 * Send a webhook message to Discord
 */
async function sendToDiscord(webhookUrl: string, payload: WebhookPayload): Promise<boolean> {
  try {
    const response = await fetch(webhookUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload),
    })

    if (!response.ok) {
      console.error('[Webhook] Discord returned error:', response.status, await response.text())
      return false
    }

    return true
  } catch (error) {
    console.error('[Webhook] Failed to send:', error)
    return false
  }
}

/**
 * Log an action to the job panel database
 */
async function logAction(
  panelId: string,
  action: string,
  category: LogCategory,
  actorId: string | null,
  actorName: string | null,
  targetId: string | null,
  targetName: string | null,
  details: Record<string, unknown> | null,
  ipAddress: string | null
): Promise<void> {
  await queryJobPanelDb(
    `INSERT INTO job_panel_logs (id, panel_id, action, category, actor_id, actor_name, target_id, target_name, details, ip_address)
     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
    [
      uuidv4(),
      panelId,
      action,
      category,
      actorId,
      actorName,
      targetId,
      targetName,
      details ? JSON.stringify(details) : null,
      ipAddress,
    ]
  )
}

/**
 * Send a faction webhook notification
 */
export async function sendFactionWebhook(
  panelId: string,
  title: string,
  description: string,
  fields?: { name: string; value: string; inline?: boolean }[],
  color: number = EMBED_COLORS.INFO,
  actorName?: string
): Promise<boolean> {
  const { factionUrl, factionEnabled } = await getWebhookUrls(panelId)

  if (!factionEnabled || !factionUrl) {
    return false
  }

  // Get panel name for the embed
  const panels = await queryJobPanelDb<RowDataPacket[]>(
    'SELECT panel_name, job_label FROM job_panels WHERE id = ?',
    [panelId]
  )
  const panelName = panels[0]?.panel_name || 'Job Panel'

  const payload: WebhookPayload = {
    username: `${panelName} - Faction Log`,
    embeds: [{
      title,
      description,
      color,
      fields,
      timestamp: new Date().toISOString(),
      footer: {
        text: actorName ? `Action by: ${actorName}` : 'SKG UCP - Job Panel',
      },
    }],
  }

  return sendToDiscord(factionUrl, payload)
}

/**
 * Send an admin webhook notification
 */
export async function sendAdminWebhook(
  panelId: string,
  title: string,
  description: string,
  fields?: { name: string; value: string; inline?: boolean }[],
  color: number = EMBED_COLORS.ADMIN,
  actorName?: string
): Promise<boolean> {
  const { adminUrl, adminEnabled } = await getWebhookUrls(panelId)

  if (!adminEnabled || !adminUrl) {
    return false
  }

  // Get panel name for the embed
  const panels = await queryJobPanelDb<RowDataPacket[]>(
    'SELECT panel_name, job_label FROM job_panels WHERE id = ?',
    [panelId]
  )
  const panelName = panels[0]?.panel_name || 'Job Panel'

  const payload: WebhookPayload = {
    username: `${panelName} - Admin Log`,
    embeds: [{
      title,
      description,
      color,
      fields,
      timestamp: new Date().toISOString(),
      footer: {
        text: actorName ? `Admin Action by: ${actorName}` : 'SKG UCP - Admin Panel',
      },
    }],
  }

  return sendToDiscord(adminUrl, payload)
}

/**
 * Log and notify: Employee joined/removed
 */
export async function logEmployeeChange(
  panelId: string,
  action: 'HIRED' | 'FIRED' | 'PROMOTED' | 'DEMOTED',
  actorId: string,
  actorName: string,
  targetId: string,
  targetName: string,
  details: { newRank?: string; oldRank?: string; reason?: string },
  ipAddress?: string
): Promise<void> {
  // Log to database
  await logAction(panelId, `EMPLOYEE_${action}`, 'FACTION', actorId, actorName, targetId, targetName, details, ipAddress || null)

  // Send faction webhook
  const colorMap = {
    HIRED: EMBED_COLORS.SUCCESS,
    FIRED: EMBED_COLORS.ERROR,
    PROMOTED: EMBED_COLORS.INFO,
    DEMOTED: EMBED_COLORS.WARNING,
  }

  const titleMap = {
    HIRED: 'Employee Hired',
    FIRED: 'Employee Terminated',
    PROMOTED: 'Employee Promoted',
    DEMOTED: 'Employee Demoted',
  }

  const fields: { name: string; value: string; inline: boolean }[] = [
    { name: 'Employee', value: targetName, inline: true },
  ]

  if (details.newRank) {
    fields.push({ name: 'New Rank', value: details.newRank, inline: true })
  }
  if (details.oldRank) {
    fields.push({ name: 'Previous Rank', value: details.oldRank, inline: true })
  }
  if (details.reason) {
    fields.push({ name: 'Reason', value: details.reason, inline: false })
  }

  await sendFactionWebhook(
    panelId,
    titleMap[action],
    `${actorName} has ${action.toLowerCase()} ${targetName}`,
    fields,
    colorMap[action],
    actorName
  )
}

/**
 * Log and notify: Record created/edited
 */
export async function logRecordChange(
  panelId: string,
  action: 'CREATED' | 'EDITED' | 'DELETED',
  actorId: string,
  actorName: string,
  recordId: string,
  recordTitle: string,
  citizenName: string,
  details?: Record<string, unknown>,
  ipAddress?: string
): Promise<void> {
  await logAction(panelId, `RECORD_${action}`, 'FACTION', actorId, actorName, recordId, recordTitle, details || null, ipAddress || null)

  const colorMap = {
    CREATED: EMBED_COLORS.SUCCESS,
    EDITED: EMBED_COLORS.INFO,
    DELETED: EMBED_COLORS.ERROR,
  }

  await sendFactionWebhook(
    panelId,
    `Criminal Record ${action.charAt(0) + action.slice(1).toLowerCase()}`,
    `A criminal record has been ${action.toLowerCase()}`,
    [
      { name: 'Title', value: recordTitle, inline: true },
      { name: 'Citizen', value: citizenName, inline: true },
    ],
    colorMap[action],
    actorName
  )
}

/**
 * Log and notify: Admin actions (panel changes, leader assignments)
 */
export async function logAdminAction(
  panelId: string,
  action: string,
  actorId: string,
  actorName: string,
  description: string,
  details?: Record<string, unknown>,
  ipAddress?: string
): Promise<void> {
  await logAction(panelId, action, 'ADMIN', actorId, actorName, null, null, details || null, ipAddress || null)

  await sendAdminWebhook(
    panelId,
    `Admin Action: ${action.replace(/_/g, ' ')}`,
    description,
    details ? Object.entries(details).map(([key, value]) => ({
      name: key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()),
      value: String(value),
      inline: true,
    })) : undefined,
    EMBED_COLORS.ADMIN,
    actorName
  )
}

/**
 * Log duty status change
 */
export async function logDutyChange(
  panelId: string,
  citizenId: string,
  citizenName: string,
  action: 'CLOCK_IN' | 'CLOCK_OUT',
  sessionDuration?: number
): Promise<void> {
  await queryJobPanelDb(
    `INSERT INTO job_panel_duty_logs (id, panel_id, citizen_id, citizen_name, action, session_duration)
     VALUES (?, ?, ?, ?, ?, ?)`,
    [uuidv4(), panelId, citizenId, citizenName, action, sessionDuration || null]
  )

  const title = action === 'CLOCK_IN' ? 'Employee On Duty' : 'Employee Off Duty'
  const color = action === 'CLOCK_IN' ? EMBED_COLORS.SUCCESS : EMBED_COLORS.NEUTRAL

  const fields: { name: string; value: string; inline: boolean }[] = [
    { name: 'Employee', value: citizenName, inline: true },
    { name: 'Status', value: action === 'CLOCK_IN' ? 'On Duty' : 'Off Duty', inline: true },
  ]

  if (sessionDuration) {
    const hours = Math.floor(sessionDuration / 3600)
    const minutes = Math.floor((sessionDuration % 3600) / 60)
    fields.push({ name: 'Session Duration', value: `${hours}h ${minutes}m`, inline: true })
  }

  await sendFactionWebhook(panelId, title, `${citizenName} is now ${action === 'CLOCK_IN' ? 'on' : 'off'} duty`, fields, color)
}

/**
 * Test a webhook URL
 */
export async function testWebhook(webhookUrl: string, webhookType: WebhookType): Promise<{ success: boolean; error?: string }> {
  if (!webhookUrl) {
    return { success: false, error: 'No webhook URL provided' }
  }

  // Validate URL format
  if (!webhookUrl.startsWith('https://discord.com/api/webhooks/') && !webhookUrl.startsWith('https://discordapp.com/api/webhooks/')) {
    return { success: false, error: 'Invalid Discord webhook URL format' }
  }

  const payload: WebhookPayload = {
    username: `SKG UCP - ${webhookType === 'FACTION' ? 'Faction' : 'Admin'} Test`,
    embeds: [{
      title: 'Webhook Test',
      description: `This is a test message for the ${webhookType.toLowerCase()} webhook.`,
      color: webhookType === 'FACTION' ? EMBED_COLORS.INFO : EMBED_COLORS.ADMIN,
      timestamp: new Date().toISOString(),
      footer: {
        text: 'SKG UCP - Job Panel System',
      },
    }],
  }

  const success = await sendToDiscord(webhookUrl, payload)
  return success ? { success: true } : { success: false, error: 'Failed to send test message' }
}
