import { createCanvas, loadImage } from '@napi-rs/canvas';

export type RankCardInput = {
  displayName: string;
  avatarUrl: string;
  level: number;
  rank: number;
  intoLevel: number;
  needed: number;
  totalXp: number;
  accentColor: string;
  backgroundColor: string;
};

function parseHexColor(color: string, fallback: string): string {
  return /^#[0-9A-Fa-f]{6}$/.test(color) ? color : fallback;
}

export async function renderRankCard(input: RankCardInput): Promise<Buffer> {
  const width = 934;
  const height = 282;
  const canvas = createCanvas(width, height);
  const ctx = canvas.getContext('2d');

  const background = parseHexColor(input.backgroundColor, '#111827');
  const accent = parseHexColor(input.accentColor, '#6366F1');

  ctx.fillStyle = background;
  ctx.fillRect(0, 0, width, height);

  ctx.fillStyle = accent;
  ctx.fillRect(0, 0, width, 6);

  const avatarSize = 128;
  const avatarX = 36;
  const avatarY = 77;
  const avatar = await loadImage(input.avatarUrl);

  ctx.save();
  ctx.beginPath();
  ctx.arc(avatarX + avatarSize / 2, avatarY + avatarSize / 2, avatarSize / 2, 0, Math.PI * 2);
  ctx.closePath();
  ctx.clip();
  ctx.drawImage(avatar, avatarX, avatarY, avatarSize, avatarSize);
  ctx.restore();

  ctx.strokeStyle = accent;
  ctx.lineWidth = 4;
  ctx.beginPath();
  ctx.arc(avatarX + avatarSize / 2, avatarY + avatarSize / 2, avatarSize / 2 + 2, 0, Math.PI * 2);
  ctx.stroke();

  const textX = 200;
  ctx.fillStyle = '#F9FAFB';
  ctx.font = 'bold 32px sans-serif';
  const name = input.displayName.slice(0, 28);
  ctx.fillText(name, textX, 110);

  ctx.fillStyle = '#D1D5DB';
  ctx.font = '22px sans-serif';
  ctx.fillText(`Rank #${input.rank}`, textX, 145);
  ctx.fillText(`Level ${input.level}`, textX, 175);
  ctx.fillText(`${input.totalXp.toLocaleString()} XP`, textX, 205);

  const barX = 520;
  const barY = 120;
  const barWidth = 370;
  const barHeight = 28;
  const progress = input.needed > 0 ? Math.min(1, input.intoLevel / input.needed) : 0;

  ctx.fillStyle = '#1F2937';
  ctx.fillRect(barX, barY, barWidth, barHeight);

  if (progress > 0) {
    ctx.fillStyle = accent;
    ctx.fillRect(barX, barY, Math.max(1, barWidth * progress), barHeight);
  }

  ctx.fillStyle = '#E5E7EB';
  ctx.font = '18px sans-serif';
  ctx.fillText(`${input.intoLevel.toLocaleString()} / ${input.needed.toLocaleString()} XP`, barX, barY + 52);

  return canvas.toBuffer('image/png');
}
