/* =========================================================
   office-hours.jsx — shared timeline + ask composer + roster data
   ========================================================= */

/* office-day data: hours 6 AM → 8 PM (14 hr window) */
const DAY_START = 6;   // 6 AM
const DAY_END   = 20;  // 8 PM
const DAY_HOURS = DAY_END - DAY_START;
const NOW_HOUR  = 7 + 42/60; // 7:42 AM

/* daily routines per agent — what they do on the rhythm of the day */
const ROSTER = [
  {
    key:"EA", name:"Estimator Agent", title:"Estimator", tone:"green",
    blurb:"Reads drawings, runs takeoffs, prices line items from your rule book, drafts supplier RFQs.",
    routines:[
      "Daily 7 AM — drawing + takeoff sweep",
      "On new drawing — diff vs prior set and flag changes",
      "On supplier reply — fold quote into the worksheet",
    ],
    askable:["Re-cost a scope", "Draft a vendor RFQ", "Diff two drawing sets", "Find a unit price"],
    runs:[
      {h:5.5,  dur:0.0,  kind:"event",   label:"R4 received overnight"},
      {h:7.0,  dur:0.7,  kind:"routine", label:"7 AM drawing + takeoff sweep"},
      {h:7.7,  dur:0.0,  kind:"event",   label:"Takeoff worksheet prepared"},
      {h:14.0, dur:0.0,  kind:"future",  label:"Mid-day re-check"},
    ],
    lastDid:"Prepared Glenrose takeoff worksheet · 7:28 AM",
    nextOn:"On call — listening for supplier replies to fold in",
    reads:["Drive · drawings & specs","Gmail · supplier replies","Your rule book"],
    drafts:["Takeoff worksheet","Supplier RFQs","Open questions"],
    sends:["Gmail (after approval)"],
    never:"Send without approval · sign off on bids · change your rule book",
  },
  {
    key:"BA", name:"Bookkeeper Agent", title:"Bookkeeper", tone:"ink",
    blurb:"Captures bills, maps vendor + project + cost code, posts to QuickBooks after approval.",
    routines:[
      "Daily 6 AM — bill sweep from Gmail + Drive",
      "Daily 11 AM — mid-day check, vendor replies",
      "Daily 4 PM — end-of-day close, post approved",
    ],
    askable:["Look up a bill", "Re-map a vendor", "Find duplicates", "Show me unpaid"],
    runs:[
      {h:6.0,  dur:0.5,  kind:"routine", label:"6 AM bill sweep"},
      {h:6.5,  dur:0.2,  kind:"event",   label:"3 mapping qs raised"},
      {h:11.0, dur:0.4,  kind:"future",  label:"11 AM mid-day"},
      {h:16.0, dur:0.5,  kind:"future",  label:"4 PM close"},
    ],
    lastDid:"Found 10 bills · 6 ready for QuickBooks · 6:14 AM",
    nextOn:"Mid-day sweep at 11:00 AM",
    reads:["Gmail · bills label","Drive · /Bills inbox","QuickBooks vendors"],
    drafts:["Bills","Vendor mappings","Duplicate flags"],
    sends:["QuickBooks (after approval)"],
    never:"Payments · deletes · vendor banking changes",
  },
  {
    key:"FA", name:"Field Intake Agent", title:"Field Intake", tone:"amber",
    blurb:"Listens to WhatsApp from site, transcribes voice notes, classifies photos, drafts daily logs.",
    routines:[
      "Continuous — listening to site channels",
      "Daily 5 PM — compile each project's daily log",
      "On voice note — transcribe + classify within 2 min",
    ],
    askable:["Pull this week's photos", "Ask the super a question", "Find a delivery receipt", "Summarise site activity"],
    runs:[
      // continuous monitor
      {h:6.0,  dur:14.0, kind:"monitor", label:"Listening"},
      // events
      {h:6.8,  dur:0.0,  kind:"event",   label:"Voice note · Marco"},
      {h:7.5,  dur:0.0,  kind:"event",   label:"5 photos filed"},
      {h:17.0, dur:0.3,  kind:"future",  label:"5 PM log compile"},
    ],
    lastDid:"Drafted Glenrose daily log · 7:38 AM",
    nextOn:"Listening to Glenrose + Oakwood site channels",
    reads:["WhatsApp · site channels","SMS · field crew"],
    drafts:["Daily logs","RFI follow-ups","Hours discrepancies"],
    sends:["Drive (file photos)","Project Room (drafts)"],
    never:"Send to client · sign off hours",
  },
  {
    key:"FC", name:"File Clerk Agent", title:"File Clerk", tone:"navy",
    blurb:"Keeps Drive organised — files attachments to project folders, names by convention, deduplicates.",
    routines:[
      "Daily 6 AM — overnight tidy",
      "Daily 12 PM — mid-day pass",
      "Daily 6 PM — end-of-day pass",
      "On Drive upload — file within 1 minute",
    ],
    askable:["Find a file", "Restructure a folder", "Show recent uploads", "Rename a batch"],
    runs:[
      {h:5.8,  dur:0.4,  kind:"routine", label:"Overnight tidy"},
      {h:7.5,  dur:0.0,  kind:"event",   label:"R4 filed"},
      {h:12.0, dur:0.3,  kind:"future",  label:"Mid-day pass"},
      {h:18.0, dur:0.4,  kind:"future",  label:"EOD pass"},
    ],
    lastDid:"Filed Glenrose R4 + 38 reorgs in Oakwood · 7:32 AM",
    nextOn:"Mid-day folder pass at 12:00 PM",
    reads:["Drive · all project folders","Gmail attachments","WhatsApp media"],
    drafts:["Rename suggestions","Folder restructures"],
    sends:["Drive (move + rename)"],
    never:"Delete (Trash only, 30-day reversal) · rename client-final files",
  },
  {
    key:"SA", name:"Scheduling Agent", title:"Scheduler", tone:"green",
    blurb:"Maintains the project Gantt. Reads logs, vendor lead-times, weather to keep milestones honest.",
    routines:[
      "Daily 5:30 AM — refresh the day's plan + weather",
      "Daily 12 PM — reminder & lead-time check",
      "On milestone slip — alert and re-plan",
    ],
    askable:["Push a milestone", "Show critical path", "Find slack on Glenrose", "Draft a reminder"],
    runs:[
      {h:5.5,  dur:0.3,  kind:"routine", label:"Morning plan refresh"},
      {h:5.8,  dur:0.0,  kind:"event",   label:"3 reminders queued"},
      {h:12.0, dur:0.4,  kind:"future",  label:"Mid-day check"},
    ],
    lastDid:"Refreshed Glenrose Gantt · queued 3 reminders · 5:30 AM",
    nextOn:"Mid-day reminder & lead-time check at 12:00 PM",
    reads:["Daily logs","Vendor lead-time history","Weather forecast"],
    drafts:["Milestone updates","Reminders"],
    sends:["Project Gantt (after approval)"],
    never:"Send schedule to client · commit vendors to dates",
  },
  {
    key:"CU", name:"Client Update Agent", title:"Client Updates", tone:"navy",
    blurb:"Drafts weekly client updates, picks photos, summarises spending in plain language. Never sends without you.",
    routines:[
      "Thursdays 7 AM — draft each project's weekly update",
      "Daily — watch Client Room for incoming questions",
      "On approved update — send Thursday 8 AM",
    ],
    askable:["Draft an ad-hoc update", "Reply to a client question", "Show what's hidden from clients", "Pick 5 photos"],
    runs:[
      {h:6.2,  dur:0.4,  kind:"event",   label:"Weekly draft (Thu preview)"},
      {h:6.9,  dur:0.0,  kind:"event",   label:"Margaret reply drafted"},
      // mostly idle — monitoring
      {h:9.0,  dur:11.0, kind:"monitor", label:"Watching Client Room"},
    ],
    lastDid:"Drafted Glenrose weekly update + Margaret reply · 6:14 AM",
    nextOn:"Watching for client messages · weekly draft Thursday 7 AM",
    reads:["Project Room","Daily logs","Filed photos"],
    drafts:["Weekly updates","Photo selections","Budget paragraphs"],
    sends:["Client Room (after approval) · Thu 8 AM"],
    never:"Mention vendor disputes · quote firm dates beyond schedule",
  },
];

/* helper: convert hour-of-day to x% on the timeline */
const h2x = (h) => `${((h - DAY_START) / DAY_HOURS) * 100}%`;

/* The horizontal timeline strip used in two places:
   - on Office Today (compact, with everyone)
   - on Staff page (compact "hero")
*/
const OfficeHoursStrip = ({ height = 28, showLabels = true }) => {
  const ticks = [6,8,10,12,14,16,18,20];
  return (
    <div>
      {/* hour scale */}
      <div style={{
        display:"grid",
        gridTemplateColumns: "120px 1fr",
        gap: 14
      }}>
        <div/>
        <div style={{position:"relative", height:18}}>
          {ticks.map(h => (
            <div key={h} style={{
              position:"absolute", left: h2x(h), top:0,
              transform:"translateX(-50%)",
              fontFamily:"var(--f-mono)", fontSize:9.5, letterSpacing:"0.08em",
              color:"var(--ink-4)"
            }}>{h <= 12 ? h : h - 12}{h < 12 ? " AM" : h === 12 ? " PM" : " PM"}</div>
          ))}
        </div>
      </div>
      {/* rows */}
      <div style={{
        display:"grid",
        gridTemplateColumns: "120px 1fr",
        gap: 14,
        rowGap: 2,
        marginTop: 2,
        position:"relative"
      }}>
        {ROSTER.map(a => (
          <React.Fragment key={a.key}>
            {showLabels && (
              <div className="row" style={{gap:8, alignItems:"center", paddingRight:4}}>
                <span style={{
                  width:18, height:18, borderRadius:4,
                  background: a.tone === "green" ? "var(--green)" :
                              a.tone === "amber" ? "var(--amber)" :
                              a.tone === "navy"  ? "var(--navy)"  : "var(--ink)",
                  color:"var(--paper)",
                  display:"grid", placeItems:"center",
                  fontFamily:"var(--f-mono)", fontSize:8.5, fontWeight:600,
                  flex:"0 0 auto"
                }}>{a.key}</span>
                <span style={{fontSize:12, color:"var(--ink-2)", whiteSpace:"nowrap"}}>{a.title}</span>
              </div>
            )}
            {!showLabels && <div/>}
            <div style={{
              position:"relative",
              height,
              background: "var(--paper-2)",
              borderRadius: 4,
              border:"1px solid var(--line)"
            }}>
              {/* hour ticks faint */}
              {ticks.map(h => (
                <div key={h} style={{
                  position:"absolute", left:h2x(h), top:0, bottom:0, width:1,
                  background:"var(--line)"
                }}/>
              ))}
              {/* runs */}
              {a.runs.map((r,i) => {
                const left = h2x(r.h);
                const widthPct = r.dur > 0 ? `${(r.dur / DAY_HOURS) * 100}%` : null;
                if (r.kind === "monitor") {
                  return <div key={i} style={{
                    position:"absolute", left, width:widthPct, top: 6, bottom: 6,
                    background: a.tone === "green" ? "rgba(79,111,63,0.22)" :
                                a.tone === "amber" ? "rgba(180,122,31,0.22)" :
                                a.tone === "navy"  ? "rgba(44,74,107,0.22)"  : "rgba(27,31,42,0.18)",
                    borderRadius: 3,
                    border: "1px dashed",
                    borderColor: a.tone === "green" ? "rgba(79,111,63,0.5)" :
                                 a.tone === "amber" ? "rgba(180,122,31,0.5)" :
                                 a.tone === "navy"  ? "rgba(44,74,107,0.5)"  : "rgba(27,31,42,0.4)",
                  }}/>;
                }
                if (r.kind === "routine") {
                  return <div key={i} style={{
                    position:"absolute", left, width:widthPct, top: 4, bottom: 4,
                    background: a.tone === "green" ? "var(--green-2)" :
                                a.tone === "amber" ? "var(--amber-2)" :
                                a.tone === "navy"  ? "var(--navy)"     : "var(--ink)",
                    borderRadius: 3
                  }}/>;
                }
                if (r.kind === "future") {
                  return <div key={i} style={{
                    position:"absolute", left, width:widthPct || 4, top:4, bottom:4,
                    border: `1.5px dashed ${a.tone === "green" ? "var(--green-2)" :
                                            a.tone === "amber" ? "var(--amber-2)" :
                                            a.tone === "navy"  ? "var(--navy)" : "var(--ink-3)"}`,
                    background:"transparent",
                    borderRadius:3
                  }}/>;
                }
                // event = single dot
                return <div key={i} style={{
                  position:"absolute", left, top: "50%", marginTop:-3.5,
                  width:7, height:7, borderRadius:"50%",
                  background: a.tone === "green" ? "var(--green-2)" :
                              a.tone === "amber" ? "var(--amber-2)" :
                              a.tone === "navy"  ? "var(--navy)"     : "var(--ink)",
                  transform:"translateX(-50%)"
                }}/>;
              })}
            </div>
          </React.Fragment>
        ))}

        {/* current-time marker spanning all rows */}
        <div style={{
          position:"absolute",
          left: `calc(120px + 14px + ${h2x(NOW_HOUR)})`,
          top: 0, bottom: 0,
          width:1.5,
          background: "var(--rust)",
          pointerEvents:"none"
        }}>
          <span style={{
            position:"absolute", top:-15, left:-22, padding:"0 4px",
            fontFamily:"var(--f-mono)", fontSize:9.5,
            color:"var(--rust)", background:"var(--paper)",
            letterSpacing:"0.06em"
          }}>NOW</span>
        </div>
      </div>

      {/* legend */}
      <div className="row" style={{gap:18, marginTop:14, fontSize:11.5, color:"var(--ink-3)", flexWrap:"wrap"}}>
        <span className="row" style={{gap:6}}>
          <i style={{display:"inline-block", width:18, height:8, background:"var(--ink)", borderRadius:2}}/>
          <span>scheduled routine</span>
        </span>
        <span className="row" style={{gap:6}}>
          <i style={{display:"inline-block", width:8, height:8, background:"var(--ink)", borderRadius:"50%"}}/>
          <span>ad-hoc / event</span>
        </span>
        <span className="row" style={{gap:6}}>
          <i style={{display:"inline-block", width:18, height:8, background:"rgba(27,31,42,0.18)", border:"1px dashed var(--ink-3)", borderRadius:2}}/>
          <span>continuous monitor</span>
        </span>
        <span className="row" style={{gap:6}}>
          <i style={{display:"inline-block", width:18, height:8, border:"1.5px dashed var(--ink-3)", borderRadius:2}}/>
          <span>scheduled later today</span>
        </span>
      </div>
    </div>
  );
};

/* Single-agent mini timeline used inside each agent card */
const AgentDayMini = ({ agent }) => {
  const ticks = [6,9,12,15,18];
  return (
    <div>
      <div style={{position:"relative", height:14, marginBottom:2}}>
        {ticks.map(h => (
          <span key={h} style={{
            position:"absolute", left: h2x(h),
            transform:"translateX(-50%)",
            fontFamily:"var(--f-mono)", fontSize:9, color:"var(--ink-4)",
            letterSpacing:"0.04em"
          }}>{h <= 12 ? h : h - 12}{h < 12 ? "a" : "p"}</span>
        ))}
      </div>
      <div style={{position:"relative", height:24, background:"var(--paper-2)", border:"1px solid var(--line)", borderRadius:5}}>
        {ticks.map(h => (
          <div key={h} style={{position:"absolute", left:h2x(h), top:0, bottom:0, width:1, background:"var(--line)"}}/>
        ))}
        {agent.runs.map((r,i) => {
          const left = h2x(r.h);
          const widthPct = r.dur > 0 ? `${(r.dur / DAY_HOURS) * 100}%` : null;
          const accent = agent.tone === "green" ? "var(--green-2)" :
                         agent.tone === "amber" ? "var(--amber-2)" :
                         agent.tone === "navy"  ? "var(--navy)"     : "var(--ink)";
          if (r.kind === "monitor") {
            return <div key={i} style={{
              position:"absolute", left, width:widthPct, top:4, bottom:4,
              background:"transparent", border:"1px dashed", borderColor:accent, opacity:0.6, borderRadius:3
            }}/>;
          }
          if (r.kind === "routine") {
            return <div key={i} style={{
              position:"absolute", left, width:widthPct, top:3, bottom:3,
              background:accent, borderRadius:3
            }}/>;
          }
          if (r.kind === "future") {
            return <div key={i} style={{
              position:"absolute", left, width:widthPct || 4, top:3, bottom:3,
              border:`1.5px dashed ${accent}`, borderRadius:3, background:"transparent"
            }}/>;
          }
          return <div key={i} style={{
            position:"absolute", left, top:"50%", marginTop:-3,
            width:6, height:6, borderRadius:"50%", background:accent,
            transform:"translateX(-50%)"
          }}/>;
        })}
        {/* NOW */}
        <div style={{position:"absolute", left:h2x(NOW_HOUR), top:0, bottom:0, width:1.5, background:"var(--rust)"}}/>
      </div>
    </div>
  );
};

/* ---- Ask the Office composer (Aaron talking back to the office) ---- */
const AskTheOffice = () => {
  const suggestions = [
    "Ask Bookkeeper to find that Sherwin-Williams duplicate",
    "Have Field Agent pull Friday's stair photos",
    "Have Estimator re-cost roofing if Hartman doesn't reply by Tue",
    "Ask File Clerk to make a /Closeout folder for Glenrose",
  ];
  return (
    <div className="card" style={{padding:"18px 22px", display:"grid", gridTemplateColumns:"1fr auto", gap:18, alignItems:"center"}}>
      <div>
        <div className="screen-eyebrow">Ask the office</div>
        <div style={{
          marginTop:8,
          padding:"12px 14px",
          background:"var(--white)",
          border:"1px solid var(--line-2)",
          borderRadius:8,
          fontSize:14,
          color:"var(--ink-3)",
          fontStyle:"italic",
          textWrap:"pretty"
        }}>
          “Hey office — tell Bookkeeper to double-check the Madsen invoice against last month's…”
        </div>
        <div className="row" style={{gap:6, marginTop:10, flexWrap:"wrap"}}>
          {suggestions.map((s,i)=>(
            <span key={i} style={{
              padding:"4px 10px",
              fontSize:11.5,
              border:"1px solid var(--line)",
              borderRadius:999,
              background:"var(--paper-2)",
              color:"var(--ink-2)",
              whiteSpace:"nowrap"
            }}>{s}</span>
          ))}
        </div>
      </div>
      <div className="col" style={{gap:8, alignItems:"stretch", minWidth:160}}>
        <Btn variant="primary" icon="send">Send to office</Btn>
        <Btn variant="ghost" size="sm" icon="voice">Voice note</Btn>
      </div>
    </div>
  );
};

/* Per-agent ad-hoc Ask (used inside an agent card) */
const AskAgent = ({ agent }) => (
  <div>
    <div className="screen-eyebrow">Ask {agent.title}</div>
    <div style={{
      marginTop:6,
      padding:"10px 12px",
      background:"var(--white)",
      border:"1px solid var(--line-2)",
      borderRadius:7,
      fontSize:13,
      color:"var(--ink-3)",
      fontStyle:"italic"
    }}>
      “{agent.askable[0]}…”
    </div>
    <div className="row" style={{gap:6, marginTop:8, flexWrap:"wrap"}}>
      {agent.askable.slice(0, 4).map((s,i)=>(
        <span key={i} style={{
          padding:"3px 9px",
          fontSize:11,
          border:"1px solid var(--line)",
          borderRadius:999,
          background:"var(--paper)",
          color:"var(--ink-3)",
          whiteSpace:"nowrap"
        }}>{s}</span>
      ))}
    </div>
  </div>
);

window.ROSTER = ROSTER;
window.OfficeHoursStrip = OfficeHoursStrip;
window.AgentDayMini = AgentDayMini;
window.AskTheOffice = AskTheOffice;
window.AskAgent = AskAgent;
window.DAY_START = DAY_START;
window.DAY_END = DAY_END;
window.NOW_HOUR = NOW_HOUR;

/* =========================================================
   STORYLINE STRIP — the office movie playing across every screen
   Glenrose Custom Home, Tue 17 May
   ========================================================= */
const STORYLINE = [
  { k:"drawings",  label:"Drawings in",        state:"done",       sub:"Mon · BCA R4",      target:"mailroom" },
  { k:"takeoff",   label:"Takeoff worksheet",  state:"done",       sub:"today 7:28 AM",     target:"estimate" },
  { k:"quotes",    label:"Quote requests",     state:"now",        sub:"3 drafts \u2192 your approval", target:"quotes" },
  { k:"replies",   label:"Trade replies",      state:"incoming",   sub:"1 in, 2 expected",  target:"mailroom" },
  { k:"budget",    label:"Budget generated",   state:"draft",      sub:"$634,710 pre-quote",target:"project" },
  { k:"schedule",  label:"Schedule drafted",   state:"next",       sub:"next Mon",          target:"project" },
  { k:"ops",       label:"Ongoing ops",        state:"continuous", sub:"bills \u00b7 logs \u00b7 update", target:"receipts" },
];

const StorylineStrip = ({ current, onGo, replayActive, sceneIdx, totalScenes }) => {
  // In replay, the strip becomes a thin progress ribbon — show the current phase + the next phase, nothing more
  if (replayActive) {
    const progress = totalScenes ? Math.max(0, Math.min(1, (sceneIdx + 1) / totalScenes)) : 0;
    return (
      <div className="storyline storyline--thin">
        <span className="storyline-thin-eyebrow">Glenrose office day · replay</span>
        <div className="storyline-thin-bar">
          <div className="storyline-thin-fill" style={{width: `${progress * 100}%`}}/>
        </div>
        <span className="storyline-thin-counter">scene {sceneIdx + 1} / {totalScenes}</span>
      </div>
    );
  }
  return (
    <div className="storyline">
      <div className="storyline-head">
        <span className="screen-eyebrow">Job storyline</span>
        <span className="storyline-job">
          <span className="serif" style={{fontStyle:"italic", fontSize:15, color:"var(--paper)"}}>Glenrose Custom Home</span>
          <span className="muted-on-rail">{`Tuesday, 17 May · day 24 of 213`}</span>
        </span>
        <span className="storyline-meta">
          <span className="now-dot"/>
          <span>now: <b style={{color:"var(--paper)"}}>your turn on supplier quotes</b></span>
        </span>
      </div>
      <div className="storyline-track">
        {STORYLINE.map((s, i) => (
          <React.Fragment key={s.k}>
            <StorylineStep step={s} active={s.target === current} onGo={onGo} />
            {i < STORYLINE.length - 1 && <StorylineConnector from={s.state} to={STORYLINE[i+1].state} />}
          </React.Fragment>
        ))}
      </div>
    </div>
  );
};

const StorylineStep = ({ step, active, onGo }) => {
  const stateColor = {
    done:       "var(--green-2)",
    now:        "var(--amber-2)",
    incoming:   "var(--amber-2)",
    draft:      "var(--ink-on-rail-2)",
    next:       "var(--ink-on-rail-3)",
    continuous: "var(--ink-on-rail-2)",
  }[step.state];

  const renderMark = () => {
    if (step.state === "done") {
      return <Icon name="check" size={9} color="var(--ink)" />;
    }
    if (step.state === "now" || step.state === "incoming") {
      return <span className="now-pulse"/>;
    }
    return null;
  };

  return (
    <button
      type="button"
      className={"storyline-step state-" + step.state + (active ? " is-active" : "")}
      onClick={() => onGo(step.target)}
    >
      <span className="step-mark" style={{
        background: (step.state === "done" || step.state === "now" || step.state === "incoming") ? stateColor : "transparent",
        border: (step.state === "done" || step.state === "now" || step.state === "incoming") ? `1.5px solid ${stateColor}` : `1.5px ${step.state === "next" ? "solid" : "dashed"} ${stateColor}`,
        color: "var(--ink)"
      }}>{renderMark()}</span>
      <span className="step-body">
        <span className="step-label">{step.label}</span>
        <span className="step-sub">{step.sub}</span>
      </span>
    </button>
  );
};

const StorylineConnector = ({ from, to }) => (
  <span className={"storyline-conn from-" + from + " to-" + to}/>
);

window.StorylineStrip = StorylineStrip;
window.STORYLINE = STORYLINE;
