/* Модуль «Смета» — паритет с монолитом:
   правка ячеек, фильтр, +строка, стиль грида (Линии/Зебра/Минимал),
   статус-колонка, скрытие Себест./Маржа по роли (seeMargin), экспорт CSV,
   клик по строке → drawer позиции. Данные/права из общего стора. */
window.RD = window.RD || { core: {}, modules: {} };
window.RD.modules.Estimate = function Estimate() {
  var store = RD.core.useStore();
  var C = RD.core, money = C.money, h = React.createElement;
  var sections = store.raw.sections || [];
  var perms = store.perms, vat = store.vatRate;

  var fRef = React.useState('all'); var filter = fRef[0], setFilter = fRef[1];
  var rwRef = React.useState(false); var raw = rwRef[0], setRaw = rwRef[1];
  var gRef = React.useState('lines'); var gridStyle = gRef[0], setGridStyle = gRef[1];
  var dRef = React.useState(null); var drawer = dRef[0], setDrawer = dRef[1];

  var seeMargin = perms.seeMargin || perms.admin;

  function editLine(secId, rowId, field, val) {
    if (!perms.estimate) { store.showToast('Недостаточно прав: роль «' + perms.role + '» не правит смету', 'warn'); return; }
    var v = Math.max(0, parseFloat(('' + val).replace(',', '.')) || 0);
    var sec = sections.find(function (s) { return s.id === secId; });
    if (!sec) return;
    var rows = sec.rows.map(function (r) { var o = Object.assign({}, r); if (r.id === rowId) o[field] = v; return o; });
    store.update('sections', secId, { rows: rows });
  }
  function chooseEstimateXor(secId, keepId) {
    var sec = sections.find(function (s) { return s.id === secId; }); if (!sec) return;
    var grp = (sec.rows.find(function (r) { return r.id === keepId; }) || {}).exclGroup; if (!grp) return;
    store.pushHist();
    var rows = sec.rows.map(function (r) { if (r.exclGroup !== grp) return r; var on = (r.id === keepId); return Object.assign({}, r, { rejected: !on, exclChosen: on, status: on ? (r.status === 'alt' ? 'planned' : r.status) : 'alt' }); });
    store.update('sections', secId, { rows: rows });
    store.showToast('Вариант выбран в смете · альтернатива исключена из итога', 'ok');
  }
  function addRow() {
    if (!perms.estimate) { store.showToast('Недостаточно прав для добавления позиции', 'warn'); return; }
    var sec = sections[0]; if (!sec) return;
    var row = { id: 'r' + Date.now(), kind: 'work', name: 'Новая позиция', unit: 'шт', qty: 1, price: 0, status: 'planned', pct: 0 };
    store.update('sections', sec.id, { rows: (sec.rows || []).concat([row]) });
    store.showToast('Добавлена позиция в «' + sec.name + '» · впишите наименование и цену', 'ok');
  }
  function exportCSV() {
    var rows = [];
    sections.forEach(function (s) { (s.rows || []).forEach(function (r) { var amt = r.qty * r.price; rows.push([s.name, r.name, r.kind === 'work' ? 'работа' : 'материал', r.unit, r.qty, r.price, Math.round(amt), Math.round(C.lineVat(amt, vat)), Math.round(amt + C.lineVat(amt, vat)), C.statusMeta(r.status).label, (r.pct || 0) + '%']); }); });
    var head = ['Раздел', 'Наименование', 'Тип', 'Ед', 'Кол-во', 'Цена', 'Сумма', 'НДС', 'Всего', 'Статус', 'Готовность'];
    var esc = function (v) { v = ('' + (v == null ? '' : v)).replace(/"/g, '""'); return /[";\n]/.test(v) ? '"' + v + '"' : v; };
    var csv = '\uFEFF' + [head.map(esc).join(';')].concat(rows.map(function (r) { return r.map(esc).join(';'); })).join('\r\n');
    try { var b = new Blob([csv], { type: 'text/csv;charset=utf-8' }); var u = URL.createObjectURL(b); var a = document.createElement('a'); a.href = u; a.download = 'smeta.csv'; document.body.appendChild(a); a.click(); document.body.removeChild(a); setTimeout(function () { URL.revokeObjectURL(u); }, 1000); store.showToast('Выгружено: smeta.csv · ' + rows.length + ' строк', 'ok'); } catch (e) { store.showToast('Ошибка экспорта', 'warn'); }
  }

  // колонки (динамически: маржа/себест только для seeMargin)
  var cols = [['no', '№', 40], ['name', 'Наименование', 1], ['unit', 'Ед.', 50], ['qty', 'Кол-во', 70], ['price', 'Цена', 88]];
  if (seeMargin) cols.push(['cost', 'Себест.', 88]);
  cols.push(['amt', 'Сумма ƒ', 104], ['vat', 'НДС ƒ', 92]);
  if (seeMargin) cols.push(['margin', 'Маржа ƒ', 92]);
  cols.push(['status', 'Статус', 90], ['pct', 'Готов.', 70]);
  var gtc = cols.map(function (c) { return c[2] === 1 ? '1fr' : c[2] + 'px'; }).join(' ');
  var minW = cols.reduce(function (a, c) { return a + (c[2] === 1 ? 180 : c[2]); }, 0);

  var grand = 0, grandVat = 0;
  var blocks = sections.map(function (s) {
    var sub = 0, subVat = 0;
    var rows = (s.rows || []).filter(function (r) { if (r.rejected && !r.exclGroup) return false; if (filter === 'work') return r.kind === 'work'; if (filter === 'material') return r.kind === 'material'; if (filter === 'unfinished') return r.status !== 'done'; return true; });
    (s.rows || []).forEach(function (r) { if (r.rejected) return; var amt = r.qty * r.price; sub += amt; subVat += C.lineVat(amt, vat); });
    grand += sub; grandVat += subVat;
    return { s: s, rows: rows, sub: sub };
  });

  function rowBg(ri) { return gridStyle === 'zebra' && ri % 2 ? 'var(--rd-surface-2)' : 'var(--rd-surface)'; }
  function brd() { return gridStyle === 'minimal' ? 'none' : '1px solid var(--rd-border)'; }
  function cell(txt, st) { return h('div', { style: Object.assign({ padding: '7px 10px', fontSize: 12, borderBottom: brd(), display: 'flex', alignItems: 'center', overflow: 'hidden' }, st) }, txt); }
  function inp(r, secId, field) { return h('div', { style: { borderBottom: brd() } }, h('input', { defaultValue: r[field], onBlur: function (e) { editLine(secId, r.id, field, e.target.value); }, disabled: !perms.estimate, className: 'mono', style: { width: '100%', height: '100%', minHeight: 30, border: 'none', background: 'transparent', textAlign: 'right', fontSize: 12, color: 'var(--rd-text)', padding: '0 10px', outline: 'none' } })); }

  var seg = function (k, lbl) { return h('button', { key: k, onClick: function () { setGridStyle(k); }, style: { padding: '5px 9px', border: '1px solid var(--rd-border)', borderRadius: 7, background: gridStyle === k ? 'var(--rd-accent-soft)' : 'var(--rd-surface)', color: gridStyle === k ? 'var(--rd-accent)' : 'var(--rd-text-2)', fontSize: 11, fontWeight: gridStyle === k ? 600 : 500, cursor: 'pointer' } }, lbl); };

  return h('div', { className: 'rd-main-content', style: { background: 'var(--rd-surface)', position: 'relative' } },
    h('div', { style: { height: 46, flex: 'none', borderBottom: '1px solid var(--rd-border)', display: 'flex', alignItems: 'center', padding: '0 16px', gap: 10, background: 'var(--rd-surface-2)', flexWrap: 'wrap' } },
      h('div', { style: { fontSize: 13, fontWeight: 600 } }, 'Смета'),
      h('div', { className: 'mono', style: { fontSize: 11.5, color: 'var(--rd-text-muted)' } }, sections.reduce(function (a, s) { return a + (s.rows || []).length; }, 0) + ' позиций · ' + sections.length + ' разд.'),
      h('button', { onClick: function () { setRaw(!raw); }, style: { padding: '5px 10px', border: '1px solid var(--rd-border)', borderRadius: 7, background: raw ? 'var(--rd-accent-soft)' : 'var(--rd-surface)', color: raw ? 'var(--rd-accent)' : 'var(--rd-text-2)', fontSize: 11, fontWeight: raw ? 600 : 500, cursor: 'pointer' } }, 'Все столбцы из БД'),
      h('div', { style: { flex: 1 } }),
      h('div', { style: { display: 'flex', gap: 4 } }, seg('lines', 'Линии'), seg('zebra', 'Зебра'), seg('minimal', 'Минимал')),
      h('div', { style: { width: 1, height: 18, background: 'var(--rd-border)' } }),
      ['all', 'work', 'material', 'unfinished'].map(function (f) { return h('button', { key: f, onClick: function () { setFilter(f); }, style: { padding: '5px 9px', border: '1px solid var(--rd-border)', borderRadius: 7, background: filter === f ? 'var(--rd-accent-soft)' : 'var(--rd-surface)', color: filter === f ? 'var(--rd-accent)' : 'var(--rd-text-2)', fontSize: 11, fontWeight: filter === f ? 600 : 500, cursor: 'pointer' } }, { all: 'Все', work: 'Работы', material: 'Материалы', unfinished: 'Незаверш.' }[f]); }),
      h('button', { onClick: exportCSV, style: { padding: '5px 10px', border: '1px solid var(--rd-border)', borderRadius: 7, background: 'var(--rd-surface)', color: 'var(--rd-text-2)', fontSize: 11, fontWeight: 500, cursor: 'pointer' } }, '↓ CSV'),
      perms.estimate ? h('button', { onClick: addRow, style: { padding: '5px 11px', border: 'none', borderRadius: 7, background: 'var(--rd-text)', color: 'var(--rd-surface)', fontSize: 11, fontWeight: 600, cursor: 'pointer' } }, '+ Строка') : null
    ),
    raw ? (function () {
      var rows = []; sections.forEach(function (s) { (s.rows || []).forEach(function (r) { rows.push(Object.assign({ раздел: s.name }, r)); }); });
      var keys = []; rows.forEach(function (x) { Object.keys(x).forEach(function (k) { if (keys.indexOf(k) < 0) keys.push(k); }); });
      var priceK = { price: 1, cost: 1 };
      var fmt = function (v) { if (v == null) return ''; if (typeof v === 'object') return JSON.stringify(v); return '' + v; };
      var grid = '40px ' + keys.map(function (k) { return k === 'name' ? '180px' : '110px'; }).join(' ');
      return h('div', { className: 'rd-gantt-wrap', style: { overflow: 'auto', padding: 12 } },
        h('div', { style: { fontSize: 10.5, color: 'var(--rd-text-muted)', marginBottom: 6 } }, 'Все столбцы из БД: ' + keys.length + ' · строк: ' + rows.length + (seeMargin ? '' : ' · себест./маржа скрыты по роли')),
        h('div', { style: { border: '1px solid var(--rd-border)', borderRadius: 8, overflow: 'auto' } },
          h('div', { style: { minWidth: 50 + keys.length * 112 } },
            h('div', { style: { display: 'grid', gridTemplateColumns: grid, background: 'var(--rd-surface-3)', borderBottom: '1px solid var(--rd-border)', fontSize: 10, fontWeight: 600, color: 'var(--rd-text-muted)', position: 'sticky', top: 0 } },
              [h('div', { key: 'n', style: { padding: '7px 8px' } }, '№')].concat(keys.map(function (k) { return h('div', { key: k, style: { padding: '7px 8px' } }, (priceK[k] && !seeMargin) ? (k + ' 🔒') : k); }))),
            rows.map(function (x, i) {
              return h('div', { key: i, style: { display: 'grid', gridTemplateColumns: grid, borderBottom: '1px solid var(--rd-border)', fontSize: 11, alignItems: 'center', background: x.rejected ? 'var(--rd-bad-soft,#fbeaea)' : (i % 2 ? 'var(--rd-surface-2)' : 'var(--rd-surface)') } },
                [h('div', { key: 'n', className: 'mono', style: { padding: '5px 8px', color: 'var(--rd-text-muted)', fontSize: 10 } }, i + 1)].concat(keys.map(function (k) {
                  var hide = priceK[k] && !seeMargin;
                  return h('div', { key: k, className: (typeof x[k] === 'number') ? 'mono' : '', style: { padding: '5px 8px', color: 'var(--rd-text-2)', fontSize: 10.5, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, hide ? '—' : fmt(x[k]));
                })));
            })
          )));
    })() : (sections.length === 0 
      ? h('div', { style: { flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 40, color: 'var(--rd-text-muted)' } },
          h('div', { style: { fontSize: 48, marginBottom: 16, opacity: 0.3 } }, '📋'),
          h('div', { style: { fontSize: 18, fontWeight: 600, marginBottom: 8, color: 'var(--rd-text)' } }, 'Смета не загружена'),
          h('div', { style: { fontSize: 13, marginBottom: 20, textAlign: 'center', maxWidth: 420 } }, 'Для проекта ещё не создана смета. Импортируйте из документов (финальная смета ТСН) или создайте вручную.'),
          h('div', { style: { display: 'flex', gap: 12 } },
            h('button', { onClick: function () { store.showToast('Импорт сметы — в разработке', 'info'); }, style: { padding: '10px 18px', border: '1px solid var(--rd-border)', borderRadius: 8, background: 'var(--rd-surface-2)', color: 'var(--rd-text)', fontSize: 13, fontWeight: 600, cursor: 'pointer' } }, '📄 Импорт из документов'),
            perms.estimate ? h('button', { onClick: function () { store.showToast('Создание сметы вручную — в разработке', 'info'); }, style: { padding: '10px 18px', border: 'none', borderRadius: 8, background: 'var(--rd-accent)', color: '#fff', fontSize: 13, fontWeight: 600, cursor: 'pointer' } }, '+ Создать вручную') : null
          )
        )
      : h('div', { className: 'rd-gantt-wrap' },
      h('div', { className: 'rd-estimate-grid', style: { minWidth: minW } },
        h('div', { style: { display: 'grid', gridTemplateColumns: gtc, position: 'sticky', top: 0, zIndex: 2, background: 'var(--rd-surface-3)', borderBottom: '1px solid var(--rd-border)' } },
          cols.map(function (c, i) { return h('div', { key: i, style: { padding: '9px 10px', fontSize: 10.5, fontWeight: 600, color: 'var(--rd-text-muted)', textAlign: (c[0] === 'qty' || c[0] === 'price' || c[0] === 'cost' || c[0] === 'amt' || c[0] === 'vat' || c[0] === 'margin') ? 'right' : 'left' } }, c[1]); })),
        blocks.map(function (b, bi) {
          return h(React.Fragment, { key: b.s.id },
            h('div', { style: { display: 'flex', alignItems: 'center', gap: 8, padding: '8px 13px', background: 'var(--rd-surface-3)', borderTop: '1px solid var(--rd-border)', borderBottom: '1px solid var(--rd-border)' } },
              h('span', { style: { fontWeight: 600, fontSize: 12.5 } }, b.s.name),
              h('span', { className: 'mono', style: { fontSize: 10.5, color: 'var(--rd-text-muted)' } }, (b.s.rows || []).length + ' поз.'),
              h('span', { style: { flex: 1 } }),
              h('span', { className: 'mono', style: { fontSize: 11, color: 'var(--rd-text-2)' } }, 'Σ ' + money(b.sub) + ' ₽')),
            b.rows.map(function (r, ri) {
              var amt = r.qty * r.price, cost = (r.cost != null ? r.cost : Math.round(r.price * 0.72)), margin = r.price - cost;
              var c2 = cols.map(function (col) {
                var k = col[0];
                if (k === 'no') return cell((bi + 1) + '.' + (ri + 1), { color: 'var(--rd-text-muted)', fontFamily: 'var(--rd-mono)', fontSize: 10.5 });
                if (k === 'name') return cell(h('span', { onClick: function () { setDrawer({ secId: b.s.id, row: r }); }, style: { display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer', opacity: r.rejected ? .5 : 1 } }, h('span', { style: { width: 7, height: 7, borderRadius: 2, background: r.kind === 'material' ? 'var(--rd-accent)' : 'var(--rd-good)', flex: 'none' } }), h('span', { style: { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', textDecoration: r.rejected ? 'line-through' : 'none' } }, r.name), r.exclGroup ? h('button', { onClick: function (e) { e.stopPropagation(); chooseEstimateXor(b.s.id, r.id); }, title: 'XOR: выбрать этот вариант', style: { flex: 'none', fontSize: 9, fontWeight: 700, padding: '1px 6px', borderRadius: 4, border: 'none', cursor: 'pointer', background: r.exclChosen ? 'var(--rd-accent)' : 'var(--rd-surface-3)', color: r.exclChosen ? '#fff' : 'var(--rd-accent)' } }, r.exclChosen ? 'XOR ✓' : 'выбрать') : null));
                if (k === 'unit') return cell(r.unit, { color: 'var(--rd-text-2)', fontSize: 11 });
                if (k === 'qty') return inp(r, b.s.id, 'qty');
                if (k === 'price') return inp(r, b.s.id, 'price');
                if (k === 'cost') return cell(money(cost), { fontFamily: 'var(--rd-mono)', justifyContent: 'flex-end', color: 'var(--rd-text-muted)', fontSize: 11 });
                if (k === 'amt') return cell(money(amt), { fontFamily: 'var(--rd-mono)', fontWeight: 600, justifyContent: 'flex-end', background: 'var(--rd-accent-soft)', color: 'var(--rd-text)' });
                if (k === 'vat') return cell(money(C.lineVat(amt, vat)), { fontFamily: 'var(--rd-mono)', justifyContent: 'flex-end', color: 'var(--rd-text-muted)', fontSize: 11 });
                if (k === 'margin') return cell((margin >= 0 ? '+' : '') + money(margin * r.qty), { fontFamily: 'var(--rd-mono)', justifyContent: 'flex-end', color: margin >= 0 ? 'var(--rd-good)' : 'var(--rd-bad)', fontSize: 11 });
                if (k === 'status') return cell(h('span', { style: C.pill(r.status) }, C.statusMeta(r.status).label));
                if (k === 'pct') return cell((r.pct || 0) + '%', { color: 'var(--rd-text-2)', fontSize: 11 });
                return cell('');
              });
              return h('div', { key: r.id, style: { display: 'grid', gridTemplateColumns: gtc, background: rowBg(ri) } }, c2);
            })
          );
        })
      )
    )),
    h('div', { style: { flex: 'none', borderTop: '1px solid var(--rd-border)', background: 'var(--rd-surface-2)', display: 'flex', alignItems: 'center', padding: '0 18px', height: 50, gap: 24 } },
      h('div', null, h('span', { style: { fontSize: 11, color: 'var(--rd-text-muted)' } }, 'Итого без НДС '), h('span', { className: 'mono', style: { fontSize: 14, fontWeight: 600 } }, money(grand) + ' ₽')),
      h('div', null, h('span', { style: { fontSize: 11, color: 'var(--rd-text-muted)' } }, 'НДС ' + Math.round(vat * 100) + '% '), h('span', { className: 'mono', style: { fontSize: 13, color: 'var(--rd-text-2)' } }, money(grandVat) + ' ₽')),
      h('div', { style: { flex: 1 } }),
      h('div', null, h('span', { style: { fontSize: 11.5, color: 'var(--rd-text-2)' } }, 'Всего с НДС '), h('span', { className: 'mono', style: { fontSize: 17, fontWeight: 700, color: 'var(--rd-accent)' } }, money(grand + grandVat) + ' ₽'))
    ),
    // drawer позиции
    drawer ? (function () {
      var r = drawer.row, amt = r.qty * r.price, cost = (r.cost != null ? r.cost : Math.round(r.price * 0.72));
      return h('div', { onClick: function () { setDrawer(null); }, style: { position: 'fixed', inset: 0, background: 'rgba(0,0,0,.34)', zIndex: 60, display: 'flex', justifyContent: 'flex-end' } },
        h('div', { onClick: function (e) { e.stopPropagation(); }, style: { width: 360, maxWidth: '92vw', height: '100%', background: 'var(--rd-surface)', boxShadow: '-12px 0 40px rgba(0,0,0,.2)', overflow: 'auto' } },
          h('div', { style: { padding: 18, borderBottom: '1px solid var(--rd-border)', display: 'flex', alignItems: 'center', gap: 10 } },
            h('div', { style: { flex: 1 } }, h('div', { style: { fontSize: 15, fontWeight: 600 } }, r.name), h('div', { style: { fontSize: 11.5, color: 'var(--rd-text-muted)' } }, (r.kind === 'material' ? 'Материал' : 'Работа') + ' · ' + r.unit)),
            h('button', { onClick: function () { setDrawer(null); }, style: { border: 'none', background: 'none', fontSize: 20, color: 'var(--rd-text-muted)', cursor: 'pointer' } }, '×')),
          h('div', { style: { padding: 16 } },
            h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 9 } },
              [['Кол-во', r.qty + ' ' + r.unit], ['Цена', money(r.price) + ' ₽'], ['Сумма', money(amt) + ' ₽'], ['НДС', money(C.lineVat(amt, vat)) + ' ₽'], ['Статус', C.statusMeta(r.status).label], ['Готовность', (r.pct || 0) + '%']]
                .concat(seeMargin ? [['Себест.', money(cost) + ' ₽'], ['Маржа', money((r.price - cost) * r.qty) + ' ₽']] : [])
                .map(function (s, i) { return h('div', { key: i, style: { border: '1px solid var(--rd-border)', borderRadius: 9, padding: '9px 11px', background: 'var(--rd-surface-2)' } }, h('div', { style: { fontSize: 10.5, color: 'var(--rd-text-muted)', marginBottom: 3 } }, s[0]), h('div', { className: 'mono', style: { fontSize: 13, fontWeight: 700 } }, s[1])); })))
        )
      );
    })() : null
  );
};
