/* lk-photos.jsx — «Фото для клиента» для кабинетов сотрудников (прораб первым), в стиле окон кабинета клиента.
   Клиент видит фото и видео только принятых работ, сразу после приёмки: в своих «Фото и видео», в ленте «Новое на объекте» и в отчёте
   за неделю. PhotosW — окно по объектам: слева принятые работы без фото («Добавить фото»: снимки сразу появляются у клиента), работы,
   сданные с фото (уйдут клиенту, когда прораб примет, — «Открыть» ведёт в карточку работы), и отчёт, который клиент получит в понедельник.
   Справа — что клиент видит сейчас: фото и видео по этапам, свежий этап сверху, просмотр со стрелками.
   Действие — функция ProjectStore через кабинет: onUpload (addAttachment). Данные — ForemanViews.photos().
   Exports on window: LKW.PhotosW (дописывает в библиотеку 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 works = (n) => n + ' ' + plural(n, 'работа', 'работы', 'работ');
  const files = (n) => n + ' ' + plural(n, 'файл', 'файла', 'файлов');
  const isoAdd = (d, n) => { const x = new Date(d + 'T00:00:00Z'); x.setUTCDate(x.getUTCDate() + n); return x.toISOString().slice(0, 10); };

  /* принятая работа без фото: снимки, добавленные здесь, клиент видит сразу */
  function BareRow({ r, one, onUpload }) {
    const [busy, setBusy] = React.useState(false);
    const [err, setErr] = React.useState('');
    const pick = (e) => {
      const list = Array.from(e.target.files || []); e.target.value = '';
      if (!list.length) return;
      setBusy(true); setErr('');
      Promise.resolve(onUpload(r, list)).then((res) => { if (res && res.error) setErr(res.error); setBusy(false); });
    };
    return (
      <div className="lw-hrow lw-prow">
        <span className="tx"><span className="t">{r.title}</span>
          <span className="lab">{[one ? '' : short(r.obj), r.stage, 'принята ' + dm(r.doneAt), r.who].filter(Boolean).join(' · ')}</span>
          {err && <span className="lab is-late">{err}</span>}</span>
        <label className="lw-btn-l lw-hup">{busy ? 'Загружаем…' : 'Добавить фото'}
          <input type="file" accept="image/*,video/*" multiple hidden onChange={pick} disabled={busy} /></label>
      </div>);
  }
  // работы, к которым фото добавили сейчас в этом окне: что увидел клиент — одной карточкой, пока окно открыто
  function AddedCard({ list }) {
    return (
      <div className="cv-w cv-dlcard lw-dok">
        {list.map((r) => (
          <div key={r.pid + r.taskId} className="lw-dokr">
            <span className="ic"><Ic n="check" s={14} /></span>
            <span className="tx"><span className="t">«{r.title}» — {r.n} фото у клиента</span>
              <span className="lab">Добавлено в «Фото и видео» клиента, этап «{r.stage}».</span></span>
          </div>))}
      </div>);
  }

  /* сданная мастером работа с фото: кадры можно посмотреть здесь, принять или вернуть — в карточке работы */
  function ReviewRow({ r, one, view, onWork }) {
    const items = r.photos.map((x) => ({ kind: 'image', url: x.url, name: x.name, work: r.title }));
    return (
      <div className="lw-hrow lw-prow">
        <span className="tx"><span className="t">{r.title}</span>
          <span className="lab">{[one ? '' : short(r.obj), r.stage, 'сдал ' + (r.who || 'мастер')].filter(Boolean).join(' · ')}</span>
          <span className="lw-pthumbs">{r.photos.slice(0, 4).map((x, i) => (
            <button type="button" key={x.url} onClick={() => view(items, i)} aria-label={'Фото ' + (i + 1) + ' из ' + r.photos.length + ': ' + r.title}><img src={x.url} alt="" loading="lazy" /></button>))}
            {r.photos.length > 4 && <span className="lab">+{r.photos.length - 4}</span>}</span></span>
        <button type="button" className="cv-arrow-btn" onClick={() => onWork(r)}>Открыть<Ic n="ne" s={13} /></button>
      </div>);
  }

  /* этап глазами клиента: те же карточки, что в его окне «Фото и видео» */
  function Stage({ g, limit, view }) {
    const items = limit ? g.items.slice(-limit) : g.items;
    return (
      <div className="lw-pgrp">
        <div className="cv-sec-h"><h3 className="lw-h3">{g.stage}</h3><span className="lab">{files(g.n)} · принято {g.date}</span></div>
        <div className="cv-gal cv-gal2">
          {items.map((it) => (
            <figure key={it.url}>
              <button type="button" onClick={() => view(g.items, g.items.indexOf(it))} aria-label={'Открыть: ' + it.work}>
                {it.kind === 'video' ? <video src={it.url + '#t=0.1'} muted preload="metadata" /> : <img src={it.url} alt="" loading="lazy" />}
                {it.kind === 'video' && <span className="lw-pplay" aria-hidden="true"><svg viewBox="0 0 24 24" width="18" height="18"><path d="M8 5.5v13l10.5-6.5z" fill="currentColor" /></svg></span>}
              </button>
              <figcaption>{it.work}</figcaption>
            </figure>))}
        </div>
      </div>);
  }

  function PhotosW({ s, t0, pid, onUpload, onWork, 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 bare = s.bare.filter(inTab), rev = s.review.filter(inTab), done = added.filter(inTab), os = s.objs.filter(inTab);
    const counts = { all: s.bare.length + s.review.length }; s.objs.forEach((o) => { counts[o.pid] = o.bareN + o.reviewN; });
    const upload = (r, list) => Promise.resolve(onUpload(r, list)).then((res) => { if (res && !res.error) setAdded((x) => x.concat([{ ...r, n: list.length }])); return res; });
    const n = os.reduce((a, o) => a + o.n, 0), revN = rev.reduce((a, r) => a + r.photos.length, 0);
    const sun = isoAdd(s.mon, 6);
    return (
      <Modal size="wide" className="lw-sup lw-photos" title="Фото для клиента" onClose={close}
        sub={[n ? 'Клиент видит ' + files(n) : 'Клиент пока не видит фото', bare.length ? works(bare.length) + ' без фото' : '', revN ? revN + ' фото на приёмке' : ''].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>{bare.length > 0 && <span className="lab">{bare.length}</span>}</div>
            {done.length > 0 && <AddedCard list={done} />}
            {bare.length ? <div className="cv-w lw-plain lw-plist">{bare.map((r) => <BareRow key={r.pid + r.taskId} r={r} one={one} onUpload={upload} />)}</div>
              : !done.length && <div className="cv-w cv-dlcard is-quiet"><div className="lab">У всех принятых работ есть фото: клиент видит каждую в «Фото и видео».</div></div>}
            {bare.length > 0 && <div className="lab lw-note">Клиент видит только фото принятых работ. У этих работ кадров нет, и в его кабинете по ним пусто. Добавленные фото он увидит сразу.</div>}

            <div className="cv-sec-h lw-sup-h"><h2 className="h2">Уйдут клиенту после приёмки</h2>{rev.length > 0 && <span className="lab">{rev.length}</span>}</div>
            {rev.length ? <div className="cv-w lw-plain lw-plist">{rev.map((r) => <ReviewRow key={r.pid + r.taskId} r={r} one={one} view={view} onWork={onWork} />)}</div>
              : <div className="cv-w cv-dlcard is-quiet"><div className="lab">Работ с фото на приёмке нет.</div></div>}
            {rev.length > 0 && <div className="lab lw-note">Фото уйдут клиенту, как только вы примете работу. Если кадр плохой, верните работу в карточке с замечанием к фото.</div>}

            <div className="cv-sec-h lw-sup-h"><h2 className="h2">Отчёт в понедельник</h2><span className="lab">{dm(s.next)}</span></div>
            <div className="cv-w lw-plain lw-mlist">
              {one ? (os[0] && os[0].week.works.length ? os[0].week.works.map((w) => (
                <div key={w.taskId} className={'lw-mrow' + (w.photos ? '' : ' is-late')}>
                  <span className="tx"><span className="t">{w.title}</span><span className="lab">{w.stage} · принята {dm(w.doneAt)}</span></span>
                  <span className="lab">{w.photos ? w.photos + ' фото' : 'без фото'}</span>
                </div>)) : <div className="lw-mrow"><span className="tx"><span className="lab">С понедельника работ не принимали: в отчёте будут только планы на неделю.</span></span></div>)
                : os.map((o) => (
                  <div key={o.pid} className="lw-mrow">
                    <span className="tx"><span className="t">{short(o.obj)}</span>
                      <span className="lab">{o.week.works.length ? works(o.week.works.length) + ', ' + o.week.photos + ' фото' + (o.week.bare ? ' · ' + o.week.bare + ' без фото' : '') : 'с понедельника работ не принимали'}</span></span>
                    <button type="button" className="cv-arrow-btn" onClick={() => setTab(o.pid)}>Подробнее<Ic n="ne" s={13} /></button>
                  </div>))}
            </div>
            <div className="lab lw-note">Клиент получит отчёт за {dm(s.mon)} – {dm(sun)}: принятые работы с фото, планы и счета на следующую неделю. Заполнять ничего не нужно.</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">{files(o.n)}{o.videos ? ', из них ' + o.videos + ' видео' : ''} · {o.groups.length} {plural(o.groups.length, 'этап', 'этапа', 'этапов')}</span></div>}
                {(one ? o.groups : o.groups.slice(0, 1)).map((g) => <Stage key={g.stage} g={g} limit={one ? 0 : 3} view={view} />)}
                {!one && o.groups.length > 1 && <button type="button" className="lw-btn-l lw-pmore" onClick={() => setTab(o.pid)}>Все фото объекта · {files(o.n)}</button>}
                {!o.groups.length && <div className="cv-w cv-dlcard is-quiet"><div className="lab">Клиент пока ничего не видит: фото появятся после приёмки первой работы с фото.</div></div>}
              </div>))}
          </div>
        </div>
      </Modal>);
  }

  W.PhotosW = PhotosW;
})();
