/* lk-hidden.jsx — «Скрытые работы» для кабинетов сотрудников (прораб первым), в стиле окон кабинета клиента.
   Скрытые коммуникации (кабель, щит, трубы, тёплый пол, трассы кондиционера) снимают до того, как их закроют штукатуркой, стяжкой
   или плиткой: клиент получает эти фото по системам в пакете сдачи, чтобы потом не просверлить трубу. HiddenW — окно по объектам:
   слева пункты принятых работ без снимков («Добавить фото») и своё фото прораба (система, комната, что на фото), справа — что клиент
   получит: фото по системам. Действие — функция ProjectStore через кабинет: onAdd (addHiddenComm). Данные — ForemanViews.hidden().
   Exports on window: LKW.HiddenW (дописывает в библиотеку lk-widgets.jsx, грузится после неё). */
(function () {
  'use strict';
  const W = window.LKW;
  const { Ic, Modal, CalTabs, plural, dateR, short } = W;
  const dm = (d) => (d ? dateR(d, { month: 'short' }) : '');
  const pts = (n) => n + ' ' + plural(n, 'пункт', 'пункта', 'пунктов');
  const SYSTEMS = [['electric', 'Электрика'], ['lowvolt', 'Слаботочка'], ['water', 'Водопровод'], ['sewer', 'Канализация'], ['heating', 'Отопление и тёплый пол'], ['vent', 'Вентиляция и кондиционеры']];
  const ROOMS = ['Кухня', 'Санузел', 'Ванная', 'Коридор', 'Гостиная', 'Спальня', 'Детская', 'Балкон'];

  // выбор файлов и загрузка по одному; ошибка — под строкой
  function useUpload(onAdd) {
    const [busy, setBusy] = React.useState(false);
    const [err, setErr] = React.useState('');
    const pick = (spec, done) => (e) => {
      const list = Array.from(e.target.files || []); e.target.value = '';
      if (!list.length) return;
      setBusy(true); setErr('');
      Promise.resolve(onAdd(spec, list)).then((res) => { setBusy(false); if (res && res.error) setErr(res.error); else if (done) done(list.length); });
    };
    return { busy, err, pick };
  }

  /* пункт принятой работы без снимков: фото, добавленное здесь, закрывает пункт и уходит в пакет сдачи клиента */
  function NeedRow({ r, one, onAdd, onDone }) {
    const u = useUpload(onAdd);
    return (
      <div className="lw-hrow lw-prow">
        <span className="tx"><span className="t">{r.label}</span>
          <span className="lab">{[one ? '' : short(r.obj), r.work, 'принята ' + dm(r.doneAt)].filter(Boolean).join(' · ')}</span>
          {u.err && <span className="lab is-late">{u.err}</span>}</span>
        <label className="lw-btn-l lw-hup">{u.busy ? 'Загружаем…' : 'Добавить фото'}
          <input type="file" accept="image/*" multiple hidden disabled={u.busy} onChange={u.pick({ pid: r.pid, system: r.system, label: r.label }, (n) => onDone({ ...r, n }))} /></label>
      </div>);
  }

  /* своё фото прораба: обход объекта, трасса без пункта в чек-листе */
  function OwnForm({ pid, onAdd, onDone }) {
    const [f, setF] = React.useState({ system: 'electric', room: '', label: '' });
    const u = useUpload(onAdd);
    const ok = f.label.trim().length > 1;
    return (
      <div className="cv-w lw-plain lw-hown">
        <div className="lw-hownf">
          <select aria-label="Система" value={f.system} onChange={(e) => setF({ ...f, system: e.target.value })}>{SYSTEMS.map(([id, l]) => <option key={id} value={id}>{l}</option>)}</select>
          <select aria-label="Комната" value={f.room} onChange={(e) => setF({ ...f, room: e.target.value })}><option value="">Комната</option>{ROOMS.map((r) => <option key={r} value={r}>{r}</option>)}</select>
          <input aria-label="Что на фото" placeholder="Что на фото, например «Трасса к кухонному острову»" value={f.label} onChange={(e) => setF({ ...f, label: e.target.value })} />
        </div>
        <div className="lw-hownb">
          <span className="lab">{u.err ? <span className="is-late">{u.err}</span> : ok ? 'Фото попадёт в пакет сдачи клиента' : 'Подпишите, что на фото'}</span>
          <label className={'lw-btn-l lw-hup' + (ok ? '' : ' is-off')} aria-disabled={!ok}>{u.busy ? 'Загружаем…' : 'Выбрать фото'}
            <input type="file" accept="image/*" multiple hidden disabled={!ok || u.busy} onChange={u.pick({ pid, system: f.system, room: f.room, label: f.label.trim() }, (n) => { onDone({ pid, label: f.label.trim(), n, own: true }); setF({ ...f, label: '' }); })} /></label>
        </div>
      </div>);
  }

  // снимки системы карточками окна клиента «Фото и видео»; во вкладке «Все объекты» — по одному на систему
  function Gal({ items, limit, view }) {
    return (
      <div className="cv-gal cv-gal2">{(limit ? items.slice(0, limit) : items).map((it, i) => (
        <figure key={it.url + i}><button type="button" onClick={() => view(items, i)} aria-label={'Открыть: ' + it.work}><img src={it.url} alt="" loading="lazy" /></button><figcaption>{it.work}</figcaption></figure>))}</div>);
  }

  function HiddenW({ s, pid, onAdd, onObject, view, close }) {
    const objs = s.objs.map((o) => ({ pid: o.pid, obj: o.obj }));
    const [tab, setTab] = React.useState(pid && objs.some((o) => o.pid === pid) ? pid : 'all');
    const [added, setAdded] = React.useState([]);
    const inTab = (x) => tab === 'all' || x.pid === tab;
    const one = tab !== 'all' || objs.length === 1;
    const need = s.need.filter(inTab), os = s.objs.filter(inTab), done = added.filter(inTab);
    const counts = { all: s.need.length }; s.objs.forEach((o) => { counts[o.pid] = o.needN; });
    const ok = (r) => setAdded((x) => x.concat([r]));
    const photosN = os.reduce((a, o) => a + o.photos, 0);
    return (
      <Modal size="wide" className="lw-sup lw-photos lw-hid" title="Скрытые работы" onClose={close}
        sub={[need.length ? pts(need.length) + ' без фото' : 'Все принятые скрытые работы сняты', photosN ? photosN + ' фото в пакете сдачи клиента' : ''].filter(Boolean).join(' · ')}>
        {objs.length > 1 ? <CalTabs label="Объекты" kinds={[['all', 'Все объекты']].concat(objs.map((o) => [o.pid, short(o.obj)]))} tab={tab} setTab={setTab} counts={counts} /> : null}
        <div className="cv-dlgrid lw-supg">
          <aside className="cv-dlside">
            <div className="cv-sec-h"><h2 className="h2">Снять до закрытия</h2>{need.length > 0 && <span className="lab">{need.length}</span>}</div>
            {done.length > 0 && <div className="cv-w cv-dlcard lw-dok">{done.map((r, i) => (
              <div key={i} className="lw-dokr"><span className="ic"><Ic n="check" s={14} /></span>
                <span className="tx"><span className="t">«{r.label}» — {r.n} фото</span><span className="lab">{r.own ? 'Своё фото прораба' : 'Пункт закрыт'}: клиент получит его в пакете сдачи.</span></span></div>))}</div>}
            {need.length ? <div className="cv-w lw-plain lw-plist">{need.map((r) => <NeedRow key={r.pid + r.key} r={r} one={one} onAdd={onAdd} onDone={ok} />)}</div>
              : !done.length && <div className="cv-w cv-dlcard is-quiet"><div className="lab">У всех принятых скрытых работ есть снимки.</div></div>}
            <div className="lab lw-note">Пункты «скрытые коммуникации» — в чек-листах сдачи. Мастер снимает их при сдаче, а если снимков нет, добавьте свои, пока трассы не закрыли штукатуркой, стяжкой или плиткой.</div>

            {one && os[0] && <React.Fragment>
              <div className="cv-sec-h lw-sup-h"><h2 className="h2">Своё фото</h2></div>
              <OwnForm pid={os[0].pid} onAdd={onAdd} onDone={ok} />
            </React.Fragment>}

            <div className="cv-sec-h lw-sup-h"><h2 className="h2">По объектам</h2></div>
            <div className="cv-w lw-plain lw-mlist">{os.map((o) => (
              <div key={o.pid} className={'lw-mrow' + (o.needN ? ' is-late' : '')}>
                <span className="tx"><span className="t">{one ? 'Пункты скрытых работ' : short(o.obj)}</span>
                  <span className="lab">{o.points ? 'сняты ' + o.shot + ' из ' + pts(o.points) + [o.going ? ', ' + o.going + ' идут' : '', o.ahead ? ', ' + o.ahead + ' впереди' : ''].join('') : 'в смете нет скрытых работ'}</span></span>
                {!one ? <button type="button" className="cv-arrow-btn" onClick={() => setTab(o.pid)}>Подробнее<Ic n="ne" s={13} /></button> : <span className="lab">{o.needN ? o.needN + ' без фото' : 'всё снято'}</span>}
              </div>))}</div>
          </aside>
          <div className="lw-supm">
            <div className="cv-sec-h"><h2 className="h2">Что получит клиент</h2><span className="lab">фото по системам в пакете сдачи</span></div>
            {os.map((o) => (
              <div key={o.pid} className="lw-pobj">
                {!one && <div className="lw-mobj-h"><button type="button" className="cv-arrow-btn" onClick={() => onObject(o.pid)}>{short(o.obj)}<Ic n="ne" s={14} /></button>
                  <span className="lab">{o.photos} фото · {o.handedAt ? 'схема передана ' + dm(o.handedAt) : 'передадим при сдаче'}</span></div>}
                {one && <div className="lab lw-hhand">{o.handedAt ? 'Схема скрытых коммуникаций передана клиенту ' + dm(o.handedAt) + '.' : 'Клиент получит фото при сдаче объекта, вместе со схемами и гарантией.'}</div>}
                {one ? o.groups.map((g) => (
                  <div key={g.system} className="lw-pgrp">
                    <div className="cv-sec-h"><h3 className="lw-h3">{g.label}</h3><span className="lab">{g.items.length} фото</span></div>
                    <Gal items={g.items} view={view} />
                  </div>)) : o.groups.length > 0 && <div className="lw-pgrp"><Gal items={o.groups.map((g) => ({ ...g.items[0], work: g.label + ': ' + g.items[0].work }))} limit={3} view={view} /></div>}
                {!one && o.groups.length > 0 && <button type="button" className="lw-btn-l lw-pmore" onClick={() => setTab(o.pid)}>Все фото объекта · {o.photos}</button>}
                {!o.groups.length && <div className="cv-w cv-dlcard is-quiet"><div className="lab">Снимков скрытых работ пока нет: они появятся, когда мастер сдаст работу с пунктом «скрытые коммуникации».</div></div>}
              </div>))}
          </div>
        </div>
      </Modal>);
  }

  W.HiddenW = HiddenW;
})();
