// Tracks — 調査／工事／保険／精算 の一覧＋詳細（進行＝トラック単位・案件詳細と連動）

const TR_KINDS = {
  survey: { label:"調査", tone:"survey" },
  work:   { label:"工事", tone:"brand" },
  ins:    { label:"保険", tone:"warn" },
  settle: { label:"精算", tone:"success" },
};
/* 進行データは store（MStore.trackRows）から導出 */
const TR_STATE = { done:{label:"完了",c:"var(--success)"}, now:{label:"進行中",c:"var(--brand)"}, waiting:{label:"相手待ち",c:"var(--warning)"}, wait:{label:"着手待ち",c:"var(--foreground-subtle)"} };

function TrRail({ rail }) {
  return (
    <div style={{ display:"flex", alignItems:"flex-start", gap:2, flexWrap:"wrap", marginTop:8 }}>
      {rail.map(([n,s,date],i)=>{
        const done=s==="done", now=s==="now", wait=s==="waiting", skip=s==="skip", hot=now||wait;
        const col = done?"var(--success)" : now?"var(--brand)" : wait?"var(--warning)" : "var(--border-strong)";
        return (
          <React.Fragment key={i}>
            <div style={{ display:"flex", flexDirection:"column", alignItems:"center", gap:3, minWidth:hot?58:46 }}>
              <span style={{ width:hot?12:8, height:hot?12:8, borderRadius:999, boxSizing:"border-box",
                background: done||now||wait ? col : "var(--card)", border:"2px solid "+col,
                display:"inline-flex", alignItems:"center", justifyContent:"center" }}>
                {done && <span style={{ fontSize:6, color:"#fff", fontWeight:700, lineHeight:1 }}>✓</span>}
              </span>
              <span style={{ fontSize:"var(--text-caption)", fontWeight:hot?700:400, whiteSpace:"nowrap", textAlign:"center", lineHeight:1.3,
                textDecoration:skip?"line-through":"none",
                color: done?"var(--muted-foreground)" : now?"var(--foreground)" : wait?"var(--warning)" : "var(--foreground-subtle)" }}>{n}</span>
              <span className="mono" style={{ fontSize:9, whiteSpace:"nowrap",
                color: done?"var(--success)" : now?"var(--brand)" : wait?"var(--warning)" : "transparent" }}>{date||"·"}</span>
            </div>
            {i<rail.length-1 && <span style={{ height:2, flex:"1 0 6px", maxWidth:18, borderRadius:1, marginTop:hot?5:3,
              background: done?"var(--success-border)":"var(--border)" }} />}
          </React.Fragment>
        );
      })}
    </div>
  );
}

const TR_COLS = {
  survey: { grid:"26px minmax(120px,1.3fr) 64px minmax(84px,1fr) 68px 76px 50px", heads:["No.","案件・物件","対象","調査業者","現在地","状態","期限"] },
  work:   { grid:"26px minmax(120px,1.3fr) 44px minmax(76px,0.9fr) minmax(92px,1fr) 68px 84px", heads:["No.","案件・物件","号室","工事内容","施工者","現在地","状態"] },
  ins:    { grid:"26px minmax(120px,1.3fr) minmax(84px,1fr) minmax(92px,1fr) 64px 76px 50px", heads:["No.","案件・物件","保険会社","契約者","現在地","状態","期限"] },
  settle: { grid:"26px minmax(120px,1.3fr) minmax(84px,1fr) minmax(88px,1fr) 64px 76px 68px", heads:["No.","案件・物件","対象","精算方式","現在地","状態","請求額"] },
};

function TracksList({ kind, onOpen, onOpenCase, initialFilter }) {
  const K = TR_KINDS[kind], C = TR_COLS[kind];
  const [f, setF] = React.useState(initialFilter||"すべて");
  React.useEffect(()=>{ if(initialFilter) setF(initialFilter); }, [initialFilter]);
  const store = window.useMStore ? window.useMStore() : null;
  const all = React.useMemo(()=> (window.MStore ? window.MStore.trackRows() : []).filter(r=>r.kind===kind), [kind, store]);
  // ページング2段目(決-1・0033)。この一覧は案件横断(caseIdでの絞り込み無し)なので、
  // 案件を直近N件だけ読み込むようになった影響を最も受ける ─ 読み込んでいない
  // 古い案件のトラックはここに出ない。件数見出しを「読み込んだ分の件数」と
  // 正直に出し、全件がもっと多ければそれも添える(見えている数を全件のように
  // 見せない)。個別の古い案件は検索(⌘K)で探して開ける(案件名・受付番号)。
  const loadedCases = store ? store.cases.length : 0;
  const totalCases = window.MStore ? (window.MStore.counts() || {}).cases : null;
  const scopeNote = totalCases != null && totalCases > loadedCases
    ? `（案件は直近${loadedCases}件・全${totalCases}件中。他の案件は検索で探せます）` : "";
  const filters = ["すべて","進行中","相手待ち","滞留","完了"];
  const match = r => f==="すべて" || (f==="進行中"&&r.state==="now") || (f==="相手待ち"&&r.state==="waiting") || (f==="滞留"&&r.mk==="delay") || (f==="完了"&&r.state==="done");
  const rows = all.filter(match);
  const cnt = x => all.filter(r=> x==="すべて" || (x==="進行中"&&r.state==="now") || (x==="相手待ち"&&r.state==="waiting") || (x==="滞留"&&r.mk==="delay") || (x==="完了"&&r.state==="done")).length;
  const cell = (r,i) => {
    if(kind==="survey") return [r.target, r.vendor, r.step, null, r.due];
    if(kind==="work") return [r.target, r.work, r.vendor, r.step, null];
    if(kind==="ins") return [r.vendor, r.holder, r.step, null, r.due];
    return [r.target, r.settleWay, r.step, null, yen(r.billed)];
  };
  return (
    <div style={{ padding:"20px 24px 32px 20px" }}>
      <div style={{ display:"flex", alignItems:"center", gap:10, flexWrap:"wrap", marginBottom:12 }}>
        <div style={{ display:"flex", gap:5, flexWrap:"wrap" }}>
          {filters.map(x=>(
            <button key={x} onClick={()=>setF(x)} style={{ all:"unset", cursor:"pointer", fontFamily:"var(--font-sans)",
              fontSize:"var(--text-body-sm)", fontWeight:f===x?700:500, padding:"5px 11px", borderRadius:"var(--radius-full)", whiteSpace:"nowrap",
              border:"1px solid "+(f===x?"var(--brand)":"var(--border)"),
              background:f===x?"var(--brand-muted)":"var(--card)", color:f===x?"var(--brand)":"var(--muted-foreground)" }}>
              {x}<span className="mono" style={{ fontSize:"var(--text-caption)", marginLeft:5, color:f===x?"var(--brand)":"var(--foreground-subtle)" }}>{cnt(x)}</span>
            </button>
          ))}
        </div>
        <span style={{ marginLeft:"auto", fontSize:"var(--text-body-sm)", color:"var(--muted-foreground)" }}>
          {K.label}の進行 <span className="mono">{rows.length}</span>件 ／ 行タップで進行詳細
        </span>
      </div>
      <div style={{ overflowX:"auto" }}>
        <div style={{ minWidth:640 }}>
          <AfCard pad={0} style={{ overflow:"hidden" }}>
            <div style={{ display:"grid", gridTemplateColumns:C.grid, gap:6, padding:"9px 12px", background:"var(--muted)", borderBottom:"1px solid var(--border-strong)", position:"sticky", top:0, zIndex:1 }}>
              {C.heads.map((h,i)=><span key={h} style={{ fontSize:"var(--text-caption)", fontWeight:600, letterSpacing:"0.03em", color:"var(--muted-foreground)", textAlign:i===C.heads.length-1&&kind==="settle"?"right":"left", whiteSpace:"nowrap" }}>{h}</span>)}
            </div>
            {rows.length===0 && <div style={{ padding:18, fontSize:"var(--text-body-md)", color:"var(--foreground-subtle)" }}>該当なし</div>}
            {rows.map((r,i)=>{
              const sd = TR_STATE[r.state], cells = cell(r,i);
              return (
                <button key={r.id} onClick={()=>onOpen&&onOpen(r)} style={{ all:"unset", boxSizing:"border-box", width:"100%",
                  display:"grid", gridTemplateColumns:C.grid, gap:6, padding:"10px 12px", cursor:"pointer", alignItems:"center",
                  fontFamily:"var(--font-sans)", 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 className="mono" style={{ fontSize:"var(--text-body-sm)", color:"var(--foreground-subtle)" }}>{i+1}</span>
                  <span style={{ display:"flex", alignItems:"center", gap:5, minWidth:0 }}>
                    <span style={{ fontSize:"var(--text-body-md)", fontWeight:600, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{r.prop}</span>
                    {r.mk==="delay" && <ScChip tone="warn" dot>滞留</ScChip>}
                    {r.mk==="warn" && <ScChip tone="survey" dot>予兆</ScChip>}
                  </span>
                  {cells.map((v,j)=> v===null
                    ? <span key={j} style={{ display:"flex", flexDirection:"column", gap:2, minWidth:0 }}>
                        <span style={{ fontSize:"var(--text-body-sm)", fontWeight:600, color:sd.c, whiteSpace:"nowrap" }}>{sd.label}</span>
                        {r.waitLabel && <span style={{ fontSize:"var(--text-caption)", color:"var(--warning)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{r.waitLabel}</span>}
                      </span>
                    : <span key={j} className={j>=3?"mono":""} style={{ fontSize:"var(--text-body-sm)", color:j===cells.length-1?"var(--muted-foreground)":"var(--foreground)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap", textAlign:kind==="settle"&&j===cells.length-1?"right":"left" }}>{v}</span>
                  )}
                </button>
              );
            })}
          </AfCard>
        </div>
      </div>
      <div style={{ fontSize:"var(--text-caption)", color:"var(--muted-foreground)", marginTop:8, lineHeight:1.7 }}>
        {K.label}の進行（トラック）を横断で並べた一覧。案件をまたいで同じ工程だけを見るための面で、現在地・状態は案件詳細の{K.label}パネルと同一データ。{scopeNote}
      </div>
    </div>
  );
}

/* K18-20(0112): 進行詳細にもトラックの先方担当(業者側/保険会社側)を出す。値は案件の個別取得
   (rpc_case_detail_context の trackContacts)で、まだなら useTrackContacts が取りに行く。
   K-28(0117): 案件詳細と同じ「付け替え/設定」(TrackContactPicker.jsx)。候補の会社は今の担当の所属(無ければ名前で探す)。 */
function TrTrackContacts({ r, Line, onToast }) {
  const list = window.useTrackContacts ? window.useTrackContacts(r.caseId, r.id) : undefined;
  const dbId = window.trackDbIdOf ? window.trackDbIdOf(r.caseId, r.id) : null;
  if (window.TrackContactField && list !== undefined && dbId) {
    return <TrackContactField caseId={r.caseId} trackDbId={dbId} ready kind={r.kind} onToast={onToast} Row={Line} />;
  }
  if (!list || !list.length) return null;
  return <Line label="先方担当"><TrackContactList contacts={list} /></Line>;
}

function TrackDetail({ track, onBack, onOpenCase, onContact, onToast }) {
  if(!track) return null;
  const r = track, K = TR_KINDS[r.kind], sd = TR_STATE[r.state];
  const profit = (r.billed||0)-(r.cost||0);
  const Line = ({ label, children }) => (
    <div style={{ display:"flex", gap:10, alignItems:"baseline" }}>
      <span style={{ fontSize:"var(--text-caption)", fontWeight:600, letterSpacing:"0.04em", color:"var(--muted-foreground)", minWidth:56, flexShrink:0 }}>{label}</span>
      <span style={{ fontSize:"var(--text-body-md)", minWidth:0 }}>{children}</span>
    </div>
  );
  return (
    <div style={{ padding:"18px 24px 32px 20px", maxWidth:900 }}>
      <button onClick={onBack} style={{ all:"unset", fontFamily:"var(--font-sans)", fontSize:"var(--text-body-sm)", fontWeight:600, color:"var(--brand)", cursor:"pointer", marginBottom:12, display:"inline-block" }}>← {K.label}一覧</button>
      <div style={{ display:"flex", alignItems:"center", gap:8, flexWrap:"wrap", fontSize:"var(--text-body-sm)", color:"var(--muted-foreground)" }}>
        <ScChip tone={K.tone}>{K.label}</ScChip>
        <span className="code" style={{ color:"var(--brand)", fontWeight:600 }}>{r.id}</span>
        <span>·</span>
        <button onClick={()=>onOpenCase&&onOpenCase(r)} style={{ all:"unset", fontFamily:"var(--font-sans)", cursor:"pointer", color:"var(--brand)", fontWeight:600 }}>{r.prop} ›</button>
      </div>
      <div style={{ display:"flex", alignItems:"center", gap:10, marginTop:4, flexWrap:"wrap" }}>
        <h1 style={{ margin:0, fontSize:"var(--text-display-md)", fontWeight:700, letterSpacing:"var(--tracking-tight)" }}>
          {r.kind==="work" ? r.target+" "+r.work : r.kind==="ins" ? r.vendor : r.target}
        </h1>
        <span style={{ fontSize:"var(--text-body-md)", fontWeight:600, color:sd.c }}>{sd.label}</span>
        <ScChip tone={r.mk==="delay"?"warn":K.tone}>{r.status}</ScChip>
        {r.mk==="delay" && <ScChip tone="warn" dot>滞留</ScChip>}
      </div>
      {r.waitLabel && <div style={{ fontSize:"var(--text-body-sm)", fontWeight:600, color:"var(--warning)", marginTop:6 }}>{r.waitLabel}</div>}

      <AfCard pad={0} style={{ marginTop:12 }}>
        <div style={{ padding:"12px 14px" }}>
          <div style={{ display:"flex", alignItems:"center", gap:8 }}>
          <span style={{ fontSize:"var(--text-caption)", fontWeight:600, letterSpacing:"0.04em", color:"var(--muted-foreground)" }}>進行（受注→入金）</span>
          <ScChip>閲覧のみ</ScChip>
          <button onClick={()=>onOpenCase&&onOpenCase(r)} style={{ all:"unset", marginLeft:"auto", fontFamily:"var(--font-sans)", fontSize:"var(--text-caption)", fontWeight:700, color:"var(--brand)", cursor:"pointer" }}>案件詳細で消込む ›</button>
        </div>
          <TrRail rail={r.rail} />
        </div>
      </AfCard>

      <div style={{ display:"grid", gridTemplateColumns:"repeat(auto-fit,minmax(300px,1fr))", gap:12, marginTop:12 }}>
        <AfCard pad={0}>
          <div style={{ padding:"12px 14px", display:"flex", flexDirection:"column", gap:9 }}>
            <div style={{ fontSize:"var(--text-caption)", fontWeight:600, letterSpacing:"0.04em", color:"var(--muted-foreground)" }}>内容</div>
            {r.kind==="work" && <React.Fragment><Line label="号室"><b className="mono">{r.target}</b></Line><Line label="工事">{r.work}</Line><Line label="施工者">{r.vendor}</Line></React.Fragment>}
            {r.kind==="survey" && <React.Fragment><Line label="対象">{r.target}</Line><Line label="調査業者">{r.vendor}</Line></React.Fragment>}
            {r.kind==="ins" && <React.Fragment><Line label="保険会社">{r.vendor}</Line><Line label="契約者">{r.holder}</Line><Line label="保険種類">{r.policy}</Line><Line label="対象">{r.target}</Line></React.Fragment>}
            {r.kind==="settle" && <React.Fragment><Line label="対象">{r.target}</Line><Line label="請求先">{r.vendor}</Line></React.Fragment>}
            {r.kind!=="settle" && <TrTrackContacts r={r} Line={Line} onToast={onToast} />}
            <Line label="現在地"><b>{r.step}</b> <span style={{ color:"var(--muted-foreground)" }}>／ 期限 <span className="mono">{r.due}</span></span></Line>
          </div>
        </AfCard>
        <AfCard pad={0}>
          <div style={{ padding:"12px 14px", display:"flex", flexDirection:"column", gap:9 }}>
            <div style={{ fontSize:"var(--text-caption)", fontWeight:600, letterSpacing:"0.04em", color:"var(--muted-foreground)" }}>精算・採算</div>
            <Line label="精算方式"><b>{r.settleWay}</b></Line>
            <Line label="請求先">{r.payer}</Line>
            <Line label="金額"><span className="mono">総額 <b>{yen(r.billed)}</b>{r.cost>0 && <React.Fragment> ／原価 −{r.cost.toLocaleString()} ／粗利 <b style={{ color:"var(--success)" }}>{yen(profit)}</b></React.Fragment>}</span></Line>
            <div style={{ display:"flex", gap:6, flexWrap:"wrap", marginTop:2 }}>
              {["電話","メール"].map(a=>(
                <AfButton key={a} size="sm" onClick={()=>onContact&&onContact({
                  name:r.vendor, ch:a,
                  onSent:(label, body)=>{
                    // 進行詳細-10: 疑似送信にせず、案件の関係者ログへ記録する。
                    if (!r.caseId || !window.MStore || !r.vendor) return;
                    const when = ((d)=>(d.getMonth()+1)+"/"+d.getDate())(new Date());
                    window.MStore.updateCase(r.caseId, c => {
                      let party = (c.parties||[]).find(x => x && x.name === r.vendor);
                      if (!party) {
                        party = { role: r.kind==="ins" ? "保険会社" : "業者", name: r.vendor, wait: null, log: [] };
                        c.parties = [...(c.parties||[]), party];
                      }
                      party.log = [{ d: when, dir: "out", t: label + "：" + (body || "連絡") }, ...(party.log || [])];
                    });
                    onToast && onToast(r.vendor + " への記録を案件に残しました");
                  },
                })}>{a}</AfButton>
              ))}
              <AfButton size="sm" onClick={()=>onOpenCase&&onOpenCase(r)}>案件詳細で見る</AfButton>
            </div>
          </div>
        </AfCard>
      </div>

      <div style={{ fontSize:"var(--text-caption)", color:"var(--muted-foreground)", marginTop:12, lineHeight:1.7 }}>
        この画面は{K.label}を案件横断で並べて見るための<b>閲覧用</b>。工程の消込・金額の入力・帳票の発行は案件詳細の{K.label}パネルから行う。
      </div>
    </div>
  );
}

Object.assign(window, { TracksList, TrackDetail, TrRail, TR_KINDS, TR_STATE });
