/* deal-data-block.jsx — единый блок данных сделки: сводка плитками, вкладки, гармошки по темам.
   Один вид везде, где смотрят на сделку: мастер (этап «ДП»), карточка сделки менеджера, страница ДП дизайнера.
   Данные — карточка объекта (loadSiteIntake) и бриф ДП (FormInstances + DpBrief, если модуль брифа загружен).
   Только просмотр: менять — в мастере сделки (editHref).
   Exports on window: DealDict, dealDataTiles, dealDataGroups, DealDataBlock */
(function () {
  const { useState } = React;
  const { Ic } = window;

  /* ─── словари карточки объекта (те же коды, что в мастере) ─── */
  const DICT = {
    housing: [['apartment', 'Квартира'], ['apart_hotel', 'Апартаменты'], ['house', 'Дом'], ['commercial', 'Коммерция']],
    objectType: [['new_build', 'Новостройка'], ['secondary', 'Вторичка']],
    finish: [['without', 'Без отделки'], ['partial', 'Черновая (white box)'], ['renovation', 'С ремонтом'], ['keep', 'С ремонтом, без демонтажа']],
    houseType: [['monolith', 'Монолит'], ['panel', 'Панель'], ['brick', 'Кирпич'], ['block', 'Блочный'], ['wood', 'Дерево']],
    wallMaterial: { aerated: 'Газобетон / пеноблок', brick: 'Кирпич', concrete: 'Бетон', gkl: 'Гипсокартон', plywood: 'Фанера / ОСП', wood: 'Дерево' },
    repair: [['cosmetic', 'Косметический'], ['capital', 'Капитальный'], ['design', 'Дизайнерский']],
    tier: [['economy', 'Эконом'], ['mid', 'Комфорт'], ['premium', 'Премиум']],
    source: [['site', 'Сайт'], ['call', 'Звонок'], ['referral', 'Рекомендация'], ['ads', 'Реклама'], ['partner', 'Партнёр'], ['repeat', 'Повторный']],
    lift: [['cargo', 'Грузовой'], ['passenger', 'Пассажирский'], ['none', 'Нет лифта']],
    parking: [['free', 'Свободная'], ['paid', 'Платная'], ['none', 'Нет / далеко']],
    yesno: [['yes', 'Да'], ['no', 'Нет']],
    tech: {
      smart_home: 'Умный дом', heated_floor_el: 'Тёплый пол электрический', heated_floor_w: 'Тёплый пол водяной', heated_floor: 'Тёплый пол',
      ac: 'Кондиционирование', vent: 'Приточная вентиляция', sound: 'Звукоизоляция', replan: 'Перепланировка', windows: 'Замена окон',
      door: 'Входная дверь', power: 'Электрощит / больше мощности', risers: 'Замена стояков', water: 'Водоподготовка / фильтры',
      boiler: 'Бойлер / водонагреватель', install: 'Скрытые инсталляции', light: 'Сценарное освещение', lowvolt: 'Слаботочка',
      cctv: 'Видеонаблюдение / сигнализация', heating: 'Радиаторы / отопление', spa: 'Сауна / хамам',
    },
  };
  const lbl = (list, v) => { if (v == null || v === '') return ''; const x = list.find((y) => y[0] === v); return x ? x[1] : String(v); };
  const str = (v) => (v == null ? '' : Array.isArray(v) ? v.filter(Boolean).join(', ') : typeof v === 'object' ? '' : String(v).trim());

  function measuredArea(it) { const t = it.measureSession && it.measureSession.totals; return t && t.area ? t.area : null; }
  function addressOf(it) {
    const apt = it.apt ? (it.housingType === 'house' ? 'уч. ' : it.housingType === 'commercial' ? 'пом. ' : 'кв. ') + it.apt : '';
    return [String(it.city || '').trim(), it.address, apt].filter(Boolean).join(', ');
  }

  /* сводка плитками: самое нужное для решения — площадь, помещения, стиль, уровень, сроки, бриф/ремонт */
  function dealDataTiles(it, brief) {
    const p = it.prefs || {}; const m = measuredArea(it);
    const area = m ? m + ' м²' : it.areaApprox ? '≈ ' + it.areaApprox + ' м²' : '';
    const rooms = [it.roomsCount ? (it.roomsCount === 'studio' ? 'студия' : it.roomsCount + ' комн.') : '', it.bathsCount ? it.bathsCount + ' с/у' : '', +it.levels > 1 ? it.levels + ' ур.' : ''].filter(Boolean).join(' · ');
    const tiles = [
      { k: 'Площадь', icon: 'ruler', v: area, s: m ? 'по замеру' : area ? 'со слов клиента' : '' },
      { k: 'Помещения', icon: 'layout-grid', v: rooms, s: (it.rooms || []).length ? it.rooms.length + ' по замеру' : '' },
      { k: 'Стиль', icon: 'palette', v: str(p.style) },
      { k: 'Отделка', icon: 'gem', v: lbl(DICT.tier, p.finishTier), s: lbl(DICT.repair, it.repairType) },
      { k: 'Сроки', icon: 'calendar', v: p.deadlineDate ? 'к ' + p.deadlineDate : p.startWanted ? 'старт ' + p.startWanted : '' },
    ];
    if (it.requiresDesign) tiles.push(brief ? { k: 'Бриф ДП', icon: 'clipboard-list', v: brief.approved ? 'согласован' : brief.progress != null ? brief.progress + '%' : '', s: brief.approved ? '' : brief.label || '', tone: brief.approved ? 'ok' : brief.submitted ? 'warn' : '' }
      : { k: 'Дизайн-проект', icon: 'pen-tool', v: 'нужен' });
    else tiles.push({ k: 'Дизайн-проект', icon: 'pen-tool', v: 'не нужен' });
    return tiles;
  }

  /* исходные данные по темам: клиент, объект, доступ, пожелания, замер, референсы, комментарии */
  function dealDataGroups(it, opts) {
    const o = opts || {}; const p = it.prefs || {}; const acc = it.access || {}; const lg = p.logistics || {};
    const refs = it.references || []; const anti = it.antiReferences || []; const m = measuredArea(it);
    const notes = it.stageNotes || {};
    const NOTE_L = { client: 'к этапу «Клиент»', object: 'к этапу «Объект»', repair: 'к этапу «Ремонт»', measure: 'к этапу «Замер»', dp: 'к этапу «ДП»' };
    const tech = (p.tech || []).map((t) => DICT.tech[t] || t);
    const G = [
      !o.noClient && { id: 'client', title: 'Клиент', icon: 'user-round', rows: [
        ['Имя', it.clientName], ['Телефон', it.clientPhone], ['Email', it.clientEmail],
        ['Источник', lbl(DICT.source, it.leadSource)], ['Комментарий', it.clientNote],
      ] },
      { id: 'object', title: 'Объект', icon: 'house', rows: [
        ['Адрес', addressOf(it)], ['Тип', [lbl(DICT.housing, it.housingType), lbl(DICT.objectType, it.objectType)].filter(Boolean).join(' · ')],
        ['Состояние', lbl(DICT.finish, it.finishState)], ['Дом', [lbl(DICT.houseType, it.houseType), it.builtYear ? it.builtYear + ' г.' : ''].filter(Boolean).join(' · ')],
        ['Материал стен', str((it.wallMaterial || []).map((w) => DICT.wallMaterial[w] || w))],
        ['Комнат · санузлов · уровней', [it.roomsCount, it.bathsCount, it.levels].filter(Boolean).join(' · ')],
        ['Площадь', m ? m + ' м² по замеру' : it.areaApprox ? '≈ ' + it.areaApprox + ' м²' : ''], ['Потолки', it.ceilingApprox ? '≈ ' + it.ceilingApprox + ' м' : ''],
        ['Открытые зоны', str((it.outdoor || []).filter((x) => x !== 'Нет'))],
      ] },
      { id: 'access', title: 'Доступ и логистика', icon: 'key-round', rows: [
        ['Подъезд · этаж', [acc.entrance ? 'подъезд ' + acc.entrance : '', acc.floor ? 'этаж ' + acc.floor : ''].filter(Boolean).join(' · ')],
        ['Домофон', acc.code], ['Шлагбаум / пропуск', acc.gate], ['Контакт на объекте', acc.contact],
        ['Лифт', lbl(DICT.lift, lg.lift)], ['Парковка', lbl(DICT.parking, lg.parking)], ['Пропуск', lbl(DICT.yesno, lg.pass)], ['Хранение материалов', lbl(DICT.yesno, lg.storage)],
      ] },
      { id: 'wish', title: 'Пожелания к ремонту', icon: 'sparkles', rows: [
        ['Ремонт', lbl(DICT.repair, it.repairType)], ['Стиль', str(p.style)], ['Уровень отделки', lbl(DICT.tier, p.finishTier)],
        ['Технические решения', tech.join(', ')], ['Дизайн-проект', it.requiresDesign === true ? 'нужен' : it.requiresDesign === false ? 'не нужен' : ''],
        ['Сроки', [p.startWanted ? 'старт ' + p.startWanted : '', p.deadlineDate ? 'закончить к ' + p.deadlineDate : ''].filter(Boolean).join(' · ')],
      ] },
      { id: 'measure', title: 'Замер', icon: 'ruler', rows: [
        ['Дата', it.measurementDate], ['Замерщик', it.measuredBy], ['Площадь', m ? m + ' м²' : ''],
        ['Помещения', str((it.rooms || []).map((r) => r.name))],
      ] },
      { id: 'refs', title: 'Референсы', icon: 'image', rows: [
        ['Нравится', refs.length ? refs.length + ' · ' + refs.filter((r) => r.imageUrl).length + ' картинок, ' + refs.filter((r) => !r.imageUrl).length + ' ссылок' : ''],
        ['Не нравится', anti.length ? anti.length + ' картинок / ссылок' : ''],
      ] },
      { id: 'notes', title: 'Комментарии', icon: 'message-square-text', rows: [
        ['Клиент', p.freeText], ...Object.keys(NOTE_L).map((k) => [NOTE_L[k][0].toUpperCase() + NOTE_L[k].slice(1), notes[k]]),
      ] },
    ].filter(Boolean);
    return G.map((g) => ({ ...g, rows: g.rows.map(([k, v]) => [k, str(v)]).filter(([, v]) => v) })).filter((g) => g.rows.length);
  }

  /* бриф ДП: экземпляр анкеты сделки, прогресс и ответы по блокам (если модуль брифа есть на странице) */
  function briefOf(dealId, it) {
    const DB = window.DpBrief; const F = window.FormInstances;
    const inst = F && F.findInstance ? F.findInstance(dealId, (i) => i.kind === 'dp_brief') : null;
    const st = inst ? inst.accessState : ((it.clientForms || {}).dpPrefs || {}).status || 'pending';
    const [label] = (DB && DB.STATUS && DB.STATUS[st]) || [({ pending: 'не начат', active: 'ссылка у клиента', in_progress: 'заполняется', submitted: 'получен', approved: 'согласован' })[st] || st];
    let groups = null;
    try { const schema = DB && inst && DB.schemaFor ? DB.schemaFor(inst, it) : null; if (schema && DB.summary) groups = DB.summary(schema, inst.responses || {}, it); } catch (e) { groups = null; }
    const progress = inst && inst.progressPct != null ? +inst.progressPct || 0 : +(((it.clientForms || {}).dpPrefs || {}).progress) || 0;
    return { inst, state: st, label, approved: st === 'approved', submitted: st === 'submitted', closed: st === 'approved' || st === 'submitted', progress: st === 'approved' ? 100 : progress, groups };
  }

  /* lead — своя первая вкладка вызывающего экрана ({ id, label, badge, render }); editHref — «изменить в мастере»;
     collapsed — все гармошки свёрнуты (страница, где блок не главный) */
  function DealDataBlock({ dealId, intake, lead, defaultTab, editHref, onOpenBrief, collapsed, tab: tabProp, onTab, sourceTools }) {
    const it = intake || {};
    const [tabOwn, setTabOwn] = useState(null);
    const tab = onTab ? tabProp : tabOwn; const setTab = onTab || setTabOwn;
    const b = briefOf(dealId, it);
    const source = dealDataGroups(it);
    const nSource = source.reduce((a, g) => a + g.rows.length, 0);
    const answers = b.groups || [];
    const nAnswers = answers.reduce((a, g) => a + g.rows.length, 0);
    const hasAnswersTab = !!it.requiresDesign;
    const tabs = [lead, hasAnswersTab && { id: 'answers', label: 'Ответы брифа', badge: nAnswers || null }, { id: 'source', label: 'Исходные данные', badge: nSource || null }].filter(Boolean);
    const fallback = lead && !b.closed ? lead.id : hasAnswersTab && nAnswers ? 'answers' : 'source';
    const cur = tabs.some((t) => t.id === tab) ? tab : tabs.some((t) => t.id === defaultTab) ? defaultTab : fallback;
    const Segs = window.LKSegs; const DataTiles = window.DataTiles; const DataAcc = window.DataAcc;
    const pdf = () => { try { const u = new URL('brief-print.html', window.location.href); u.searchParams.set('deal', dealId); u.searchParams.set('print', '1'); window.open(u.toString(), '_blank'); } catch (e) {} };
    return (
      <div className="ddb">
        {DataTiles && <DataTiles items={dealDataTiles(it, b)} />}
        {Segs && tabs.length > 1 && <div className="dbk-bar"><Segs segs={tabs.map((t) => ({ id: t.id, label: t.label, badge: t.badge }))} active={cur} onChange={setTab} /></div>}
        {lead && cur === lead.id && <div className="dbk-pane">{lead.render()}</div>}
        {cur === 'answers' && (
          <div className="dbk-pane">
            <div className="dbk-tools">
              <span>{answers.length ? answers.length + ' блоков · ' + nAnswers + ' ответов' + (b.closed ? '' : ' · черновик, клиент ещё заполняет') : ''}</span>
              <span className="sp" />
              {onOpenBrief && <button type="button" className="chip" onClick={onOpenBrief}><Ic n="presentation" s={12} />презентация</button>}
              {b.inst && <button type="button" className="chip" onClick={pdf}><Ic n="file-down" s={12} />PDF для AI</button>}
            </div>
            {b.groups == null
              ? <div className="lk-empty-note">Ответы брифа открываются в мастере сделки — этап «ДП».{editHref ? <React.Fragment> <a href={editHref + '&stage=dp'}>Открыть</a></React.Fragment> : null}</div>
              : DataAcc && <DataAcc key={'a' + answers.length} groups={answers} first={!collapsed} empty={'Ответов пока нет — бриф ' + (b.state === 'pending' ? 'не начат.' : 'заполняется.')} />}
          </div>)}
        {cur === 'source' && (
          <div className="dbk-pane">
            <div className="dbk-tools">
              <span>карточка объекта: этапы «Клиент», «Объект», «Ремонт», «Замер»</span>
              <span className="sp" />
              {sourceTools || (editHref && <a className="chip" href={editHref}><Ic n="pencil" s={12} />изменить в мастере</a>)}
            </div>
            {DataAcc && <DataAcc groups={source} first={false} empty="Карточка объекта пока пустая — заполните её в мастере сделки." />}
          </div>)}
      </div>
    );
  }

  window.DealDict = DICT;
  Object.assign(window, { dealDataTiles, dealDataGroups, DealDataBlock, dealBriefOf: briefOf });
})();
