/**
 * cubeSkinFactories — фабрики текстур для GD-скинов куба.
 *
 * Каждый скин = функция (canvas, primary, secondary) которая рисует на canvas
 * 256×256 пикселей. Дальше canvas заворачивается в Babylon DynamicTexture
 * и накладывается на куб как diffuseTexture (одна и та же текстура на все
 * 6 граней — на куб смотрят с одного-двух ракурсов как в GD).
 *
 * primary/secondary — hex-цвета вида "#66ff66".
 * isAnimated — если true, фабрика умеет работать с time-параметром (для пульсации/glow).
 *
 * Базовые 10 скинов согласно RUBLOX_GD_SKINS.md §3.
 */

const SIZE = 256;
const PAD = 12;  // отступ от края (рамка)

// --- утилиты ---

function clear(ctx, color) {
  ctx.fillStyle = color;
  ctx.fillRect(0, 0, SIZE, SIZE);
}

function border(ctx, color, thickness = 8) {
  ctx.strokeStyle = color;
  ctx.lineWidth = thickness;
  const o = thickness / 2;
  ctx.strokeRect(o, o, SIZE - thickness, SIZE - thickness);
}

function filledRect(ctx, color, x, y, w, h) {
  ctx.fillStyle = color;
  ctx.fillRect(x, y, w, h);
}

function filledCircle(ctx, color, cx, cy, r) {
  ctx.fillStyle = color;
  ctx.beginPath();
  ctx.arc(cx, cy, r, 0, Math.PI * 2);
  ctx.fill();
}

function strokeCircle(ctx, color, cx, cy, r, thickness = 6) {
  ctx.strokeStyle = color;
  ctx.lineWidth = thickness;
  ctx.beginPath();
  ctx.arc(cx, cy, r, 0, Math.PI * 2);
  ctx.stroke();
}


// =====================================================================
// СКИН 1 — DEFAULT: простой куб с базовой рамкой и квадратом внутри.
// Имитирует "icon_01" из оригинального GD (плоское лицо)
// =====================================================================
function drawDefault(ctx, primary, secondary) {
  clear(ctx, primary);
  border(ctx, secondary, 12);
  // Глаза-квадраты
  filledRect(ctx, secondary, 70,  90, 36, 36);
  filledRect(ctx, secondary, 150, 90, 36, 36);
  // Рот — полоса
  filledRect(ctx, secondary, 80, 165, 96, 14);
}

// =====================================================================
// СКИН 2 — SMILE: широкая улыбка
// =====================================================================
function drawSmile(ctx, primary, secondary) {
  clear(ctx, primary);
  border(ctx, secondary, 12);
  // Глаза-круги
  filledCircle(ctx, secondary, 88,  100, 18);
  filledCircle(ctx, secondary, 168, 100, 18);
  // Улыбка — дуга
  ctx.strokeStyle = secondary;
  ctx.lineWidth = 10;
  ctx.lineCap = 'round';
  ctx.beginPath();
  ctx.arc(SIZE/2, 150, 50, 0.15 * Math.PI, 0.85 * Math.PI);
  ctx.stroke();
}

// =====================================================================
// СКИН 3 — SAD: грустный (рот дугой вниз, брови опущены)
// =====================================================================
function drawSad(ctx, primary, secondary) {
  clear(ctx, primary);
  border(ctx, secondary, 12);
  // Глаза прищуренные (овалы)
  ctx.fillStyle = secondary;
  ctx.beginPath();
  ctx.ellipse(88, 110, 18, 10, 0, 0, Math.PI * 2);
  ctx.ellipse(168, 110, 18, 10, 0, 0, Math.PI * 2);
  ctx.fill();
  // Брови — диагонали внутрь-вниз
  ctx.strokeStyle = secondary;
  ctx.lineWidth = 6;
  ctx.lineCap = 'round';
  ctx.beginPath();
  ctx.moveTo(68, 80);   ctx.lineTo(108, 95);
  ctx.moveTo(188, 80);  ctx.lineTo(148, 95);
  ctx.stroke();
  // Рот — обратная дуга
  ctx.beginPath();
  ctx.arc(SIZE/2, 210, 50, 1.15 * Math.PI, 1.85 * Math.PI);
  ctx.stroke();
}

// =====================================================================
// СКИН 4 — COOL: солнцезащитные очки
// =====================================================================
function drawCool(ctx, primary, secondary) {
  clear(ctx, primary);
  border(ctx, secondary, 12);
  // Очки — два прямоугольника соединённые перемычкой
  filledRect(ctx, '#000000', 50,  90, 60, 42);
  filledRect(ctx, '#000000', 146, 90, 60, 42);
  filledRect(ctx, '#000000', 110, 102, 36, 12);
  // Блик в очках (secondary)
  filledRect(ctx, secondary, 60,  98,  16, 8);
  filledRect(ctx, secondary, 156, 98,  16, 8);
  // Полуулыбка
  ctx.strokeStyle = secondary;
  ctx.lineWidth = 8;
  ctx.lineCap = 'round';
  ctx.beginPath();
  ctx.arc(SIZE/2, 170, 36, 0.1 * Math.PI, 0.9 * Math.PI);
  ctx.stroke();
}

// =====================================================================
// СКИН 5 — SKULL: череп
// =====================================================================
function drawSkull(ctx, primary, secondary) {
  clear(ctx, primary);
  border(ctx, secondary, 12);
  // Глазницы (большие чёрные круги)
  filledCircle(ctx, '#000', 90,  120, 32);
  filledCircle(ctx, '#000', 166, 120, 32);
  // Точки-зрачки (secondary)
  filledCircle(ctx, secondary, 90,  120, 8);
  filledCircle(ctx, secondary, 166, 120, 8);
  // Нос — треугольник
  ctx.fillStyle = '#000';
  ctx.beginPath();
  ctx.moveTo(SIZE/2,  165);
  ctx.lineTo(SIZE/2 - 10, 185);
  ctx.lineTo(SIZE/2 + 10, 185);
  ctx.closePath();
  ctx.fill();
  // Зубы — ряд квадратов
  for (let i = 0; i < 5; i++) {
    filledRect(ctx, '#000', 80 + i * 20, 200, 14, 18);
  }
}

// =====================================================================
// СКИН 6 — STAR: пятиконечная звезда
// =====================================================================
function drawStar(ctx, primary, secondary) {
  clear(ctx, primary);
  border(ctx, secondary, 12);
  // Звезда
  const cx = SIZE / 2;
  const cy = SIZE / 2;
  const rOuter = 70;
  const rInner = 30;
  ctx.fillStyle = secondary;
  ctx.beginPath();
  for (let i = 0; i < 10; i++) {
    const r = i % 2 === 0 ? rOuter : rInner;
    const a = (i / 10) * Math.PI * 2 - Math.PI / 2;
    const x = cx + r * Math.cos(a);
    const y = cy + r * Math.sin(a);
    if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
  }
  ctx.closePath();
  ctx.fill();
}

// =====================================================================
// СКИН 7 — FLAME: языки пламени (анимируется через time)
// =====================================================================
function drawFlame(ctx, primary, secondary, time = 0) {
  clear(ctx, primary);
  // Языки пламени снизу-вверх
  ctx.fillStyle = secondary;
  ctx.beginPath();
  ctx.moveTo(0, SIZE);
  for (let x = 0; x <= SIZE; x += 16) {
    // волна Y зависит от time для пульсации
    const wave = Math.sin((x / SIZE) * Math.PI * 4 + time * 3) * 22;
    const baseY = 110 + Math.cos((x / SIZE) * Math.PI * 2 + time * 2) * 18;
    ctx.lineTo(x, baseY + wave);
  }
  ctx.lineTo(SIZE, SIZE);
  ctx.closePath();
  ctx.fill();
  // Внутренние огоньки — белые точки
  const dots = 7;
  for (let i = 0; i < dots; i++) {
    const fx = 30 + (SIZE - 60) * (i / (dots - 1));
    const fy = 180 + Math.sin(time * 4 + i) * 15;
    filledCircle(ctx, '#ffffff', fx, fy, 6);
  }
  border(ctx, secondary, 8);
}

// =====================================================================
// СКИН 8 — ICE: ледяные кристаллы
// =====================================================================
function drawIce(ctx, primary, secondary) {
  clear(ctx, primary);
  border(ctx, secondary, 12);
  // Снежинка в центре — 6 лучей
  const cx = SIZE / 2;
  const cy = SIZE / 2;
  ctx.strokeStyle = secondary;
  ctx.lineWidth = 8;
  ctx.lineCap = 'round';
  for (let i = 0; i < 6; i++) {
    const a = (i / 6) * Math.PI * 2;
    const x = cx + 70 * Math.cos(a);
    const y = cy + 70 * Math.sin(a);
    ctx.beginPath();
    ctx.moveTo(cx, cy);
    ctx.lineTo(x, y);
    ctx.stroke();
    // маленькие веточки на каждом луче
    const bx1 = cx + 45 * Math.cos(a);
    const by1 = cy + 45 * Math.sin(a);
    ctx.beginPath();
    ctx.moveTo(bx1, by1);
    ctx.lineTo(bx1 + 12 * Math.cos(a + 0.5), by1 + 12 * Math.sin(a + 0.5));
    ctx.moveTo(bx1, by1);
    ctx.lineTo(bx1 + 12 * Math.cos(a - 0.5), by1 + 12 * Math.sin(a - 0.5));
    ctx.stroke();
  }
  // центральный кристалл
  filledCircle(ctx, secondary, cx, cy, 12);
}

// =====================================================================
// СКИН 9 — PIZZA: ломтик пиццы (треугольник с начинкой)
// =====================================================================
function drawPizza(ctx, primary, secondary) {
  clear(ctx, primary);
  border(ctx, secondary, 12);
  // Корка (треугольник) — золотисто-коричневый
  ctx.fillStyle = '#d4a572';
  ctx.beginPath();
  ctx.moveTo(SIZE/2, 50);
  ctx.lineTo(40, 210);
  ctx.lineTo(216, 210);
  ctx.closePath();
  ctx.fill();
  // Сыр сверху
  ctx.fillStyle = '#ffe066';
  ctx.beginPath();
  ctx.moveTo(SIZE/2, 70);
  ctx.lineTo(58, 200);
  ctx.lineTo(198, 200);
  ctx.closePath();
  ctx.fill();
  // Пепперони
  filledCircle(ctx, '#cc3333', SIZE/2, 120, 15);
  filledCircle(ctx, '#cc3333', SIZE/2 - 30, 160, 13);
  filledCircle(ctx, '#cc3333', SIZE/2 + 30, 160, 13);
  filledCircle(ctx, '#cc3333', SIZE/2 - 50, 195, 11);
  filledCircle(ctx, '#cc3333', SIZE/2 + 50, 195, 11);
  filledCircle(ctx, '#cc3333', SIZE/2,      195, 12);
}

// =====================================================================
// СКИН 10 — CAT: морда кота с ушами и усами
// =====================================================================
function drawCat(ctx, primary, secondary, time = 0) {
  clear(ctx, primary);
  border(ctx, secondary, 12);
  // Уши — два треугольника сверху
  ctx.fillStyle = secondary;
  ctx.beginPath();
  ctx.moveTo(40, 50);  ctx.lineTo(78, 30);  ctx.lineTo(95, 75);  ctx.closePath();
  ctx.moveTo(216, 50); ctx.lineTo(178, 30); ctx.lineTo(161, 75); ctx.closePath();
  ctx.fill();
  // Внутренняя розовая часть ушей
  ctx.fillStyle = '#ff99cc';
  ctx.beginPath();
  ctx.moveTo(60, 52);  ctx.lineTo(78, 42);  ctx.lineTo(82, 65);  ctx.closePath();
  ctx.moveTo(196, 52); ctx.lineTo(178, 42); ctx.lineTo(174, 65); ctx.closePath();
  ctx.fill();
  // Глаза (моргание — time-based)
  const blink = Math.sin(time * 0.8) > 0.96 ? 0.15 : 1.0;
  ctx.fillStyle = secondary;
  ctx.beginPath();
  ctx.ellipse(88, 130, 18, 22 * blink, 0, 0, Math.PI * 2);
  ctx.ellipse(168, 130, 18, 22 * blink, 0, 0, Math.PI * 2);
  ctx.fill();
  // Зрачки-щёлки (если глаза открыты)
  if (blink > 0.5) {
    ctx.fillStyle = '#000';
    ctx.beginPath();
    ctx.ellipse(88, 130, 5, 18, 0, 0, Math.PI * 2);
    ctx.ellipse(168, 130, 5, 18, 0, 0, Math.PI * 2);
    ctx.fill();
  }
  // Нос — треугольник
  ctx.fillStyle = '#ff99cc';
  ctx.beginPath();
  ctx.moveTo(SIZE/2 - 10, 168);
  ctx.lineTo(SIZE/2 + 10, 168);
  ctx.lineTo(SIZE/2,      182);
  ctx.closePath();
  ctx.fill();
  // Рот — w-образный
  ctx.strokeStyle = secondary;
  ctx.lineWidth = 4;
  ctx.lineCap = 'round';
  ctx.beginPath();
  ctx.moveTo(SIZE/2, 182);
  ctx.lineTo(SIZE/2, 195);
  ctx.moveTo(SIZE/2, 195);
  ctx.quadraticCurveTo(SIZE/2 - 15, 210, SIZE/2 - 22, 200);
  ctx.moveTo(SIZE/2, 195);
  ctx.quadraticCurveTo(SIZE/2 + 15, 210, SIZE/2 + 22, 200);
  ctx.stroke();
  // Усы
  ctx.lineWidth = 2.5;
  ctx.beginPath();
  ctx.moveTo(50, 175);  ctx.lineTo(105, 180);
  ctx.moveTo(50, 188);  ctx.lineTo(105, 188);
  ctx.moveTo(206, 175); ctx.lineTo(151, 180);
  ctx.moveTo(206, 188); ctx.lineTo(151, 188);
  ctx.stroke();
}


// =====================================================================
// РЕЕСТР СКИНОВ
// =====================================================================

export const CUBE_SKINS = [
  { id: 'cube_default', title: 'Базовый',     category: 'Базовый',    priceStars: 0,   draw: drawDefault, animated: false },
  { id: 'cube_smile',   title: 'Улыбка',      category: 'Эмоция',     priceStars: 5,   draw: drawSmile,   animated: false },
  { id: 'cube_sad',     title: 'Грустный',    category: 'Эмоция',     priceStars: 5,   draw: drawSad,     animated: false },
  { id: 'cube_cool',    title: 'В очках',     category: 'Эмоция',     priceStars: 10,  draw: drawCool,    animated: false },
  { id: 'cube_skull',   title: 'Череп',       category: 'Базовый',    priceStars: 10,  draw: drawSkull,   animated: false },
  { id: 'cube_star',    title: 'Звезда',      category: 'Базовый',    priceStars: 10,  draw: drawStar,    animated: false },
  { id: 'cube_flame',   title: 'Пламя',       category: 'Тематический', priceStars: 20, draw: drawFlame,  animated: true },
  { id: 'cube_ice',     title: 'Лёд',         category: 'Тематический', priceStars: 20, draw: drawIce,    animated: false },
  { id: 'cube_pizza',   title: 'Пицца',       category: 'Тематический', priceStars: 15, draw: drawPizza,  animated: false },
  { id: 'cube_cat',     title: 'Кошка',       category: 'Тематический', priceStars: 15, draw: drawCat,    animated: true },
];

// =====================================================================
// TRAIL-эффекты (параметры для Babylon ParticleSystem, без canvas)
// =====================================================================
export const CUBE_TRAILS = [
  {
    id: 'trail_white', title: 'Белый', priceStars: 0,
    params: { colorStart: '#ffffff', colorEnd: '#aaaaaa', emissionRate: 30, lifetime: 0.6, sizeStart: 0.18 },
  },
  {
    id: 'trail_fire',  title: 'Огонь',  priceStars: 25,
    params: { colorStart: '#ff6600', colorEnd: '#ffe44a', emissionRate: 50, lifetime: 0.9, sizeStart: 0.22 },
  },
  {
    id: 'trail_rainbow', title: 'Радуга', priceStars: 50,
    params: { colorStart: 'rainbow', colorEnd: '#ffffff', emissionRate: 60, lifetime: 1.0, sizeStart: 0.20 },
  },
];

// Базовая палитра цветов (18 как в GD, см. SKINS.md §4)
export const SKIN_COLORS = [
  { id: 'green',    hex: '#66ff66', priceStars: 0,    title: 'Зелёный' },
  { id: 'red',      hex: '#ff4444', priceStars: 0,    title: 'Красный' },
  { id: 'blue',     hex: '#4488ff', priceStars: 0,    title: 'Синий' },
  { id: 'yellow',   hex: '#ffe44a', priceStars: 10,   title: 'Жёлтый' },
  { id: 'purple',   hex: '#b266ff', priceStars: 10,   title: 'Фиолетовый' },
  { id: 'orange',   hex: '#ff9533', priceStars: 10,   title: 'Оранжевый' },
  { id: 'pink',     hex: '#ff66cc', priceStars: 20,   title: 'Розовый' },
  { id: 'cyan',     hex: '#44ddcc', priceStars: 20,   title: 'Бирюзовый' },
  { id: 'lime',     hex: '#aaff44', priceStars: 20,   title: 'Лайм' },
  { id: 'black',    hex: '#222222', priceStars: 30,   title: 'Чёрный' },
  { id: 'white',    hex: '#f0f0f0', priceStars: 30,   title: 'Белый' },
  { id: 'silver',   hex: '#cccccc', priceStars: 50,   title: 'Серебро' },
  { id: 'gold',     hex: '#ffd700', priceStars: 100,  title: 'Золото' },
];

export const DEFAULT_PRIMARY = '#66ff66';
export const DEFAULT_SECONDARY = '#44aa44';

/**
 * Перерисовать canvas со скином.
 * Принимает HTMLCanvasElement, id скина, цвета и опциональное время.
 */
export function renderSkin(canvas, skinId, primary = DEFAULT_PRIMARY, secondary = DEFAULT_SECONDARY, time = 0) {
  const skin = CUBE_SKINS.find(s => s.id === skinId);
  if (!skin) return;
  const ctx = canvas.getContext('2d');
  ctx.imageSmoothingEnabled = false;
  skin.draw(ctx, primary, secondary, time);
}
