import { mkdirSync, writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const outDir = join(__dirname, '..', 'public', 'prototypes');

const W = 1440;
const C = {
  page: '#f4f4f4',
  paper: '#ffffff',
  panel: '#ffffff',
  soft: '#f7f7f7',
  line: '#d5d5d5',
  dark: '#181818',
  mid: '#545454',
  muted: '#777777',
  fill: '#e8e8e8',
  fill2: '#f0f0f0',
};
const font = '"Times New Roman", Times, serif';

function esc(value) {
  return String(value)
    .replaceAll('&', '&amp;')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;');
}

function attrs(values) {
  return Object.entries(values)
    .filter(([, value]) => value !== undefined && value !== null)
    .map(([key, value]) => `${key}="${esc(value)}"`)
    .join(' ');
}

function rect(x, y, width, height, options = {}) {
  const {
    rx = 18,
    fill = C.panel,
    stroke = C.line,
    sw = 1.5,
  } = options;

  return `<rect ${attrs({ x, y, width, height, rx, fill, stroke, 'stroke-width': sw })} />`;
}

function line(x1, y1, x2, y2, options = {}) {
  return `<line ${attrs({
    x1,
    y1,
    x2,
    y2,
    stroke: options.stroke ?? C.line,
    'stroke-width': options.sw ?? 1.5,
  })} />`;
}

function text(x, y, value, options = {}) {
  const {
    size = 16,
    weight = 500,
    fill = C.dark,
    anchor = 'start',
  } = options;

  return `<text ${attrs({
    x,
    y,
    'font-family': font,
    'font-size': size,
    'font-weight': weight,
    fill,
    'text-anchor': anchor,
  })}>${esc(value)}</text>`;
}

function circle(cx, cy, r, options = {}) {
  return `<circle ${attrs({
    cx,
    cy,
    r,
    fill: options.fill ?? C.fill,
    stroke: options.stroke,
    'stroke-width': options.sw,
  })} />`;
}

function chip(x, y, value, options = {}) {
  const width = options.width ?? Math.max(76, value.length * 9 + 28);
  const selected = options.selected ?? false;
  return [
    rect(x, y, width, 34, {
      rx: 17,
      fill: selected ? C.dark : C.soft,
      stroke: selected ? C.dark : C.line,
    }),
    text(x + width / 2, y + 22, value, {
      size: 13,
      weight: 700,
      fill: selected ? '#ffffff' : C.mid,
      anchor: 'middle',
    }),
  ].join('');
}

function input(x, y, width, label) {
  return [
    text(x, y - 12, label, { size: 13, weight: 700, fill: C.mid }),
    rect(x, y, width, 48, { rx: 16, fill: C.paper }),
  ].join('');
}

function button(x, y, width, label, options = {}) {
  const dark = options.dark ?? false;
  return [
    rect(x, y, width, 44, {
      rx: 22,
      fill: dark ? C.dark : C.fill,
      stroke: dark ? C.dark : C.line,
    }),
    text(x + width / 2, y + 28, label, {
      size: 14,
      weight: 700,
      fill: dark ? '#ffffff' : C.mid,
      anchor: 'middle',
    }),
  ].join('');
}

function topShell(label, nav = [], active = '') {
  const parts = [
    rect(24, 24, 1392, 56, { rx: 28, fill: '#fafafa' }),
    rect(24, 52, 1392, 28, { rx: 0, fill: '#fafafa', stroke: '#fafafa' }),
    circle(58, 52, 7, { fill: '#b7b7b7' }),
    circle(82, 52, 7, { fill: '#d2d2d2' }),
    circle(106, 52, 7, { fill: '#d4d4d4' }),
    text(136, 58, label, { size: 17, weight: 700 }),
  ];

  let x = 820;
  for (const item of nav) {
    parts.push(chip(x, 36, item, { width: Math.max(88, item.length * 10 + 34), selected: item === active }));
    x += Math.max(88, item.length * 10 + 34) + 12;
  }

  return parts.join('');
}

function page(label, height, body, options = {}) {
  const nav = options.nav ?? ['Каталог', 'Мои заказы', 'Корзина', 'Профиль'];
  const active = options.active ?? '';
  return `<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${height}" viewBox="0 0 ${W} ${height}" fill="none"><rect width="${W}" height="${height}" fill="${C.page}" />${rect(24, 24, 1392, height - 48, { rx: 28, fill: C.paper })}${topShell(label, nav, active)}${body.join('')}</svg>`;
}

function titleBlock(title, y = 132, x = 72) {
  return text(x, y, title, { size: 32, weight: 800 });
}

function searchHero(title, placeholder, controls = []) {
  const parts = [
    titleBlock(title),
    rect(72, 168, 600, 54, { rx: 27, fill: C.paper }),
    text(98, 201, placeholder, { size: 15, weight: 500, fill: C.muted }),
  ];
  let x = 700;
  for (const control of controls) {
    parts.push(chip(x, 178, control, { width: Math.max(120, control.length * 9 + 34), selected: control === controls[0] }));
    x += Math.max(120, control.length * 9 + 34) + 12;
  }
  return parts.join('');
}

function catalogCards(y = 260) {
  const cards = ['Стретч-пленка', 'Скотч', 'Пакеты', 'Пленка ПВД', 'Воздушно-пузырьковая', 'Картон'];
  const parts = [];
  cards.forEach((name, index) => {
    const col = index % 3;
    const row = Math.floor(index / 3);
    const x = 72 + col * 432;
    const yy = y + row * 238;
    parts.push(rect(x, yy, 396, 202, { rx: 26 }));
    parts.push(rect(x + 20, yy + 20, 356, 118, { rx: 22, fill: C.fill2 }));
    parts.push(text(x + 28, yy + 170, name, { size: 22, weight: 800 }));
  });
  return parts.join('');
}

function orderRows(x, y, width, rows, options = {}) {
  const parts = [];
  const rowH = options.rowH ?? 72;
  rows.forEach((row, index) => {
    const yy = y + index * (rowH + 12);
    parts.push(rect(x, yy, width, rowH, { rx: 20, fill: index % 2 ? '#fbfbfb' : C.paper }));
    parts.push(text(x + 24, yy + 30, row[0], { size: 17, weight: 800 }));
    parts.push(text(x + 24, yy + 54, row[1], { size: 14, weight: 500, fill: C.mid }));
    if (row[2]) {
      parts.push(chip(x + width - 210, yy + 18, row[2], { width: 150 }));
    }
  });
  return parts.join('');
}

function cardGrid(x, y, labels, columns = 3) {
  const parts = [];
  labels.forEach((label, index) => {
    const col = index % columns;
    const row = Math.floor(index / columns);
    const w = columns === 4 ? 300 : 388;
    const xx = x + col * (w + 24);
    const yy = y + row * 128;
    parts.push(rect(xx, yy, w, 104, { rx: 24 }));
    parts.push(circle(xx + 44, yy + 52, 24, { fill: C.fill2 }));
    parts.push(text(xx + 82, yy + 48, label[0], { size: 17, weight: 800 }));
    if (label[1]) {
      parts.push(text(xx + 82, yy + 72, label[1], { size: 14, weight: 500, fill: C.mid }));
    }
  });
  return parts.join('');
}

const pages = {
  'dashboard.svg': page('Главная страница клиента', 900, [
    searchHero('Каталог', 'Поиск по типу товара', []),
    catalogCards(260),
  ], { active: 'Каталог' }),

  'catalog-grid.svg': page('Каталог продукции', 900, [
    searchHero('Каталог', 'Поиск по типу товара', []),
    catalogCards(260),
  ], { active: 'Каталог' }),

  'product-card.svg': page('Карточка товара', 1040, [
    button(72, 116, 110, 'Назад'),
    titleBlock('Алюминиевый скотч', 166),
    rect(72, 220, 400, 330, { rx: 32 }),
    rect(102, 252, 340, 228, { rx: 26, fill: C.fill2 }),
    text(272, 510, 'Изображение товара', { size: 16, weight: 700, fill: C.mid, anchor: 'middle' }),
    rect(504, 220, 536, 330, { rx: 32 }),
    text(536, 258, 'Параметры', { size: 22, weight: 800 }),
    text(536, 304, 'Ширина', { size: 14, weight: 700, fill: C.mid }),
    chip(536, 320, '48 мм', { selected: true }),
    chip(628, 320, '75 мм'),
    text(780, 304, 'Длина', { size: 14, weight: 700, fill: C.mid }),
    chip(780, 320, '25 м', { selected: true }),
    chip(862, 320, '50 м'),
    chip(944, 320, '100 м'),
    text(536, 386, 'Толщина', { size: 14, weight: 700, fill: C.mid }),
    chip(536, 402, '43 мкм', { selected: true }),
    chip(638, 402, '45 мкм'),
    text(780, 386, 'Втулка', { size: 14, weight: 700, fill: C.mid }),
    chip(780, 402, 'Стандарт', { selected: true, width: 112 }),
    chip(904, 402, 'Логотип', { width: 104 }),
    text(536, 468, 'Цвет', { size: 14, weight: 700, fill: C.mid }),
    chip(536, 484, 'Серебристый', { selected: true, width: 126 }),
    text(780, 468, 'Надпись', { size: 14, weight: 700, fill: C.mid }),
    chip(780, 484, 'Без надписи', { selected: true, width: 136 }),
    rect(1072, 220, 296, 330, { rx: 32 }),
    text(1100, 262, 'FRG-ALU-48-50', { size: 20, weight: 800 }),
    text(1100, 310, 'В наличии', { size: 16, weight: 700, fill: C.mid }),
    text(1100, 342, '2 140', { size: 38, weight: 800 }),
    button(1100, 394, 220, 'В корзину', { dark: true }),
    text(72, 624, 'Доступные варианты', { size: 24, weight: 800 }),
    rect(72, 652, 1296, 258, { rx: 24 }),
    text(104, 698, 'SKU', { size: 14, weight: 800, fill: C.mid }),
    text(312, 698, 'Ширина', { size: 14, weight: 800, fill: C.mid }),
    text(470, 698, 'Длина', { size: 14, weight: 800, fill: C.mid }),
    text(620, 698, 'Толщина', { size: 14, weight: 800, fill: C.mid }),
    text(790, 698, 'Втулка', { size: 14, weight: 800, fill: C.mid }),
    text(970, 698, 'Остаток', { size: 14, weight: 800, fill: C.mid }),
    text(1160, 698, 'Действие', { size: 14, weight: 800, fill: C.mid }),
    line(96, 716, 1344, 716),
    orderRows(96, 738, 1248, [
      ['FRG-ALU-48-50', '48 мм · 50 м · 43 мкм · стандарт', 'В корзину'],
      ['FRG-ALU-75-50', '75 мм · 50 м · 45 мкм · стандарт', 'В корзину'],
    ], { rowH: 64 }),
  ], { active: 'Каталог' }),

  'cart.svg': page('Корзина', 900, [
    titleBlock('Корзина'),
    rect(72, 168, 1296, 68, { rx: 24, fill: C.soft }),
    text(102, 210, 'Заполните карточку контрагента перед оформлением заявки', { size: 16, weight: 700, fill: C.mid }),
    text(72, 284, 'Состав заказа', { size: 24, weight: 800 }),
    rect(72, 312, 760, 330, { rx: 28 }),
    orderRows(104, 344, 696, [
      ['Стретч-пленка', '48 мм · 50 м · 43 мкм', '2 шт'],
      ['Скотч упаковочный', '75 мм · 66 м', '4 шт'],
      ['Пакет ПВД', '300 x 400 мм', '1 шт'],
    ], { rowH: 72 }),
    rect(872, 312, 496, 330, { rx: 28 }),
    text(904, 354, 'Информация о доставке', { size: 22, weight: 800 }),
    chip(904, 390, 'Склад клиента', { selected: true, width: 160 }),
    chip(904, 444, 'Новый адрес', { width: 148 }),
    input(904, 532, 380, 'Комментарий'),
    button(904, 610, 260, 'Оформить заявку', { dark: true }),
  ], { active: 'Корзина' }),

  'client-order.svg': page('Карточка заказа клиента', 860, [
    button(72, 116, 190, 'Назад к моим заказам'),
    titleBlock('Заказ FRG-1024', 170),
    rect(72, 220, 1296, 118, { rx: 28 }),
    text(104, 262, 'Статус заказа', { size: 16, weight: 700, fill: C.mid }),
    chip(104, 282, 'Предложение', { selected: true, width: 148 }),
    chip(282, 282, 'Подтвердить', { width: 150 }),
    chip(456, 282, 'Отклонить', { width: 130 }),
    text(72, 394, 'Состав заказа', { size: 24, weight: 800 }),
    rect(72, 426, 1296, 260, { rx: 28 }),
    orderRows(104, 458, 1232, [
      ['Стретч-пленка', '48 мм · 50 м · количество 2', 'Цена задана'],
      ['Скотч упаковочный', '75 мм · 66 м · количество 4', 'Цена задана'],
    ], { rowH: 76 }),
    rect(72, 720, 1296, 80, { rx: 24, fill: C.soft }),
    text(104, 754, 'Доставка', { size: 17, weight: 800 }),
    text(260, 754, 'Адрес, срок и стоимость доставки показываются в одной строке', { size: 15, weight: 500, fill: C.mid }),
  ], { active: 'Мои заказы' }),

  'login.svg': page('Логин', 760, [
    rect(450, 130, 540, 520, { rx: 32 }),
    text(720, 196, 'Фрегат', { size: 14, weight: 800, fill: C.mid, anchor: 'middle' }),
    text(720, 244, 'Вход', { size: 36, weight: 800, anchor: 'middle' }),
    input(510, 304, 420, 'E-mail'),
    button(510, 386, 420, 'Получить код', { dark: true }),
    line(510, 464, 930, 464),
    text(720, 492, 'или войти через', { size: 13, weight: 700, fill: C.mid, anchor: 'middle' }),
    button(510, 526, 196, 'Telegram'),
    button(734, 526, 196, 'Max'),
  ], { nav: [] }),

  'bonus-cabinet.svg': page('Бонусный кабинет', 940, [
    titleBlock('Чёрный кабинет бонусной программы'),
    rect(72, 178, 820, 250, { rx: 30 }),
    text(112, 230, 'Аккаунт', { size: 15, weight: 700, fill: C.mid }),
    text(112, 280, 'Клиент бонусной программы', { size: 32, weight: 800, fill: C.dark }),
    text(112, 354, 'Доступный баланс', { size: 15, weight: 700, fill: C.mid }),
    text(112, 398, '12 400', { size: 48, weight: 800, fill: C.dark }),
    rect(928, 178, 440, 250, { rx: 30 }),
    text(968, 230, 'Вывод бонусов', { size: 20, weight: 800, fill: C.dark }),
    input(968, 292, 320, 'Сумма заявки'),
    button(968, 370, 280, 'Подать заявку', { dark: false }),
    rect(72, 472, 620, 300, { rx: 30 }),
    text(112, 522, 'История бонусов', { size: 24, weight: 800, fill: C.dark }),
    orderRows(112, 552, 540, [
      ['+1 500', 'Начисление по заказу', ''],
      ['+900', 'Реферальное начисление', ''],
    ], { rowH: 68 }),
    rect(748, 472, 620, 300, { rx: 30 }),
    text(788, 522, 'Вознаграждения', { size: 24, weight: 800, fill: C.dark }),
    button(788, 566, 170, 'Ozon 3000'),
    button(980, 566, 210, 'Wildberries 4000'),
    button(788, 634, 190, 'М.Видео 5000'),
  ], { active: 'Профиль' }),

  'client-list.svg': page('Клиенты', 900, [
    searchHero('Клиенты', 'Имя, компания или email', ['Пригласить']),
    cardGrid(72, 270, [
      ['Иван Петров', 'ООО Альфа'],
      ['Мария Соколова', 'ИП Соколова'],
      ['Дмитрий Иванов', 'ООО Север'],
      ['Анна Смирнова', 'ООО Вектор'],
      ['Павел Морозов', 'Завод Мир'],
      ['Елена Орлова', 'ТД Орлова'],
    ], 3),
  ], { nav: ['Заказы', 'Бонусы', 'Настройки'], active: 'Заказы' }),

  'client-card.svg': page('Карточка клиента', 880, [
    button(72, 116, 170, 'Назад к клиентам'),
    titleBlock('Клиент Иван Петров', 170),
    cardGrid(72, 224, [
      ['Email', 'client@company.ru'],
      ['Telegram', 'Подключен'],
      ['Компания', 'ООО Альфа'],
      ['ИНН', '7700000000'],
    ], 4),
    text(72, 500, 'Заказы пользователя', { size: 24, weight: 800 }),
    rect(72, 532, 1296, 240, { rx: 28 }),
    orderRows(104, 564, 1232, [
      ['FRG-1024', 'Стретч-пленка · Москва', 'В работе'],
      ['FRG-1017', 'Скотч · Санкт-Петербург', 'Завершен'],
    ], { rowH: 72 }),
  ], { nav: ['Заказы', 'Бонусы', 'Настройки'], active: 'Заказы' }),

  'manager-order.svg': page('Обработка заявки', 900, [
    button(72, 116, 170, 'Назад к заказам'),
    titleBlock('Заказ FRG-1024', 170),
    rect(72, 220, 1296, 118, { rx: 28 }),
    text(104, 262, 'Статус заказа', { size: 16, weight: 700, fill: C.mid }),
    chip(104, 282, 'В обработке', { selected: true, width: 148 }),
    chip(282, 282, 'Предложение', { width: 150 }),
    rect(72, 382, 920, 300, { rx: 28 }),
    text(104, 426, 'Состав заказа', { size: 24, weight: 800 }),
    orderRows(104, 460, 856, [
      ['Стретч-пленка', 'Количество 2 · цена редактируется', 'Цена'],
      ['Скотч упаковочный', 'Количество 4 · цена редактируется', 'Цена'],
    ], { rowH: 76 }),
    rect(1028, 382, 340, 300, { rx: 28 }),
    text(1060, 426, 'Условия', { size: 24, weight: 800 }),
    input(1060, 484, 250, 'Срок доставки'),
    input(1060, 578, 250, 'Стоимость доставки'),
    button(1060, 650, 230, 'Сохранить', { dark: true }),
  ], { nav: ['Заказы', 'Бонусы', 'Настройки'], active: 'Заказы' }),

  'manager-orders.svg': page('Заказы менеджера', 920, [
    searchHero('Заказы', 'Номер заказа, клиент, адрес или товар', ['Список', 'Календарь']),
    chip(72, 250, 'Все', { selected: true, width: 88 }),
    chip(174, 250, 'Заявки', { width: 112 }),
    chip(300, 250, 'Предложения', { width: 150 }),
    chip(464, 250, 'В работе', { width: 126 }),
    chip(604, 250, 'Закрытые', { width: 126 }),
    rect(72, 320, 1296, 430, { rx: 30 }),
    orderRows(104, 356, 1232, [
      ['FRG-1024', 'Иван Петров · Стретч-пленка · Москва', 'Заявка'],
      ['FRG-1025', 'Мария Соколова · Скотч · Казань', 'Предложение'],
      ['FRG-1026', 'Дмитрий Иванов · Пакеты · СПб', 'В работе'],
      ['FRG-1027', 'Анна Смирнова · Пленка ПВД · Москва', 'Закрыт'],
    ], { rowH: 76 }),
  ], { nav: ['Заказы', 'Бонусы', 'Настройки'], active: 'Заказы' }),

  'catalog-settings.svg': page('Настройки каталога', 980, [
    titleBlock('Каталог'),
    rect(72, 184, 1296, 104, { rx: 28 }),
    text(104, 226, 'Стретч-пленка', { size: 22, weight: 800 }),
    text(104, 256, '6 параметров, 3 кастомные возможности', { size: 15, weight: 500, fill: C.mid }),
    rect(72, 318, 1296, 446, { rx: 28 }),
    text(104, 362, 'Кастомные возможности', { size: 22, weight: 800 }),
    chip(104, 390, 'Любая длина', { selected: true, width: 140 }),
    chip(262, 390, 'Логотип на втулке', { width: 190 }),
    chip(470, 390, 'Нанесение надписи', { width: 200 }),
    text(104, 478, 'Диапазон длины', { size: 18, weight: 800 }),
    input(104, 520, 240, 'Мин. длина, м'),
    input(378, 520, 240, 'Макс. длина, м'),
    input(652, 520, 240, 'Шаг, м'),
    text(104, 638, 'Параметры', { size: 18, weight: 800 }),
    chip(104, 664, 'Ширина', { width: 110 }),
    chip(232, 664, 'Длина', { width: 100 }),
    chip(350, 664, 'Толщина', { width: 120 }),
    chip(488, 664, 'Втулка', { width: 108 }),
    chip(614, 664, 'Цвет', { width: 96 }),
    chip(728, 664, 'Надпись', { width: 120 }),
    button(1100, 804, 190, 'Сохранить', { dark: true }),
  ], { nav: ['Заказы', 'Бонусы', 'Настройки'], active: 'Настройки' }),

  'sync-settings.svg': page('Настройки синхронизации', 900, [
    titleBlock('1С'),
    text(72, 168, 'Статус загрузки файлов обмена', { size: 16, weight: 500, fill: C.mid }),
    cardGrid(72, 230, [
      ['counterparties_snapshot', 'Контрагенты'],
      ['catalog_snapshot', 'Каталог и остатки'],
      ['balances_snapshot', 'Задолженность клиентов'],
      ['orders_snapshot', 'Заказы клиентов'],
    ], 4),
    rect(72, 450, 1296, 250, { rx: 28 }),
    text(104, 494, 'Последние загрузки', { size: 24, weight: 800 }),
    orderRows(104, 530, 1232, [
      ['Контрагенты', 'Загружены реквизиты и признаки доступа', 'Работает'],
      ['Каталог и остатки', 'Загружено 2 418 записей · последний run сегодня', 'Работает'],
      ['Задолженность клиентов', 'Баланс по клиентам с личным кабинетом', 'Работает'],
      ['Заказы клиентов', 'Статусы заказов за рабочий период', 'Работает'],
    ], { rowH: 62 }),
  ], { nav: ['Заказы', 'Бонусы', 'Настройки'], active: 'Настройки' }),

  'profile.svg': page('Профиль клиента', 820, [
    titleBlock('Профиль'),
    cardGrid(72, 210, [
      ['Карточка контрагента', 'Реквизиты и ИНН'],
      ['Уведомления', 'Telegram и Max'],
      ['Адреса доставки', 'Список адресов'],
    ], 3),
  ], { active: 'Профиль' }),

  'bonus-manager.svg': page('Бонусная система менеджера', 920, [
    searchHero('Бонусы', 'Клиент, связанный клиент или email', ['Добавить']),
    chip(72, 250, 'Балансы', { selected: true, width: 120 }),
    chip(208, 250, 'Заявки', { width: 110 }),
    chip(334, 250, 'Награды', { width: 116 }),
    cardGrid(72, 320, [
      ['Иван Петров', '12 400 ₽'],
      ['Мария Соколова', '8 250 ₽'],
      ['Дмитрий Иванов', '5 100 ₽'],
      ['Анна Смирнова', '2 900 ₽'],
    ], 4),
    rect(72, 610, 1296, 170, { rx: 28 }),
    text(104, 654, 'Заявки на выплату', { size: 24, weight: 800 }),
    orderRows(104, 686, 1232, [
      ['WD-01A23F', 'Иван Петров · на проверке', '12 000 ₽'],
    ], { rowH: 68 }),
  ], { nav: ['Заказы', 'Бонусы', 'Настройки'], active: 'Бонусы' }),
};

mkdirSync(outDir, { recursive: true });
for (const [fileName, content] of Object.entries(pages)) {
  writeFileSync(join(outDir, fileName), `${content}\n`, 'utf8');
}
