// PartnersV6 — 取引先一覧: [顧客][関係者][業者] タブ（取引実績から導出・マスタ書換なし）。
// 行は DB(rpc_list_partners) から読む。固定11件は架空の電話番号だったので捨てた。

// K18-31: 池田さん版(PartnersV6)の列に合わせ、No. を外し、取引と精算を 2 列に分けた。
// K18-32: 社内担当(rpc_list_partners の ownerUser・0114)の列を足した。
// K18-33: 契約(contractStatus)・確認(verifiedAt)の列を足した(0115。部品は OrgFields.jsx)。
// 既定の報告先は main の機能として残す(池田さん版には無い・docs/21 §0)。
// 名前と既定の報告先に下限を置く(下限なしの 1.4fr だと固定列 574px に押されて名前が約 10px まで潰れた)。
// 列の合計(下限 810px + 間 72px + 左右 28px)より狭いカードでは横にスクロールする。
const PV_COLS = "minmax(140px,1.4fr) 78px 70px 76px 64px 104px 84px 58px 40px minmax(96px,1fr)";
const PV_MIN_W = 910;
const PV_NARROW_KEEP = ["名前","種別","取引","関連案件"];
// スマホ幅(768px 以下。サイドバーがドロワーになる幅と同じ)では 名前・種別・取引・関連案件 だけにする。
// 見出しと各行は別々の grid なので、列幅は固定値で揃える(auto だと行ごとにずれる)。
const PV_CSS = "@media (max-width: 768px){"
  + ".mr-pv-inner{min-width:0 !important}"
  + ".mr-pv-grid{grid-template-columns:minmax(0,1fr) 64px 60px 44px !important}"
  + ".mr-pv-wide{display:none !important}"
  + "}";

function PvChip({ tone, children }) {
  const T = {
    green:["var(--success)","var(--success-muted)","var(--success-border)"],
    survey:["var(--status-survey)","var(--status-survey-muted)","var(--status-survey-border)"],
    brand:["var(--brand)","var(--brand-muted)","var(--brand-border)"],
    neutral:["var(--muted-foreground)","var(--muted)","var(--border)"],
  }[tone||"neutral"];
  return <span style={{ display:"inline-flex", alignItems:"center", height:16, padding:"0 7px", borderRadius:"var(--radius-sm)",
    fontSize:"var(--text-caption)", fontWeight:600, whiteSpace:"nowrap", flexShrink:0, color:T[0], background:T[1], border:"1px solid "+T[2] }}>{children}</span>;
}

function pvFetch(query, kind, limit) {
  const cloud = typeof window !== "undefined" ? window.MarurouCloud : null;
  if (!cloud || typeof cloud.listPartners !== "function") {
    return Promise.resolve({ rows: [], counts: { "すべて":0, "顧客":0, "関係者":0, "業者":0 }, truncated: false, offline: true });
  }
  return cloud.listPartners({ query: query || null, kind: kind === "すべて" ? null : kind, limit: limit || 100 });
}

function PartnersV6({ onToast, onOpen }) {
  const [kind, setKind] = React.useState("すべて");
  const [q, setQ] = React.useState("");
  const [rows, setRows] = React.useState(null);   // null=読込中
  const [counts, setCounts] = React.useState({ "すべて":0, "顧客":0, "関係者":0, "業者":0 });
  const [truncated, setTruncated] = React.useState(false);
  const [err, setErr] = React.useState("");
  const tabs = ["すべて","顧客","関係者","業者"];

  const load = React.useCallback(async () => {
    try {
      const r = await pvFetch(q, kind, 100);
      const list = (r && r.rows) || [];
      setRows(list);
      setCounts(r && r.counts ? r.counts : { "すべて":0, "顧客":0, "関係者":0, "業者":0 });
      setTruncated(!!(r && r.truncated));
      setErr(r && r.offline ? "取引先マスタを読み込めていません（接続の設定がありません）。" : "");
      // 検索・手配・報告先の推定が同じ名簿を見る。ここにだけ実体を置く。
      window.PV_ROWS = list;
    } catch (e) {
      setRows([]);
      setErr((e && e.message) || "取引先を読めませんでした");
    }
  }, [q, kind]);
  React.useEffect(() => { const t = setTimeout(load, q ? 250 : 0); return () => clearTimeout(t); }, [load]);

  const dealLabel = p => p.kind==="業者"?"発注先" : p.cont==="継続"?"継続" : p.cont==="スポット"?"スポット" : null;
  const dealTone = p => p.kind==="業者"?"brand" : p.cont==="継続"?"green" : p.cont==="スポット"?"survey" : "neutral";
  return (
    <div className="mr-page-pad" style={{ padding:"20px 24px 32px 20px" }}>
      <style>{PV_CSS}</style>
      <SectionTitle sub="顧客／関係者／業者＝取引実績から導出（マスタ書換なし・昇格操作なし）">取引先一覧</SectionTitle>

      <div style={{ display:"flex", gap:10, alignItems:"center", flexWrap:"wrap", marginBottom:12 }}>
        <div style={{ display:"flex", gap:5, flexWrap:"wrap" }}>
          {tabs.map(k=>(
            <button key={k} onClick={()=>setKind(k)} style={{
              all:"unset", cursor:"pointer", fontFamily:"var(--font-sans)", fontSize:"var(--text-body-sm)", fontWeight:kind===k?700:500,
              padding:"5px 11px", borderRadius:"var(--radius-full)", whiteSpace:"nowrap",
              border:"1px solid "+(kind===k?"var(--brand)":"var(--border)"),
              background:kind===k?"var(--brand-muted)":"var(--card)", color:kind===k?"var(--brand)":"var(--muted-foreground)",
              transition:"all var(--duration-fast) var(--easing)",
            }}>{k}<span className="mono" style={{ fontSize:"var(--text-caption)", marginLeft:5, color:kind===k?"var(--brand)":"var(--foreground-subtle)" }}>{counts[k]||0}</span></button>
          ))}
        </div>
        <AfInput value={q} onChange={e=>setQ(e.target.value)} placeholder="名前・フリガナ・電話で絞込..." style={{ width:200, marginLeft:"auto" }} />
      </div>

      <AfCard pad={0} style={{ overflowX:"auto", overflowY:"hidden" }}>
        <div className="mr-pv-inner" style={{ minWidth:PV_MIN_W }}>
        <div className="mr-pv-grid" style={{ display:"grid", gridTemplateColumns:PV_COLS, gap:8, padding:"9px 14px", background:"var(--muted)", borderBottom:"1px solid var(--border-strong)", position:"sticky", top:0, zIndex:1 }}>
          {["名前","種別","取引","精算","関連案件","連絡先","社内担当","契約","確認","既定の報告先"].map((h,i)=>(
            <span key={h} className={PV_NARROW_KEEP.includes(h) ? undefined : "mr-pv-wide"} style={{ fontSize:"var(--text-caption)", fontWeight:600, letterSpacing:"0.03em", color:"var(--muted-foreground)", textAlign:h==="関連案件"?"right":"left" }}>{h}</span>
          ))}
        </div>
        {err && <div style={{ padding:18, fontSize:"var(--text-body-md)", color:"var(--destructive)" }}>{err}</div>}
        {rows===null && !err && <div style={{ padding:18, fontSize:"var(--text-body-md)", color:"var(--foreground-subtle)" }}>読み込み中…</div>}
        {rows && rows.length===0 && !err && <div style={{ padding:18, fontSize:"var(--text-body-md)", color:"var(--foreground-subtle)" }}>
          {kind==="顧客" && !q ? "請求先が付いた取引先がここに出ます。いま精算明細の宛先はまだ入っていません。" : "該当なし"}
        </div>}
        {rows && rows.map((p,i)=>(
          <button key={p.id||p.name} className="mr-pv-grid" onClick={()=>onOpen&&onOpen(p)} style={{
            all:"unset", boxSizing:"border-box", width:"100%", display:"grid", gridTemplateColumns:PV_COLS, gap:8,
            padding:"10px 14px", fontFamily:"var(--font-sans)", cursor:"pointer", alignItems:"center",
            borderBottom:i<rows.length-1?"1px solid var(--border)":"none", transition:"background var(--duration-fast) var(--easing)",
          }}
            onMouseEnter={e=>e.currentTarget.style.background="var(--accent)"}
            onMouseLeave={e=>e.currentTarget.style.background="transparent"}>
            <span style={{ fontSize:"var(--text-body-md)", fontWeight:600, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{p.name}</span>
            <PvChip>{p.type||"—"}</PvChip>
            <span style={{ display:"flex", alignItems:"center", minWidth:0 }}>
              {dealLabel(p) ? <PvChip tone={dealTone(p)}>{dealLabel(p)}</PvChip> : <span style={{ fontSize:"var(--text-body-sm)", color:"var(--foreground-subtle)" }}>—</span>}
            </span>
            {/* 精算(業者は支払): 規定の請求パターン(default_billing_pattern) */}
            <span className="mr-pv-wide" style={{ fontSize:"var(--text-body-sm)", color:p.contract?"var(--muted-foreground)":"var(--foreground-subtle)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{p.contract || "—"}</span>
            <span className="mono" style={{ fontSize:"var(--text-body-md)", fontWeight:600, textAlign:"right" }}>{p.cases||0}</span>
            <span className="mono mr-pv-wide" style={{ fontSize:"var(--text-body-sm)", color:"var(--muted-foreground)" }}>{p.tel||"—"}</span>
            <span className="mr-pv-wide" style={{ fontSize:"var(--text-body-sm)", color:"var(--muted-foreground)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{(window.orgOwnerName && window.orgOwnerName(p)) || "—"}</span>
            <span className="mr-pv-wide">{window.OrgContractChip ? <window.OrgContractChip p={p} /> : "—"}</span>
            <span className="mr-pv-wide">{window.OrgVerifiedMark ? <window.OrgVerifiedMark p={p} /> : "—"}</span>
            <span className="mr-pv-wide" style={{ fontSize:"var(--text-caption)", color:"var(--foreground-subtle)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>
              {(p.reportTo||[]).join("・") || "—"}
            </span>
          </button>
        ))}
        </div>
      </AfCard>

      <div style={{ fontSize:"var(--text-caption)", color:"var(--muted-foreground)", marginTop:12, lineHeight:1.7 }}>
        受注で請求が立てば自動で顧客に現れる。継続＝関連案件が2件以上・スポット＝1件。名前検索では未取引の取引先も出ます。
        {truncated ? " 表示は上位100社です。名前で絞り込んでください。" : ""}
        行タップで取引先詳細（連絡先・関連案件）へ。
      </div>
    </div>
  );
}

/* 既定の報告先：seed の依頼者規定 → 無ければ依頼者のみ。
   固定11件の名前部分一致は、実在しない会社に報告先が付くので使わない。
   語彙と旧語の読み替えは atoms.jsx(resolveReportTo。「依頼担当者」旧「依頼者」→ 取引先名)。 */
const pvReportTo = client => {
  if (!client) return [];
  const orgs = (window.MStore && window.MStore.masters) ? (window.MStore.masters().orgs || []) : [];
  const hit = orgs.find(o => o.name === client);
  const resolve = window.resolveReportTo || ((l, c) => (Array.isArray(l) ? l : []).map(x => (x === "依頼担当者" || x === "依頼者") ? c : x));
  const d = hit && Array.isArray(hit.defaultReportTo) ? resolve(hit.defaultReportTo, client) : [];
  if (d.length) return d;
  return [client];
};
Object.assign(window, { PartnersV6, pvReportTo, pvFetch });
