// T2 Falcon Admin — Templates list (tabs, table, row menu)

const { useState: useStateL, useRef: useRefL, useEffect: useEffectL, useLayoutEffect: useLayoutEffectL } = React;

// Status pill mapping
const TplStatusPill = ({ status, t }) => {
  const map = {
    approved: { cls: 'approved', label: t.tplStatusApproved },
    pending:  { cls: 'pending',  label: t.tplStatusPending },
    rejected: { cls: 'rejected', label: t.tplStatusRejected },
    review:   { cls: 'review',   label: t.tplStatusInReview },
    deleted:  { cls: 'deleted',  label: t.tplStatusDeleted },
  };
  const m = map[status] || map.pending;
  return <span className={`tpl-pill ${m.cls}`}><span className="dot"></span>{m.label}</span>;
};

// Checker cell (name + italic stat)
const TplCheckerCell = ({ checker, t }) => {
  // Null/undefined checker → "NA" (no second line)
  if (checker == null) {
    return <div className="tpl-checker na"><span className="name">{t.tplStatusNA || 'NA'}</span></div>;
  }
  // Pending review — no decision yet → "---" with the italic "Pending" label beneath.
  if (checker.status === 'pending') {
    return (
      <div className="tpl-checker pending">
        <span className="name">---</span>
        <span className="stat">{t.tplStatusPending}</span>
      </div>
    );
  }
  const statMap = {
    approved: { cls: 'approved', label: t.tplStatusApproved },
    pending:  { cls: 'pending',  label: t.tplStatusPending },
    rejected: { cls: 'rejected', label: t.tplStatusRejected },
  };
  const stat = statMap[checker.status];
  // Placeholder name "---" → render dashes + the italic stat below
  if (!checker.name || checker.name === '---') {
    return (
      <div className={`tpl-checker ${stat ? stat.cls : 'muted'}`}>
        <span className="name">---</span>
        {stat && <span className="stat">{stat.label}</span>}
      </div>
    );
  }
  return (
    <div className={`tpl-checker ${stat ? stat.cls : 'pending'}`}>
      <span className="name">{checker.name}</span>
      <span className="stat">{(stat || statMap.pending).label}</span>
    </div>
  );
};

// Shared with chip (first name + +N). On hover, a fixed-positioned tooltip
// shows the full list of names with check icons. Uses position: fixed so it
// escapes the table's overflow container.
const TplSharedWithChip = ({ list, extra, t }) => {
  const wrapRef = useRefL(null);
  const [tipPos, setTipPos] = useStateL(null); // null when hidden, {top,right} when shown
  useEffectL(() => {
    if (!tipPos) return;
    const onDoc = (e) => { if (wrapRef.current && !wrapRef.current.contains(e.target)) setTipPos(null); };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, [tipPos]);
  if (!list || list.length === 0) return <span className="tpl-shared-pill no-extra">---</span>;
  const first = list[0];
  const hasMore = extra > 0 || list.length > 1;

  const toggleTip = (e) => {
    e.stopPropagation();
    if (!hasMore || !wrapRef.current) return;
    if (tipPos) { setTipPos(null); return; }
    const r = wrapRef.current.getBoundingClientRect();
    setTipPos({ top: r.bottom + 6, right: window.innerWidth - r.right });
  };

  return (
    <span
      ref={wrapRef}
      className="tpl-shared-wrap"
      onClick={(e) => e.stopPropagation()}
    >
      <span
        className={`tpl-shared-pill ${extra > 0 ? '' : 'no-extra'} ${hasMore ? 'clickable' : ''}`}
        onClick={toggleTip}
      >
        <span>{first}</span>
        {extra > 0 && <span className="more">+{extra}</span>}
      </span>
      {hasMore && tipPos && (
        <div
          className="tpl-shared-tooltip"
          role="dialog"
          style={{ position: 'fixed', top: tipPos.top, right: tipPos.right }}
        >
          <div className="tpl-shared-tooltip-title">{(t && t.tplSharedWithMore) || 'Shared with more'}</div>
          <div className="tpl-shared-tooltip-list">
            {list.map((name, i) => (
              <div key={i} className="tpl-shared-tooltip-item">
                <span className="check">
                  <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12" /></svg>
                </span>
                <span>{name}</span>
              </div>
            ))}
          </div>
        </div>
      )}
    </span>
  );
};

// Status by Meta cell
const TplMetaStatusCell = ({ status, quality, t }) => {
  if (status === '---') return <span className="tpl-meta-status">---</span>;
  if (status === 'NA')  return <span className="tpl-meta-status">{t.tplStatusNA}</span>;
  if (status === 'Rejected' || status === 'rejected') return <span className="tpl-meta-status rejected">{t.tplStatusRejected}</span>;
  if (status === 'In-Review') return <span className="tpl-meta-status">{t.tplStatusInReview}</span>;
  if (status === 'Active Quality Pending') return <span className="tpl-meta-status">{t.tplStatusActiveQP}</span>;
  if (status === 'Active - High Quality') return <span className="tpl-meta-status">{t.tplStatusActiveHQ}</span>;
  if (status === 'Active - Medium Quality') return <span className="tpl-meta-status">{t.tplStatusActiveMQ}</span>;
  if (status === 'Active - Low Quality') return <span className="tpl-meta-status">{t.tplStatusActiveLQ}</span>;
  return <span className="tpl-meta-status">{status}</span>;
};

// Edit is allowed ONLY for an internally-rejected template — i.e. rejected by a Checker
// (Level 1 or 2), NOT by Meta, and therefore never submitted to the third party. Every
// other state (Approved, Pending, Rejected-by-Meta, Deleted, Restricted) is NOT editable.
// The "logged-in user is the Maker" part is enforced by the view: only the Client (maker)
// view is non-readOnly; the Falcon (checker) view is readOnly, so Edit never shows there.
const tplCanEdit = (tpl) => {
  if (!tpl || tpl.restricted) return false;
  // Edit is offered ONLY when the template was rejected INTERNALLY by a Checker (Level 1 or 2)
  // — driven by the checker data, not the final status. (The overall status may still read
  // "Pending" if only one checker has rejected.) Approved, fully-pending and Meta-rejected
  // templates are NOT editable.
  const rejectedByChecker = (tpl.checker1 && tpl.checker1.status === 'rejected')
                         || (tpl.checker2 && tpl.checker2.status === 'rejected');
  return (tpl.channel === 'WhatsApp' || tpl.channel === 'IVR Voice') && rejectedByChecker;
};

// Share is the COMPLEMENT of Edit: shown for a WhatsApp/IVR template whenever Edit is NOT
// offered (any state except internally-rejected — Approved, Pending, Meta-rejected…).
// It opens the Edit layout read-only with only "Shared With" enabled. Not for deleted.
const tplCanShare = (tpl) => !!tpl
  && (tpl.channel === 'WhatsApp' || tpl.channel === 'IVR Voice')
  && tpl.status !== 'rejected'   // NOT when the final status is rejected (Meta / internal) …
  && tpl.status !== 'deleted'
  && !tplCanEdit(tpl);           // … and not an internally-rejected (editable) template

// Row actions menu — reuses Hierarchy's .row-menu / .row-menu-item classes
// so position and styling match the Organization Hierarchy users table.
const TplRowMenu = ({ open, onClose, onView, onEdit, onShare, onDelete, readOnly, onlyDetails, canEdit, canShare, t }) => {
  const menuRef = useRefL(null);
  const [pos, setPos] = useStateL(null);
  // Position the menu with FIXED viewport coordinates computed from the kebab, so it is
  // never clipped by the table's overflow (.table-panel: hidden / .table-scroll: auto).
  // Opens below the kebab; flips above when there isn't room (last rows).
  useLayoutEffectL(() => {
    if (!open) { setPos(null); return; }
    const el = menuRef.current;
    if (!el) return;
    const cell = el.closest('.tpl-actions-cell');
    const kebab = cell && cell.querySelector('.tpl-action-btn');
    if (!kebab) return;
    const kr = kebab.getBoundingClientRect();
    const mh = el.offsetHeight || 150;
    const mw = el.offsetWidth || 180;
    const openUp = (window.innerHeight - kr.bottom) < (mh + 16) && kr.top > (mh + 16);
    const top = openUp ? Math.max(8, kr.top - mh - 6) : (kr.bottom + 6);
    const left = Math.max(8, Math.min(kr.right - mw, window.innerWidth - mw - 8));
    setPos({ top, left });
  }, [open]);
  // Close on scroll / resize so the fixed menu never floats away from its row.
  useEffectL(() => {
    if (!open) return;
    const close = () => onClose && onClose();
    window.addEventListener('scroll', close, true);
    window.addEventListener('resize', close);
    return () => { window.removeEventListener('scroll', close, true); window.removeEventListener('resize', close); };
  }, [open]);
  if (!open) return null;
  const style = pos
    ? { position: 'fixed', top: pos.top, left: pos.left, insetInlineEnd: 'auto', bottom: 'auto', marginTop: 0 }
    : { visibility: 'hidden' };
  return (
    <div ref={menuRef} className="row-menu tpl-row-menu" style={style} onClick={(e) => e.stopPropagation()}>
      <button className="row-menu-item" onClick={() => { onView && onView(); onClose(); }}>
        <IcInfo size={14} stroke={1.5} />
        <span>{readOnly ? t.tplViewDetailsOnly : t.tplMoreDetails}</span>
      </button>
      {!readOnly && !onlyDetails && (
        <>
          {canEdit ? (
            <button className="row-menu-item" onClick={() => { onEdit && onEdit(); onClose(); }}>
              <IcEdit size={14} stroke={1.5} />
              <span>{t.tplEdit}</span>
            </button>
          ) : canShare ? (
            <button className="row-menu-item" onClick={() => { onShare && onShare(); onClose(); }}>
              <IcUsers size={14} stroke={1.5} />
              <span>{t.tplShare || 'Share'}</span>
            </button>
          ) : null}
          <button className="row-menu-item danger" onClick={() => { onDelete && onDelete(); onClose(); }}>
            <IcClose size={14} stroke={2} />
            <span>{t.tplDelete}</span>
          </button>
        </>
      )}
    </div>
  );
};

// ---- Main list page ----
// NOTE: tabs, Create button, and Filter/Search controls are now rendered in
// templates.jsx (alongside the node-header). This component only renders the
// bordered table-panel + table + pagination.
const TemplatesList = ({
  tab = 'templates',
  templates,
  search,
  setSearch,
  channel,
  setChannel,
  t,
  onView,
  onEdit,
  onShare,
  onCreateOpen,
  openMenuId,
  setOpenMenuId,
  pushToast,
  readOnly = false,
  isClient = false,
}) => {

  const [tplPage, setTplPage] = useStateL(1);
  const [tplPageSize, setTplPageSize] = useStateL(20);

  // Local UI state for the toolbar (filter dropdown). Create button lives in node-header.
  const [filterOpen, setFilterOpen] = useStateL(false);
  const filterRef = useRefL(null);
  useEffectL(() => {
    const onDoc = (e) => {
      if (filterRef.current && !filterRef.current.contains(e.target)) setFilterOpen(false);
    };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, []);

  const channels = ['all', 'WhatsApp', 'IVR Voice', 'SMS', 'Email'];
  const channelLabel = (c) => c === 'all' ? t.allChannels
    : c === 'WhatsApp'  ? t.chWhatsApp
    : c === 'IVR Voice' ? (t.chIvrVoice || 'IVR Voice')
    : c === 'SMS'       ? t.chSMS
    : t.chEmail;

  // Filter
  const visible = templates.filter(tpl => {
    if (channel !== 'all' && tpl.channel !== channel) return false;
    if (search && !tpl.name.toLowerCase().includes(search.toLowerCase())) return false;
    return true;
  });

  // Active-tab title shown in the table head bar (parity with Hierarchy's "Users" title)
  const tabTitle = tab === 'pending' ? t.tabPendingReview
                 : tab === 'shared'  ? t.tabSharedTemplates
                 : t.tabTemplates;

  return (
    <div className={`table-panel tpl-table-panel ${readOnly ? 'falcon' : 'client'}`}>
      {/* Active tab title row + inline toolbar (search · filter) — Create button stays in the node-header */}
      <div className="table-head-bar tpl-head-bar tpl-head-bar-toolbar">
        <div className="table-head-title">{tabTitle}</div>
        <div className="tpl-list-toolbar">
          <div className="tpl-search">
            <IcSearch size={14} stroke={1.8} />
            <input
              type="text"
              placeholder={t.searchTemplates}
              value={search || ''}
              onChange={(e) => setSearch && setSearch(e.target.value)}
            />
          </div>
          <div className="tpl-filter" ref={filterRef}>
            <button className="tpl-filter-btn" onClick={() => setFilterOpen(o => !o)}>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
                <IcFilter size={14} stroke={1.7} />
                {channelLabel(channel)}
              </span>
              <IcChevronDown size={14} stroke={1.7} className="chev" />
            </button>
            {filterOpen && (
              <div className="tpl-filter-menu">
                {channels.map(c => (
                  <div
                    key={c}
                    className={`tpl-filter-item ${channel === c ? 'selected' : ''}`}
                    onClick={() => { setChannel && setChannel(c); setFilterOpen(false); }}
                  >
                    {channelLabel(c)}
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>
      </div>
      {/* Table */}
      <div className="table-scroll tpl-table-wrap">
        <table className="tpl-table">
          <thead>
            <tr>
              <th className="col-id">{t.colId}</th>
              <th>{t.colTemplateName}</th>
              <th>{t.colCommchannelType}</th>
              <th>{t.colServicesType}</th>
              <th>{t.language}</th>
              {tab !== 'pending' && <th>{t.colTplStatus}</th>}
              <th>{t.colCheckerL1}</th>
              <th>{t.colCheckerL2}</th>
              {tab !== 'pending' && <th>{t.colStatusByMeta}</th>}
              <th>{t.colReferenceId}</th>
              <th>{t.colWabaAccount}</th>
              <th>{t.colCreatedBy}</th>
              <th>{t.colCreationDate}</th>
              <th>{t.colSharedWith}</th>
              <th style={{ textAlign: 'center' }}>{t.colTplActions}</th>
            </tr>
          </thead>
          <tbody>
            {visible.slice((tplPage - 1) * tplPageSize, tplPage * tplPageSize).map(tpl => (
              <tr key={tpl.id}>
                <td className="col-id">{tpl.id}</td>
                <td className="col-name"><span className="name-text">{tpl.name}</span></td>
                <td>{tpl.channel}</td>
                <td>{tpl.serviceType}</td>
                <td>{tpl.language}</td>
                {tab !== 'pending' && <td><TplStatusPill status={tpl.status} t={t} /></td>}
                <td><TplCheckerCell checker={tpl.checker1} t={t} /></td>
                <td><TplCheckerCell checker={tpl.checker2} t={t} /></td>
                {tab !== 'pending' && <td><TplMetaStatusCell status={tpl.statusByMeta} t={t} /></td>}
                <td>{tpl.referenceId}</td>
                <td>{tpl.wabaAccount || '—'}</td>
                <td>{tpl.createdBy}</td>
                <td>
                  <div className="tpl-date">
                    <span className="d">{tplFmtDate(tpl.creationDate)}</span>
                    <span className="t">{tpl.creationTime}</span>
                  </div>
                </td>
                <td><TplSharedWithChip list={tpl.sharedWith} extra={tpl.sharedWithCount} t={t} /></td>
                <td className="tpl-actions-cell" onClick={(e) => e.stopPropagation()}>
                  <button
                    className={`tpl-action-btn ${openMenuId === tpl.id ? 'open' : ''}`}
                    onClick={(e) => { e.stopPropagation(); setOpenMenuId(openMenuId === tpl.id ? null : tpl.id); }}
                  >
                    <IcMore size={16} stroke={1.7} />
                  </button>
                  <TplRowMenu
                    open={openMenuId === tpl.id}
                    onClose={() => setOpenMenuId(null)}
                    onView={() => onView(tpl)}
                    onEdit={() => onEdit ? onEdit(tpl) : pushToast('Edit template flow not implemented in this mock')}
                    onShare={() => onShare && onShare(tpl)}
                    onDelete={() => pushToast(t.toastTplDeleted)}
                    readOnly={readOnly}
                    onlyDetails={tab === 'pending' || tab === 'shared'}
                    canEdit={tplCanEdit(tpl)}
                    canShare={tplCanShare(tpl)}
                    t={t}
                  />
                </td>
              </tr>
            ))}
            {visible.length === 0 && (
              <tr><td colSpan={tab === 'pending' ? 13 : 15} style={{ textAlign: 'center', padding: 40, color: 'var(--text-muted)' }}>No templates match the current filters.</td></tr>
            )}
          </tbody>
        </table>
      </div>
      <TablePagination
        total={visible.length}
        page={tplPage}
        pageSize={tplPageSize}
        onPageChange={setTplPage}
        onPageSizeChange={(n) => { setTplPageSize(n); setTplPage(1); }}
        t={t}
      />
    </div>
  );
};

Object.assign(window, { TemplatesList, TplStatusPill, TplCheckerCell, TplSharedWithChip, TplMetaStatusCell });
