import {
  EmbedBuilder,
  ActionRowBuilder,
  ButtonBuilder,
  ButtonStyle,
  type MessageCreateOptions,
} from 'discord.js';
import { PRIORITY_CONFIG, STAGE_DISPLAY, COLORS, type Priority } from '../config.js';
import type { Task } from '../api-client.js';

/**
 * Build the rich embed + button row for a pending approval request.
 * This is the primary interactive message posted to #factory-tasks.
 */
export function buildApprovalRequestEmbed(task: Task): MessageCreateOptions {
  const priority = task.priority as Priority;
  const pConfig = PRIORITY_CONFIG[priority];

  // Format stage transition
  const stageDisplay = task.stageName
    ? STAGE_DISPLAY[task.stageName] ?? task.stageName
    : 'Unknown';

  // Format test results if available
  const ctx = task.context;
  const testStr = ctx.testResults
    ? `${ctx.testResults.passed === ctx.testResults.total ? '✅' : '⚠️'} ${ctx.testResults.passed}/${ctx.testResults.total} passing`
    : 'N/A';
  const coverageStr = ctx.testResults
    ? `${ctx.testResults.coveragePercent >= 80 ? '✅' : '⚠️'} ${ctx.testResults.coveragePercent}%`
    : 'N/A';

  // Format wait time
  const waitMs = Date.now() - new Date(task.createdAt).getTime();
  const waitStr = formatDuration(waitMs);

  // Format SLA remaining
  let slaStr = 'No SLA';
  if (task.slaDeadline) {
    const remaining = new Date(task.slaDeadline).getTime() - Date.now();
    if (remaining <= 0) {
      slaStr = '🚨 **BREACHED**';
    } else if (remaining < 60 * 60 * 1000) {
      slaStr = `⚠️ ${formatDuration(remaining)} remaining`;
    } else {
      slaStr = `${formatDuration(remaining)} remaining`;
    }
  }

  // Changes summary
  const changesStr = ctx.diffSummary
    ? `${ctx.diffSummary.filesChanged} files (+${ctx.diffSummary.insertions} / -${ctx.diffSummary.deletions})`
    : 'N/A';

  const embed = new EmbedBuilder()
    .setTitle(`🔔 Approval Required`)
    .setDescription(
      `**${task.title}**\n\n${ctx.summary ?? task.description ?? ''}`,
    )
    .addFields(
      { name: 'Pipeline', value: task.pipelineId ?? 'N/A', inline: true },
      { name: 'Stage', value: stageDisplay, inline: true },
      { name: 'Priority', value: `${pConfig.emoji} ${pConfig.label}`, inline: true },
      { name: 'Tests', value: testStr, inline: true },
      { name: 'Coverage', value: coverageStr, inline: true },
      { name: 'Changes', value: changesStr, inline: true },
      { name: 'Waiting', value: `⏰ ${waitStr}`, inline: true },
      { name: 'SLA', value: slaStr, inline: true },
      { name: 'Type', value: formatTaskType(task.type), inline: true },
    )
    .setColor(task.slaBreached ? COLORS.slaBreach : pConfig.color)
    .setFooter({ text: `Task ID: ${task.id}` })
    .setTimestamp();

  const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents(
    new ButtonBuilder()
      .setCustomId(`approve:${task.id}`)
      .setLabel('✅ Approve')
      .setStyle(ButtonStyle.Success),
    new ButtonBuilder()
      .setCustomId(`reject:${task.id}`)
      .setLabel('❌ Reject')
      .setStyle(ButtonStyle.Danger),
    new ButtonBuilder()
      .setCustomId(`details:${task.id}`)
      .setLabel('📋 Details')
      .setStyle(ButtonStyle.Secondary),
    new ButtonBuilder()
      .setCustomId(`defer:${task.id}`)
      .setLabel('⏰ Defer')
      .setStyle(ButtonStyle.Secondary),
  );

  return { embeds: [embed], components: [buttons] };
}

/**
 * Build the "approved" embed that replaces the original when approved.
 */
export function buildApprovedEmbed(task: Task, approvedBy: string): MessageCreateOptions {
  const embed = new EmbedBuilder()
    .setTitle(`✅ Approved`)
    .setDescription(`**${task.title}**\n\nApproved by <@${approvedBy}>`)
    .addFields(
      { name: 'Pipeline', value: task.pipelineId ?? 'N/A', inline: true },
      { name: 'Stage', value: STAGE_DISPLAY[task.stageName ?? ''] ?? task.stageName ?? 'N/A', inline: true },
      { name: 'Decision', value: '✅ Approved', inline: true },
    )
    .setColor(COLORS.success)
    .setFooter({ text: `Task ID: ${task.id}` })
    .setTimestamp();

  return { embeds: [embed], components: [] };
}

/**
 * Build the "rejected" embed that replaces the original.
 */
export function buildRejectedEmbed(
  task: Task,
  rejectedBy: string,
  reason: string,
): MessageCreateOptions {
  const embed = new EmbedBuilder()
    .setTitle(`❌ Rejected`)
    .setDescription(
      `**${task.title}**\n\nRejected by <@${rejectedBy}>\n\n**Reason:** ${reason}`,
    )
    .addFields(
      { name: 'Pipeline', value: task.pipelineId ?? 'N/A', inline: true },
      { name: 'Stage', value: STAGE_DISPLAY[task.stageName ?? ''] ?? task.stageName ?? 'N/A', inline: true },
      { name: 'Decision', value: '❌ Rejected', inline: true },
    )
    .setColor(COLORS.danger)
    .setFooter({ text: `Task ID: ${task.id}` })
    .setTimestamp();

  return { embeds: [embed], components: [] };
}

/**
 * Build the "deferred" embed that replaces the original.
 */
export function buildDeferredEmbed(task: Task, deferredBy: string): MessageCreateOptions {
  const embed = new EmbedBuilder()
    .setTitle(`⏰ Deferred`)
    .setDescription(
      `**${task.title}**\n\nDeferred by <@${deferredBy}>`,
    )
    .addFields(
      { name: 'Pipeline', value: task.pipelineId ?? 'N/A', inline: true },
      { name: 'Stage', value: STAGE_DISPLAY[task.stageName ?? ''] ?? task.stageName ?? 'N/A', inline: true },
    )
    .setColor(COLORS.neutral)
    .setFooter({ text: `Task ID: ${task.id}` })
    .setTimestamp();

  return { embeds: [embed], components: [] };
}

// ─── Helpers ──────────────────────────────────

function formatDuration(ms: number): string {
  const totalMinutes = Math.floor(ms / 60_000);
  if (totalMinutes < 60) return `${totalMinutes}m`;
  const hours = Math.floor(totalMinutes / 60);
  const minutes = totalMinutes % 60;
  if (hours < 24) return `${hours}h ${minutes}m`;
  const days = Math.floor(hours / 24);
  return `${days}d ${hours % 24}h`;
}

function formatTaskType(type: string): string {
  const map: Record<string, string> = {
    approval: '🔒 Gate Approval',
    review: '👀 Code Review',
    decision: '🤔 Decision',
    manual_action: '🔧 Manual Action',
    fix_required: '🐛 Fix Required',
  };
  return map[type] ?? type;
}
