// ======== page-jsa.js ========
const JSA_HAZARDS = [
  "Electrocution/Shock","Hot Surfaces","Laceration","Chemicals (MSDS Review)","Fall from Heights",
  "Pinch Points","Amputation","Restricted Access/ Confined Space","Work Overhead","Flying Particles",
  "Hose Tangled","Poor Lighting","Lifting: Manual/Mechanical","Vehicle Traffic","Chemical Splash",
  "Heat Stress/Cold Temperatures","Rough/Sharp Material","Asphyxiation","Poor Work Position",
  "Compressed Air","Slippery/Uneven Surfaces","Welding Fume","Noise","Repetitive Motion",
  "Machinery Rotate/Moving","Welding Arc","Flammable Materials","Other"
];
const JSA_FIRE = ["Fire Blanket","Welding Screens","Flammables Removed","Suitable Fire Extinguishers","Trained Fire Watch Stationed","Cords/Leads/Hoses Elevated 7'","Permits Required","Work Permit","Hot Work","Line Break","Wind Speed 25 mph or Greater","Confined Space Entry","Other"];
const JSA_PPE = ["Hard Hat","Steel Toe Boots","Safety Glasses","Gloves","Fire Retardant Clothing","Face Shield","Monogoggles","Hearing Protection","Gloves for Specific Hazard","Rubber Gloves","Chemical Suits","Fall Protection Equipment","Respiratory Protection","Foot/Metatarsal Guards","Location of Safety Shower Known","Location of Eye Wash Known","Electrical Flash Gear","Jewelry Policy Being Followed","Rail Work: Derailer/Blue Flag","Barricades Needed"];
const JSA_ENERGY = ["Ground Fault Protection (GFCI)","Lock-Out/Tag-Out","Electrical Tool Cords Inspected","High Voltage Lines Identified","Hot Pipes Need Temp. Insulation","Has Crew Determined Wind Direction","Rail Work: Derailer/Blue Flag","Other"];
const JSA_PLATFORMS = ["Scaffold Needed/Inspected","JLG/Scissor Lift (Operator Certificate)","Ladders (Inspected & Secured)","Personnel Basket"];
const JSA_ABATEMENTS = ["Pre-Lift Rigging","Asbestos","Lead Paint","Demolition","Excavation","Other (List)","Caution (Yellow)","Danger (Red)","Hard Barricade","Flashing Lights"];
const JSA_TASK_TYPES = [
  "Equipment Set Up",
  "Pigging with H2O",
  "Pigging with HCL",
  "Pigging with Chemical",
  "Operating Lifting Equipment",
  "Loading / Unloading Trailers",
  "Manual Entry"
];

const JSA_PREWORK = [
  "Do you understand your permit, job task and safety requirements",
  "Have you, your supervisor, and the Client Representative confirmed the equipment and/or process has been properly blocked, tagged, locked, drained, decontaminated, and bleeders open and rodded",
  "Has the jobsite been walked with the client and our employees to understand the scope of work and potential safety hazards",
  "Has proper safety precautions been taken for others in the work area that may be affected by your work task (i.e., barricades, etc)",
  "Do you have all the proper information, tools, equipment, and materials to safely perform the task",
  "Is all the equipment in good order and properly tagged or color coded",
  "Are SDS sheets for material on the job site",
  "Have the safety hazards for your type of work been communicated to the client and our employees"
];
const JSA_POSTJOB = [
  "Do you or anyone in the work team know of or had any job related injuries or health concerns today",
  "Did you or any member in the work team witness a Near Miss or incident that could have caused an injury or health concern on this task",
  "Do you know of any Environmental Incident that occurred on this task",
  "Did your work group clean your work area at the end of the day and/or the completion of the task"
];

function CheckRow({label, checked, onChange}) {
  return (
    <div style={{display:"flex",alignItems:"center",gap:8,padding:"4px 0",borderBottom:"1px solid rgba(0,0,0,0.05)"}}>
      <div onClick={()=>onChange(!checked)} style={{width:22,height:22,borderRadius:4,border:`2px solid ${checked?"var(--accent)":"var(--border)"}`,background:checked?"var(--accent)":"transparent",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>
        {checked&&<span style={{color:"#000",fontSize:14,fontWeight:900}}>✓</span>}
      </div>
      <span style={{fontSize:12,color:"var(--text)",lineHeight:1.3}}>{label}</span>
    </div>
  );
}

function PreworkRow({question, value, onChange}) {
  return (
    <div style={{marginBottom:10,borderBottom:"1px solid rgba(0,0,0,0.05)",paddingBottom:10}}>
      <div style={{fontSize:12,color:"var(--text)",marginBottom:6,lineHeight:1.4}}>{question}</div>
      <div style={{display:"flex",gap:8}}>
        {["Yes","No","N/A"].map(opt=>(
          <button key={opt} onClick={()=>onChange(opt)} style={{padding:"6px 14px",borderRadius:8,border:`1px solid ${value===opt?"var(--accent)":"var(--border)"}`,background:value===opt?"rgba(255,165,0,0.15)":"transparent",color:value===opt?"var(--accent)":"var(--muted)",fontSize:12,fontWeight:700,cursor:"pointer",fontFamily:"var(--font)"}}>
            {opt}
          </button>
        ))}
      </div>
    </div>
  );
}

function SignatureCapture({name, onSign}) {
  const canvasRef = useRef(null);
  const [drawing, setDrawing] = useState(false);
  const [sigName, setSigName] = useState(name||"");
  const [signed, setSigned] = useState(false);

  const getPos = (e, canvas) => {
    const rect = canvas.getBoundingClientRect();
    const src = e.touches ? e.touches[0] : e;
    return { x: src.clientX - rect.left, y: src.clientY - rect.top };
  };

  const startDraw = (e) => {
    e.preventDefault();
    const canvas = canvasRef.current; if(!canvas) return;
    const ctx = canvas.getContext("2d");
    const pos = getPos(e, canvas);
    ctx.beginPath(); ctx.moveTo(pos.x, pos.y);
    setDrawing(true);
  };

  const draw = (e) => {
    e.preventDefault();
    if(!drawing) return;
    const canvas = canvasRef.current; if(!canvas) return;
    const ctx = canvas.getContext("2d");
    const pos = getPos(e, canvas);
    ctx.lineTo(pos.x, pos.y);
    ctx.strokeStyle = "#ffa500"; ctx.lineWidth = 2; ctx.lineCap = "round";
    ctx.stroke();
    setSigned(true);
  };

  const endDraw = () => setDrawing(false);

  const clear = () => {
    const canvas = canvasRef.current; if(!canvas) return;
    canvas.getContext("2d").clearRect(0,0,canvas.width,canvas.height);
    setSigned(false);
  };

  const submit = () => {
    if(!sigName.trim()) { alert("Please enter your name."); return; }
    if(!signed) { alert("Please sign before submitting."); return; }
    const canvas = canvasRef.current;
    const sig = canvas ? canvas.toDataURL() : null;
    onSign({ name: sigName, sig, time: Date.now() });
    setSigName(""); clear();
  };

  return (
    <div style={{background:"rgba(255,165,0,0.04)",borderRadius:10,padding:12,marginBottom:8,border:"1px solid rgba(255,165,0,0.15)"}}>
      <input value={sigName} onChange={e=>setSigName(e.target.value)} placeholder="Full Name" style={{...S.inp,marginBottom:8}} />
      <canvas ref={canvasRef} width={340} height={100} onMouseDown={startDraw} onMouseMove={draw} onMouseUp={endDraw} onTouchStart={startDraw} onTouchMove={draw} onTouchEnd={endDraw}
        style={{background:"rgba(0,0,0,0.3)",borderRadius:8,border:"1px solid var(--border)",width:"100%",height:100,touchAction:"none",cursor:"crosshair",display:"block"}} />
      <div style={{display:"flex",gap:8,marginTop:8}}>
        <button onClick={clear} style={{...S.bs,flex:0.5,padding:"8px",fontSize:12}}>Clear</button>
        <button onClick={submit} style={{...S.bp,flex:1,padding:"8px",fontSize:13}}>✓ Sign</button>
      </div>
    </div>
  );
}

function blankJSA(proj) {
  return {
    id: Date.now(),
    date: new Date().toLocaleDateString("en-US"),
    supervisor: "",
    client: proj.client||"",
    location: proj.location||"",
    taskActivity: "",
    evacuationRoutes: "",
    tasks: [],
    hazards: {},
    jobSteps: [{letter:"A", actions:""}],
    fire: {}, ppe: {}, energy: {}, platforms: {}, abatements: {},
    prework: {},
    taskStartTime: "",
    taskEndTime: "",
    postTask: {locksRemoved:false, injuriesReported:false, railCleared:false, areaClean:false},
    postJob: {},
    postJobExplanations: {},
    emergencyExt: "",
    fireExt: "",
    additionalComments: "",
    postJobOtherComments: "",
    crewSignIn: [],
    crewSignOut: [],
    completed: false
  };
}

function TasksSection({jsa, upd}) {
  const [showTaskMenu, setShowTaskMenu] = useState(false);
  const [pickingHazardsFor, setPickingHazardsFor] = useState(null); // task index

  const tasks = jsa.tasks || [];

  const addTask = (type) => {
    const newTask = {
      id: Date.now(),
      type,
      customLabel: "",
      hazards: [], // array of {name, mitigation}
    };
    upd("tasks", [...tasks, newTask]);
    setShowTaskMenu(false);
    setPickingHazardsFor(tasks.length); // open hazard picker for the new task
  };

  const removeTask = (idx) => {
    upd("tasks", tasks.filter((_,i)=>i!==idx));
    if(pickingHazardsFor===idx) setPickingHazardsFor(null);
  };

  const updateTask = (idx, changes) => {
    const updated = tasks.map((t,i)=>i===idx?{...t,...changes}:t);
    upd("tasks", updated);
  };

  const toggleHazard = (taskIdx, hazardName) => {
    const task = tasks[taskIdx];
    const exists = task.hazards.find(h=>h.name===hazardName);
    let newHazards;
    if(exists) {
      newHazards = task.hazards.filter(h=>h.name!==hazardName);
    } else {
      newHazards = [...task.hazards, {name:hazardName, mitigation:""}];
    }
    updateTask(taskIdx, {hazards: newHazards});
  };

  const updateMitigation = (taskIdx, hazardName, val) => {
    const task = tasks[taskIdx];
    const newHazards = task.hazards.map(h=>h.name===hazardName?{...h,mitigation:val}:h);
    updateTask(taskIdx, {hazards: newHazards});
  };

  return (
    <div style={S.card}>
      <div style={S.ct}>Tasks</div>

      {tasks.map((task, taskIdx)=>(
        <div key={task.id} style={{marginBottom:16,border:"1px solid rgba(255,165,0,0.2)",borderRadius:10,overflow:"hidden"}}>
          {/* Task header */}
          <div style={{background:"rgba(255,165,0,0.08)",padding:"10px 12px",display:"flex",alignItems:"center",justifyContent:"space-between"}}>
            <div style={{flex:1}}>
              <div style={{fontSize:12,fontWeight:800,color:"var(--accent)"}}>Task {taskIdx+1}: {task.type==="Manual Entry"?task.customLabel||"(enter task below)":task.type}</div>
              {task.type==="Manual Entry"&&(
                <input
                  value={task.customLabel||""}
                  onChange={e=>updateTask(taskIdx,{customLabel:e.target.value})}
                  placeholder="Describe task..."
                  style={{...S.inp,marginTop:6,fontSize:12}}
                />
              )}
            </div>
            <button onClick={()=>removeTask(taskIdx)} style={{background:"none",border:"none",color:"#ff4444",fontSize:16,cursor:"pointer",padding:"4px 8px",flexShrink:0}}>✕</button>
          </div>

          {/* Hazard picker toggle */}
          <div style={{padding:"8px 12px",borderBottom:"1px solid rgba(0,0,0,0.06)"}}>
            <button
              onClick={()=>setPickingHazardsFor(pickingHazardsFor===taskIdx?null:taskIdx)}
              style={{...S.ba,fontSize:11,padding:"6px 12px",width:"auto"}}
            >
              {pickingHazardsFor===taskIdx?"▲ Close Hazard List":"+ Add Hazards"}
            </button>
            {task.hazards.length>0&&<span style={{fontSize:10,color:"var(--muted)",marginLeft:10}}>{task.hazards.length} hazard{task.hazards.length!==1?"s":""} selected</span>}
          </div>

          {/* Hazard picker */}
          {pickingHazardsFor===taskIdx&&(
            <div style={{padding:"8px 12px",background:"rgba(0,0,0,0.08)",borderBottom:"1px solid rgba(0,0,0,0.06)"}}>
              <div style={{fontSize:10,color:"var(--muted)",marginBottom:6}}>Select all hazards that apply to this task:</div>
              <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:2}}>
                {JSA_HAZARDS.map(h=>{
                  const sel = task.hazards.find(x=>x.name===h);
                  return (
                    <div key={h} onClick={()=>toggleHazard(taskIdx,h)} style={{display:"flex",alignItems:"center",gap:6,padding:"5px 4px",cursor:"pointer",borderRadius:6,background:sel?"rgba(255,165,0,0.1)":"transparent"}}>
                      <div style={{width:16,height:16,borderRadius:3,border:`1px solid ${sel?"var(--accent)":"var(--border)"}`,background:sel?"var(--accent)":"transparent",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>
                        {sel&&<span style={{fontSize:9,fontWeight:900,color:"#000"}}>✓</span>}
                      </div>
                      <span style={{fontSize:10,color:sel?"var(--text)":"var(--muted)",lineHeight:1.2}}>{h}</span>
                    </div>
                  );
                })}
              </div>
            </div>
          )}

          {/* Hazards with mitigation fields */}
          {task.hazards.length>0&&(
            <div style={{padding:"8px 12px"}}>
              <div style={{fontSize:10,color:"var(--muted)",marginBottom:6,fontWeight:700}}>Hazards & Mitigations:</div>
              {task.hazards.map((h,hi)=>(
                <div key={h.name} style={{marginBottom:10,paddingBottom:10,borderBottom:hi<task.hazards.length-1?"1px solid rgba(0,0,0,0.06)":"none"}}>
                  <div style={{display:"flex",alignItems:"center",gap:6,marginBottom:5}}>
                    <div style={{width:20,height:20,borderRadius:4,background:"var(--accent)",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>
                      <span style={{fontSize:9,fontWeight:900,color:"#000"}}>{String.fromCharCode(65+hi)}</span>
                    </div>
                    <span style={{fontSize:12,fontWeight:700,color:"var(--text)"}}>{h.name}</span>
                  </div>
                  <textarea
                    rows={2}
                    value={h.mitigation||""}
                    onChange={e=>updateMitigation(taskIdx,h.name,e.target.value)}
                    placeholder="Describe mitigation for this hazard..."
                    style={{...S.inp,fontSize:12,resize:"vertical",minHeight:48}}
                  />
                </div>
              ))}
            </div>
          )}
        </div>
      ))}

      {/* Add Task button + dropdown */}
      <div style={{position:"relative"}}>
        <button onClick={()=>setShowTaskMenu(v=>!v)} style={{...S.bp,fontSize:13,padding:"12px 16px"}}>
          + Add Task
        </button>
        {showTaskMenu&&(
          <div style={{position:"absolute",top:"100%",left:0,right:0,background:"var(--card)",border:"1px solid var(--border)",borderRadius:10,zIndex:100,marginTop:4,overflow:"hidden",boxShadow:"0 8px 24px rgba(0,0,0,0.5)"}}>
            {JSA_TASK_TYPES.map(type=>(
              <div
                key={type}
                onClick={()=>addTask(type)}
                style={{padding:"12px 16px",fontSize:13,color:"var(--text)",cursor:"pointer",borderBottom:"1px solid rgba(0,0,0,0.06)"}}
                onMouseEnter={e=>e.currentTarget.style.background="rgba(255,165,0,0.08)"}
                onMouseLeave={e=>e.currentTarget.style.background="transparent"}
              >
                {type}
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

function JSAForm({jsa, onUpdate, proj}) {
  const [addingSigIn, setAddingSigIn] = useState(false);
  const [addingSigOut, setAddingSigOut] = useState(false);

  const upd = (field, val) => onUpdate({...jsa, [field]:val});
  const updNested = (field, key, val) => onUpdate({...jsa, [field]:{...jsa[field],[key]:val}});

  const signCrewOut = () => {
    // Sign out all crew members who signed in but haven't signed out
    const signedInNames = (jsa.crewSignIn||[]).map(s=>s.name);
    const signedOutNames = new Set((jsa.crewSignOut||[]).map(s=>s.name));
    const toSignOut = signedInNames.filter(n=>!signedOutNames.has(n));
    if(toSignOut.length===0){alert("All crew members are already signed out.");return;}
    const newSignOuts = toSignOut.map(name=>({name, sig:null, time:Date.now(), auto:true}));
    upd("crewSignOut",[...(jsa.crewSignOut||[]),...newSignOuts]);
  };

  return (
    <div style={{paddingBottom:20}}>
      <div style={{...S.card,background:"linear-gradient(135deg,rgba(180,60,0,0.12),rgba(255,165,0,0.06))"}}>
        <div style={{fontSize:13,fontWeight:900,color:"var(--accent)",textAlign:"center",marginBottom:2}}>Job Safety Analysis (JSA) & Daily ToolBox Talk</div>
        <div style={{fontSize:9,color:"var(--muted)",textAlign:"center",marginBottom:12}}>Internal Pipeline Services · IPS-JSA</div>
        <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:10}}>
          <Inp label="Supervisor (Print Name)" value={jsa.supervisor} onChange={v=>upd("supervisor",v)} />
          <Inp label="Client" value={jsa.client} onChange={v=>upd("client",v)} />
          <Inp label="Date" value={jsa.date} onChange={v=>upd("date",v)} />
          <Inp label="Location of Work" value={jsa.location} onChange={v=>upd("location",v)} />
        </div>
        <Inp label="Evacuation Routes and Assembly Areas" value={jsa.evacuationRoutes} onChange={v=>upd("evacuationRoutes",v)} style={{marginTop:10}} />
      </div>

      <TasksSection jsa={jsa} upd={upd} />

      <div style={S.card}>
        <div style={S.ct}>Safety Checklist</div>
        <div style={{fontSize:11,fontWeight:700,color:"var(--accent)",marginBottom:6}}>Fire Protection Precautions</div>
        {JSA_FIRE.map(item=><CheckRow key={item} label={item} checked={!!jsa.fire?.[item]} onChange={v=>updNested("fire",item,v)} />)}
        <div style={{fontSize:11,fontWeight:700,color:"var(--accent)",marginTop:14,marginBottom:6}}>PPE Needed</div>
        {JSA_PPE.map(item=><CheckRow key={item} label={item} checked={!!jsa.ppe?.[item]} onChange={v=>updNested("ppe",item,v)} />)}
        <div style={{fontSize:11,fontWeight:700,color:"var(--accent)",marginTop:14,marginBottom:6}}>Energized Equipment Secured</div>
        {JSA_ENERGY.map(item=><CheckRow key={item} label={item} checked={!!jsa.energy?.[item]} onChange={v=>updNested("energy",item,v)} />)}
        <div style={{fontSize:11,fontWeight:700,color:"var(--accent)",marginTop:14,marginBottom:6}}>Work Platforms for Task</div>
        {JSA_PLATFORMS.map(item=><CheckRow key={item} label={item} checked={!!jsa.platforms?.[item]} onChange={v=>updNested("platforms",item,v)} />)}
        <div style={{fontSize:11,fontWeight:700,color:"var(--accent)",marginTop:14,marginBottom:6}}>Abatements Necessary</div>
        {JSA_ABATEMENTS.map(item=><CheckRow key={item} label={item} checked={!!jsa.abatements?.[item]} onChange={v=>updNested("abatements",item,v)} />)}
      </div>

      <div style={S.card}>
        <div style={S.ct}>Pre-Work Job Safety Review</div>
        {JSA_PREWORK.map((q,i)=><PreworkRow key={i} question={q} value={jsa.prework?.[i]} onChange={v=>updNested("prework",i,v)} />)}
        <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:10,marginTop:10}}>
          <Inp label="In Event of Emergency, Call Ext:" value={jsa.emergencyExt} onChange={v=>upd("emergencyExt",v)} />
          <Inp label="Fires Reported by Dialing Ext:" value={jsa.fireExt} onChange={v=>upd("fireExt",v)} />
        </div>
        <div style={{marginTop:10}}>
          <label style={S.lb}>Additional Comments and/or Instructions</label>
          <textarea rows={3} value={jsa.additionalComments} onChange={e=>upd("additionalComments",e.target.value)} style={{...S.inp,resize:"vertical"}} />
        </div>
      </div>

      {/* Crew Sign-In */}
      <div style={S.card}>
        <div style={S.ct}>Crew Sign-In Before Task</div>
        <div style={{fontSize:11,color:"var(--muted)",marginBottom:8,fontStyle:"italic"}}>I understand the safety precautions and have the training to perform this task.</div>
        <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:8,marginBottom:8}}>
          <Inp label="Task Start Time" value={jsa.taskStartTime} onChange={v=>upd("taskStartTime",v)} />
        </div>
        {(jsa.crewSignIn||[]).map((sig,i)=>(
          <div key={i} style={{display:"flex",alignItems:"center",gap:8,padding:"6px 10px",background:"rgba(0,230,118,0.06)",borderRadius:8,marginBottom:6,border:"1px solid rgba(0,230,118,0.15)"}}>
            <span style={{fontSize:13,fontWeight:700,color:"var(--text)",flex:1}}>{sig.name}</span>
            {sig.sig&&<img src={sig.sig} alt="sig" style={{height:30,filter:"brightness(1.5)"}} />}
            <input
              type="time"
              value={sig.time ? new Date(sig.time).toLocaleTimeString("en-US",{hour12:false,hour:"2-digit",minute:"2-digit"}) : ""}
              onChange={e=>{
                const [h,m]=e.target.value.split(":").map(Number);
                const d=sig.time?new Date(sig.time):new Date();
                d.setHours(h,m,0,0);
                const updated=(jsa.crewSignIn||[]).map((s,j)=>j===i?{...s,time:d.getTime()}:s);
                upd("crewSignIn",updated);
              }}
              style={{fontSize:11,padding:"2px 4px",borderRadius:4,border:"1px solid rgba(0,230,118,0.3)",background:"rgba(0,0,0,0.2)",color:"var(--text)",width:80}}
            />
            <button onClick={()=>upd("crewSignIn",(jsa.crewSignIn||[]).filter((_,j)=>j!==i))} style={{background:"none",border:"none",color:"#ff4444",cursor:"pointer",fontSize:14}}>✕</button>
          </div>
        ))}
        {!addingSigIn
          ? <button onClick={()=>setAddingSigIn(true)} style={{...S.ba,fontSize:13}}>+ Add Signature</button>
          : <><SignatureCapture onSign={sig=>{upd("crewSignIn",[...(jsa.crewSignIn||[]),sig]);setAddingSigIn(false)}} />
              <button onClick={()=>setAddingSigIn(false)} style={{...S.bs,marginTop:6,fontSize:12,padding:"8px"}}>Cancel</button></>
        }
      </div>

      {/* Crew Sign-Out */}
      <div style={S.card}>
        <div style={S.ct}>Crew Sign-Out After Task</div>
        <div style={{fontSize:11,color:"var(--muted)",marginBottom:8,fontStyle:"italic"}}>I have worked safely today and have not been injured.</div>
        <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:8,marginBottom:8}}>
          <Inp label="Task End Time" value={jsa.taskEndTime} onChange={v=>upd("taskEndTime",v)} />
        </div>
        {(jsa.crewSignOut||[]).map((sig,i)=>(
          <div key={i} style={{display:"flex",alignItems:"center",gap:8,padding:"6px 10px",background:"rgba(255,165,0,0.06)",borderRadius:8,marginBottom:6,border:"1px solid rgba(255,165,0,0.15)"}}>
            <span style={{fontSize:13,fontWeight:700,color:"var(--text)",flex:1}}>{sig.name}</span>
            {sig.sig&&!sig.auto&&<img src={sig.sig} alt="sig" style={{height:30,filter:"brightness(1.5)"}} />}
            {sig.auto&&<span style={{fontSize:10,color:"var(--accent)",fontWeight:700}}>AUTO</span>}
            <input
              type="time"
              value={sig.time ? new Date(sig.time).toLocaleTimeString("en-US",{hour12:false,hour:"2-digit",minute:"2-digit"}) : ""}
              onChange={e=>{
                const [h,m]=e.target.value.split(":").map(Number);
                const d=sig.time?new Date(sig.time):new Date();
                d.setHours(h,m,0,0);
                const updated=(jsa.crewSignOut||[]).map((s,j)=>j===i?{...s,time:d.getTime()}:s);
                upd("crewSignOut",updated);
              }}
              style={{fontSize:11,padding:"2px 4px",borderRadius:4,border:"1px solid rgba(255,165,0,0.3)",background:"rgba(0,0,0,0.2)",color:"var(--text)",width:80}}
            />
            <button onClick={()=>upd("crewSignOut",(jsa.crewSignOut||[]).filter((_,j)=>j!==i))} style={{background:"none",border:"none",color:"#ff4444",cursor:"pointer",fontSize:14}}>✕</button>
          </div>
        ))}
        {/* Sign Crew Out button */}
        {(jsa.crewSignIn||[]).length > 0 && (
          <button onClick={signCrewOut} style={{...S.ba,fontSize:13,marginBottom:8,width:"100%",padding:"12px 16px",background:"rgba(0,230,118,0.1)",color:"#00e676",border:"1px solid rgba(0,230,118,0.25)"}}>
            ✓ Sign Crew Out (All)
          </button>
        )}
        {!addingSigOut
          ? <button onClick={()=>setAddingSigOut(true)} style={{...S.ba,fontSize:13}}>+ Individual Signature</button>
          : <><SignatureCapture onSign={sig=>{upd("crewSignOut",[...(jsa.crewSignOut||[]),sig]);setAddingSigOut(false)}} />
              <button onClick={()=>setAddingSigOut(false)} style={{...S.bs,marginTop:6,fontSize:12,padding:"8px"}}>Cancel</button></>
        }
      </div>

    </div>
  );
}

function JSAPage({jsas, setJSAs, proj, NavBar}) {
  const [view, setView] = useState("list");
  const [selId, setSelId] = useState(null);
  const todayStr = new Date().toLocaleDateString("en-US");

  const selJSA = jsas.find(j=>j.id===selId);

  const addJSA = () => {
    const j = blankJSA(proj);
    setJSAs(prev=>[...prev,j]);
    setSelId(j.id); setView("form");
  };

  // "Same as Last" — prefills from the most recently saved JSA (any date)
  const sameAsLast = () => {
    const sorted = [...jsas].sort((a,b)=>new Date(b.date)-new Date(a.date));
    const last = sorted[0];
    if(!last){alert("No previous JSA found.");return;}
    const j = {...last, id:Date.now(), date:todayStr, crewSignIn:[], crewSignOut:[], taskStartTime:"", taskEndTime:"", completed:false};
    setJSAs(prev=>[...prev,j]);
    setSelId(j.id); setView("form");
  };

  const duplicateJSA = (source) => {
    const j = {...source, id:Date.now(), date:todayStr, crewSignIn:[], crewSignOut:[], taskStartTime:"", taskEndTime:"", completed:false};
    setJSAs(prev=>[...prev,j]);
    setSelId(j.id); setView("form");
  };

  const updateJSA = (updated) => {
    setJSAs(prev=>prev.map(j=>j.id===updated.id?updated:j));
  };

  const deleteJSA = (id) => {
    if(confirm("Delete this JSA?")) setJSAs(prev=>prev.filter(j=>j.id!==id));
  };

  if(view==="form"&&selJSA) {
    return (
      <div style={{padding:"12px 16px",maxWidth:500,margin:"0 auto",paddingBottom:80}}>
        <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12}}>
          <button onClick={()=>setView("list")} style={{...S.bs,padding:"8px 14px",fontSize:12,width:"auto"}}>← JSAs</button>
          <div style={{fontSize:13,fontWeight:800,color:"var(--accent)"}}>JSA — {selJSA.date}</div>
          <div style={{display:"flex",gap:6}}>
            <button onClick={()=>ReportGen.emailJSA(proj, selJSA)} style={{...S.ba,padding:"8px 14px",fontSize:12,width:"auto"}}>✉️</button>
            <button onClick={()=>{updateJSA({...selJSA,completed:true});setView("list")}} style={{...S.bp,padding:"8px 14px",fontSize:12,width:"auto"}}>✓ Done</button>
          </div>
        </div>
        <JSAForm jsa={selJSA} onUpdate={updateJSA} proj={proj} />
      </div>
    );
  }

  const byDate = {};
  jsas.forEach(j=>{if(!byDate[j.date])byDate[j.date]=[];byDate[j.date].push(j)});
  const dates = Object.keys(byDate).sort((a,b)=>new Date(b)-new Date(a));

  return (
    <div style={{padding:"12px 16px",maxWidth:CONTAINER_MAX,margin:"0 auto",paddingBottom:80}}>
      <div style={{fontSize:16,fontWeight:900,fontFamily:"var(--display)",textAlign:"center",marginBottom:16}}>JSA</div>
      <div style={{display:"flex",gap:8,marginBottom:16}}>
        <button onClick={addJSA} style={{...S.bp,flex:1,padding:"14px 12px",fontSize:14}}>+ New JSA</button>
        <button onClick={sameAsLast} style={{...S.ba,flex:1,padding:"14px 12px",fontSize:13}}>↻ Same as Last</button>
      </div>
      {jsas.length===0&&<div style={{textAlign:"center",padding:32,color:"var(--dim)"}}>No JSAs yet</div>}
      {dates.map(d=>(
        <div key={d} style={{marginBottom:16}}>
          <div style={{fontSize:11,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",marginBottom:6}}>{d}{d===todayStr?" (Today)":""}</div>
          {byDate[d].map(j=>(
            <div key={j.id} style={{...S.card,marginBottom:8}}>
              <div style={{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:8}} onClick={()=>{setSelId(j.id);setView("form")}}>
                <div style={{flex:1,cursor:"pointer"}}>
                  <div style={{fontWeight:800,fontSize:13,color:"var(--accent)"}}>{j.tasks&&j.tasks.length>0?j.tasks.map(t=>t.type==="Manual Entry"?t.customLabel||"Manual Entry":t.type).join(", "):"(No tasks set)"}</div>
                  <div style={{fontSize:11,color:"var(--muted)",marginTop:2}}>{j.supervisor||"No supervisor"} · {j.crewSignIn?.length||0} signed in · {j.crewSignOut?.length||0} signed out</div>
                </div>
                {j.completed&&<span style={{fontSize:10,color:"#00e676",fontWeight:700,marginLeft:8}}>✓ Done</span>}
              </div>
              <div style={{display:"flex",gap:6}}>
                <button onClick={()=>{setSelId(j.id);setView("form")}} style={{...S.ba,flex:1,padding:"8px 10px",fontSize:12}}>Open</button>
                <button onClick={()=>ReportGen.emailJSA(proj,j)} style={{...S.bs,width:"auto",padding:"8px 12px",fontSize:12}}>✉️</button>
                <button onClick={()=>duplicateJSA(j)} style={{...S.bs,width:"auto",padding:"8px 12px",fontSize:12}}>⎘ Dup</button>
                <button onClick={e=>{e.stopPropagation();deleteJSA(j.id)}} style={{background:"none",border:"none",color:"#ff4444",cursor:"pointer",fontSize:16,padding:"4px 8px"}}>✕</button>
              </div>
            </div>
          ))}
        </div>
      ))}
    </div>
  );
}

// ======== CHECKLIST PAGE ========
const DEFAULT_CHECKLIST = [
  {
    id: "s1", title: "Project List Notes", collapsed: false,
    items: [
      {id:"i1a",text:"Traps / Spools",checked:false,notes:""},
      {id:"i1b",text:"Gate Valves",checked:false,notes:""},
      {id:"i1c",text:"Bolts",checked:false,notes:""},
      {id:"i1d",text:"Gaskets",checked:false,notes:""},
      {id:"i1e",text:"O-rings",checked:false,notes:""},
      {id:"i1f",text:"Fabrication",checked:false,notes:""},
      {id:"i1g",text:"Pig stopper / ramp / rails",checked:false,notes:""},
      {id:"i1h",text:"Hoses",checked:false,notes:""},
      {id:"i1i",text:"Valve Setups / Fittings (CLEANING)",checked:false,notes:""},
      {id:"i1j",text:"Manifold on ground",checked:false,notes:""},
      {id:"i1k",text:"1.5\" solvent removal hoses and guns",checked:false,notes:""},
      {id:"i1l",text:"Pig puller and trap cleaner",checked:false,notes:""},
      {id:"i1m",text:"Berms - All Tanks and Ground covering",checked:false,notes:""},
      {id:"i1n",text:"Gauge setups",checked:false,notes:""},
      {id:"i1o",text:"Diaphragm Pump and hoses",checked:false,notes:""},
      {id:"i1p",text:"Teflon Tape / Dope Stuart",checked:false,notes:""},
      {id:"i1q",text:"Hand tools",checked:false,notes:""},
      {id:"i1r",text:"Impact and Gate Valve Drill",checked:false,notes:""},
      {id:"i1s",text:"Hose whips",checked:false,notes:""},
      {id:"i1t",text:"Basin for Door (CLEANING)",checked:false,notes:""},
      {id:"i1u",text:"Pig Drains Uline",checked:false,notes:""},
      {id:"i1v",text:"Shovel",checked:false,notes:""},
      {id:"i1w",text:"Tripod",checked:false,notes:""},
      {id:"i1x",text:"Socket for Drums / Trap Door / Trap Bolts",checked:false,notes:""},
      {id:"i1y",text:"Rod / Grabber for Gate Valve (Long)",checked:false,notes:""},
      {id:"i1z",text:"5 / 2 / small Gallon buckets Uline",checked:false,notes:""},
      {id:"i1aa",text:"Rags Uline",checked:false,notes:""},
      {id:"i1ab",text:"Empty Drums Uline",checked:false,notes:""},
      {id:"i1ac",text:"Plastic Wrap Uline",checked:false,notes:""},
      {id:"i1ad",text:"Visqueen",checked:false,notes:""},
      {id:"i1ae",text:"Ratchet Straps and Rope Amazon",checked:false,notes:""},
      {id:"i1af",text:"Drum Liners / Trash Bags",checked:false,notes:""},
      {id:"i1ag",text:"Duck Tape / Electric tape Uline",checked:false,notes:""},
      {id:"i1ah",text:"WD-40",checked:false,notes:""},
      {id:"i1ai",text:"Black / Red Spray Paint",checked:false,notes:""},
      {id:"i1aj",text:"Radios",checked:false,notes:""},
      {id:"i1ak",text:"Fire Extinguisher",checked:false,notes:""},
      {id:"i1al",text:"First Aid Kit",checked:false,notes:""},
      {id:"i1am",text:"Job box power source",checked:false,notes:""},
      {id:"i1an",text:"Extension cords",checked:false,notes:""},
      {id:"i1ao",text:"Gate Valve Step",checked:false,notes:""},
      {id:"i1ap",text:"Canopy",checked:false,notes:""},
      {id:"i1aq",text:"Trap Support (Cribbing)",checked:false,notes:""},
      {id:"i1ar",text:"Spill Kit",checked:false,notes:""},
      {id:"i1as",text:"Crescent Wrenches (valve handles)",checked:false,notes:""},
      {id:"i1at",text:"Lights",checked:false,notes:""},
      {id:"i1au",text:"Grounding Equipment",checked:false,notes:""},
      {id:"i1av",text:"Ladder",checked:false,notes:""},
      {id:"i1aw",text:"Cheater Bar",checked:false,notes:""},
      {id:"i1ax",text:"Antifoam - Confirm With Sky",checked:false,notes:""},
      {id:"i1ay",text:'1" Poly Pump & 2" Poly Pump',checked:false,notes:""},
      {id:"i1az",text:"Lifting straps and shackles Uline",checked:false,notes:""},
      {id:"i1ba",text:"Bathrooms",checked:false,notes:""},
      {id:"i1bb",text:"Drinking Water",checked:false,notes:""},
    ]
  },
  {
    id: "s2", title: "Coating", collapsed: false,
    items: [
      {id:"i2a",text:"Coating",checked:false,notes:""},
      {id:"i2b",text:"Grease",checked:false,notes:""},
      {id:"i2c",text:"Pallet Jack Scale (Charged)",checked:false,notes:""},
      {id:"i2d",text:"Pipeline Insulation",checked:false,notes:""},
      {id:"i2e",text:"Basins for Door (COATING)",checked:false,notes:""},
      {id:"i2f",text:"Coating Vent Tanks",checked:false,notes:""},
      {id:"i2g",text:"Totes for Paint",checked:false,notes:""},
      {id:"i2h",text:"Paint removal defuser",checked:false,notes:""},
      {id:"i2i",text:"Valve Setups / Fittings (COATING)",checked:false,notes:""},
      {id:"i2j",text:"Pig cleaner (motor / hoses / fittings)",checked:false,notes:""},
    ]
  },
  {
    id: "s3", title: "Testing Equipment", collapsed: false,
    items: [
      {id:"i3a",text:"Quantab (30-600 PPM)",checked:false,notes:""},
      {id:"i3b",text:"pH Strip",checked:false,notes:""},
      {id:"i3c",text:"Mill Gauge",checked:false,notes:""},
      {id:"i3d",text:"Dewpoint meter",checked:false,notes:""},
      {id:"i3e",text:"Camphor Cubes",checked:false,notes:""},
      {id:"i3f",text:"Centrifuge",checked:false,notes:""},
      {id:"i3g",text:"Centrifuge Tubes 15 mL",checked:false,notes:""},
      {id:"i3h",text:"Scale",checked:false,notes:""},
      {id:"i3i",text:"Sample Bottles",checked:false,notes:""},
      {id:"i3j",text:"Temp. Gun",checked:false,notes:""},
      {id:"i3k",text:"Phenolphthalein",checked:false,notes:""},
      {id:"i3l",text:".25N or .29N NaOH",checked:false,notes:""},
      {id:"i3m",text:"1 mL and 3 mL syringe or pipette",checked:false,notes:""},
      {id:"i3n",text:"200 mL beaker",checked:false,notes:""},
      {id:"i3o",text:"Hydrocarbon indicator strips",checked:false,notes:""},
    ]
  },
  {
    id: "s4", title: "PPE", collapsed: false,
    items: [
      {id:"i4a",text:"Leather Gloves Amazon",checked:false,notes:""},
      {id:"i4b",text:"Rubber Gloves / Test Gloves",checked:false,notes:""},
      {id:"i4c",text:"Acid Suits",checked:false,notes:""},
      {id:"i4d",text:"Paint Suits",checked:false,notes:""},
      {id:"i4e",text:"Hearing Protection",checked:false,notes:""},
      {id:"i4f",text:"Respirators and Replacement Cartridges",checked:false,notes:""},
      {id:"i4g",text:"Goggles",checked:false,notes:""},
      {id:"i4h",text:"Glasses Amazon",checked:false,notes:""},
      {id:"i4i",text:"Face shields",checked:false,notes:""},
      {id:"i4j",text:"Rubber Boots",checked:false,notes:""},
      {id:"i4k",text:"Emergency Shower",checked:false,notes:""},
      {id:"i4l",text:"Eye Wash",checked:false,notes:""},
      {id:"i4m",text:"Crew Fit Tested",checked:false,notes:""},
    ]
  },
  {
    id: "s5", title: "Printed Forms", collapsed: false,
    items: [
      {id:"i5a",text:"JHAs",checked:false,notes:""},
      {id:"i5b",text:"SDS's",checked:false,notes:""},
      {id:"i5c",text:"Run Sheets",checked:false,notes:""},
      {id:"i5d",text:"Coating Inspection Forms",checked:false,notes:""},
      {id:"i5e",text:"Empty File Folders",checked:false,notes:""},
      {id:"i5f",text:"Coating Logs",checked:false,notes:""},
      {id:"i5g",text:"Truck and Tank Logs",checked:false,notes:""},
      {id:"i5h",text:"Temperature Logs",checked:false,notes:""},
      {id:"i5i",text:"Laminator",checked:false,notes:""},
      {id:"i5j",text:"Printer & Paper",checked:false,notes:""},
    ]
  },
  {
    id: "s6", title: "Disposal", collapsed: false,
    items: [
      {id:"i6a",text:"Client Environmental Contact",checked:false,notes:""},
      {id:"i6b",text:"Confirm Legal Generator",checked:false,notes:""},
      {id:"i6c",text:"Apply for Episodic / One-time shipment #'s",checked:false,notes:""},
      {id:"i6d",text:"Receive One-Time Shipment #'s",checked:false,notes:""},
      {id:"i6e",text:"Submit Profiles for waste streams",checked:false,notes:""},
      {id:"i6f",text:"HAZ Boxes",checked:false,notes:""},
    ]
  },
  {
    id: "s7", title: "Office / Admin", collapsed: false,
    items: [
      {id:"i7a",text:"Purchase Order",checked:false,notes:""},
      {id:"i7b",text:"First Invoice",checked:false,notes:""},
      {id:"i7c",text:"Insurance Requirements",checked:false,notes:""},
      {id:"i7d",text:"Job Walk",checked:false,notes:""},
      {id:"i7e",text:"Scheduled",checked:false,notes:""},
      {id:"i7f",text:"Hotels",checked:false,notes:""},
      {id:"i7g",text:"Flights",checked:false,notes:""},
      {id:"i7h",text:"Compressor and Dryer - Confirm With Sky",checked:false,notes:""},
      {id:"i7i",text:"Reach Lifts - Confirm With Sky",checked:false,notes:""},
      {id:"i7j",text:"Light Plants - Confirm With Sky",checked:false,notes:""},
      {id:"i7k",text:"Chemicals - Confirm With Sky",checked:false,notes:""},
      {id:"i7l",text:"Coating",checked:false,notes:""},
      {id:"i7m",text:"Training Requirements",checked:false,notes:""},
      {id:"i7n",text:"Rental Trucks",checked:false,notes:""},
      {id:"i7o",text:"Rental Trailers",checked:false,notes:""},
      {id:"i7p",text:"Trailer Shipping",checked:false,notes:""},
      {id:"i7q",text:"Poly Tanks",checked:false,notes:""},
      {id:"i7r",text:"Frac Tanks",checked:false,notes:""},
      {id:"i7s",text:"Certified Clean Frac Tanks",checked:false,notes:""},
      {id:"i7t",text:"MAK Tank / Truck",checked:false,notes:""},
      {id:"i7u",text:"Roll-Off Dumpster",checked:false,notes:""},
      {id:"i7v",text:"Pig Drain Dumpster",checked:false,notes:""},
      {id:"i7w",text:"Water and Acid Pick Ups",checked:false,notes:""},
      {id:"i7x",text:"Haz Boxes Pick Ups",checked:false,notes:""},
      {id:"i7y",text:"Empty Drums Pick Ups",checked:false,notes:""},
    ]
  },
  {
    id: "s8", title: "Job Walk", collapsed: false,
    items: [
      {id:"i8a",text:"Purpose of Meeting",checked:false,notes:""},
      {id:"i8b",text:"Contact personnel",checked:false,notes:""},
      {id:"i8c",text:"Location: Address 1",checked:false,notes:""},
      {id:"i8d",text:"Location: Address 2",checked:false,notes:""},
      {id:"i8e",text:"Start date",checked:false,notes:""},
      {id:"i8f",text:"Run out spools",checked:false,notes:""},
      {id:"i8g",text:"Board mat area",checked:false,notes:""},
      {id:"i8h",text:"Equipment List",checked:false,notes:""},
      {id:"i8i",text:"Training requirements",checked:false,notes:""},
      {id:"i8j",text:"Truck access",checked:false,notes:""},
      {id:"i8k",text:"Insulation requirements",checked:false,notes:""},
      {id:"i8l",text:"Design of Loops",checked:false,notes:""},
      {id:"i8m",text:"Estimate of exposed pipe",checked:false,notes:""},
      {id:"i8n",text:"Estimate of elevation",checked:false,notes:""},
      {id:"i8o",text:"Support needed",checked:false,notes:""},
      {id:"i8p",text:"Disposal",checked:false,notes:""},
    ]
  },
];

function ChecklistPage({checklist, setChecklist, NavBar}) {
  const uid = () => "cl_" + Date.now() + "_" + Math.random().toString(36).slice(2,6);

  const toggleSection = (sId) => {
    setChecklist(prev => prev.map(s => s.id === sId ? {...s, collapsed: !s.collapsed} : s));
  };

  const toggleItem = (sId, iId) => {
    setChecklist(prev => prev.map(s => s.id === sId
      ? {...s, items: s.items.map(it => it.id === iId ? {...it, checked: !it.checked} : it)}
      : s));
  };

  const updateNotes = (sId, iId, val) => {
    setChecklist(prev => prev.map(s => s.id === sId
      ? {...s, items: s.items.map(it => it.id === iId ? {...it, notes: val} : it)}
      : s));
  };

  const addItem = (sId) => {
    const newItem = {id: uid(), text: "New Item", checked: false, notes: ""};
    setChecklist(prev => prev.map(s => s.id === sId ? {...s, items: [...s.items, newItem]} : s));
  };

  const updateItemText = (sId, iId, val) => {
    setChecklist(prev => prev.map(s => s.id === sId
      ? {...s, items: s.items.map(it => it.id === iId ? {...it, text: val} : it)}
      : s));
  };

  const deleteItem = (sId, iId) => {
    setChecklist(prev => prev.map(s => s.id === sId
      ? {...s, items: s.items.filter(it => it.id !== iId)}
      : s));
  };

  const addSection = () => {
    const newSection = {id: uid(), title: "New Section", collapsed: false, items: []};
    setChecklist(prev => [...prev, newSection]);
  };

  const updateSectionTitle = (sId, val) => {
    setChecklist(prev => prev.map(s => s.id === sId ? {...s, title: val} : s));
  };

  const deleteSection = (sId) => {
    if (window.confirm("Delete this section and all its items?")) {
      setChecklist(prev => prev.filter(s => s.id !== sId));
    }
  };

  const handlePrint = () => {
    const printWin = window.open("", "_blank");
    const today = new Date().toLocaleDateString("en-US", {year:"numeric",month:"long",day:"numeric"});
    let html = `<!DOCTYPE html><html><head><title>IPS Checklist</title><style>
      *{box-sizing:border-box;margin:0;padding:0}
      body{font-family:Arial,sans-serif;font-size:12px;color:#111;padding:24px}
      h1{font-size:18px;font-weight:900;color:#333;margin-bottom:4px}
      .sub{font-size:11px;color:#666;margin-bottom:20px}
      .section{margin-bottom:20px;border:1px solid #ccc;border-radius:6px;overflow:hidden}
      .section-title{background:#1a2535;color:#fff;font-size:13px;font-weight:800;padding:8px 12px;text-transform:uppercase;letter-spacing:0.06em}
      table{width:100%;border-collapse:collapse}
      th{background:#f0f0f0;font-size:10px;font-weight:700;text-transform:uppercase;padding:5px 8px;text-align:left;border-bottom:1px solid #ccc}
      tr{border-bottom:1px solid #e8e8e8}
      tr:last-child{border-bottom:none}
      td{padding:6px 8px;vertical-align:top}
      .check-col{width:28px;text-align:center;font-size:14px}
      .text-col{width:40%}
      .notes-col{color:#555}
      .checked-row td{color:#888;text-decoration:line-through}
      @media print{body{padding:12px}}
    </style></head><body>`;
    html += `<h1>IPS — Project Checklist</h1><div class="sub">Printed: ${today}</div>`;
    checklist.forEach(s => {
      html += `<div class="section"><div class="section-title">${s.title}</div>`;
      html += `<table><thead><tr><th class="check-col">✓</th><th class="text-col">Item</th><th>Notes</th></tr></thead><tbody>`;
      s.items.forEach(it => {
        const cls = it.checked ? " class=\"checked-row\"" : "";
        const mark = it.checked ? "✔" : "☐";
        html += `<tr${cls}><td class="check-col">${mark}</td><td class="text-col">${it.text}</td><td class="notes-col">${it.notes || ""}</td></tr>`;
      });
      html += `</tbody></table></div>`;
    });
    html += `</body></html>`;
    printWin.document.write(html);
    printWin.document.close();
    printWin.focus();
    setTimeout(() => { printWin.print(); }, 400);
  };

  const totalItems = checklist.reduce((a, s) => a + s.items.length, 0);
  const checkedItems = checklist.reduce((a, s) => a + s.items.filter(i => i.checked).length, 0);
  const pct = totalItems > 0 ? Math.round((checkedItems / totalItems) * 100) : 0;

  return (
    <div style={{minHeight:"100vh",background:"var(--bg)",paddingBottom:80}}>
      <style>{`
        .cl-item-row { display:flex; align-items:flex-start; gap:10px; padding:10px 14px; border-bottom:1px solid rgba(0,0,0,0.06); }
        .cl-item-row:last-child { border-bottom:none; }
        .cl-check { width:26px; height:26px; min-width:26px; border-radius:6px; border:2px solid rgba(255,165,0,0.4); background:transparent; cursor:pointer; display:flex; align-items:center; justify-content:center; font-size:14px; transition:all 0.15s; }
        .cl-check.checked { background:rgba(255,165,0,0.9); border-color:var(--accent); }
        .cl-item-text { flex:1; font-size:13px; color:var(--text); background:transparent; border:none; outline:none; font-family:var(--font); cursor:text; padding:2px 0; line-height:1.4; }
        .cl-item-text.checked-text { color:var(--text); text-decoration:none; }
        .cl-notes { flex:1.2; font-size:12px; color:var(--muted); background:rgba(0,0,0,0.05); border:1px solid rgba(0,0,0,0.08); border-radius:6px; padding:4px 8px; outline:none; font-family:var(--font); resize:none; min-height:30px; }
        .cl-notes:focus { border-color:rgba(255,165,0,0.35); background:rgba(255,165,0,0.04); }
        .cl-del-btn { color:var(--dim); background:none; border:none; cursor:pointer; font-size:14px; padding:2px 4px; opacity:0.5; }
        .cl-del-btn:hover { opacity:1; color:#ff4444; }
        .cl-section-hdr { display:flex; align-items:center; gap:8px; padding:11px 14px; background:rgba(255,165,0,0.07); border-bottom:1px solid rgba(255,165,0,0.15); cursor:pointer; user-select:none; }
        .cl-add-btn { width:100%; background:rgba(0,0,0,0.04); border:1px dashed rgba(0,0,0,0.12); border-radius:0; padding:9px; color:var(--muted); font-size:12px; cursor:pointer; font-family:var(--font); transition:background 0.15s; }
        .cl-add-btn:hover { background:rgba(255,165,0,0.06); color:var(--accent); border-color:rgba(255,165,0,0.25); }
        @media print { .no-print{display:none!important} }
      `}</style>

      {/* Header */}
      <div style={{padding:"18px 16px 12px",background:"rgba(245,246,248,0.97)",borderBottom:"1px solid var(--border)",position:"sticky",top:0,zIndex:100}}>
        <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:10}}>
          <div style={{fontSize:15,fontWeight:900,color:"var(--accent)",letterSpacing:"0.06em",textTransform:"uppercase"}}>☑ Checklist</div>
          <button onClick={handlePrint} style={{background:"rgba(255,165,0,0.15)",border:"1px solid rgba(255,165,0,0.4)",borderRadius:8,padding:"7px 14px",color:"var(--accent)",fontSize:12,fontWeight:800,cursor:"pointer",fontFamily:"var(--font)"}}>🖨 Print</button>
        </div>
        {/* Progress bar */}
        <div style={{display:"flex",alignItems:"center",gap:10}}>
          <div style={{flex:1,height:6,background:"rgba(0,0,0,0.08)",borderRadius:3,overflow:"hidden"}}>
            <div style={{height:"100%",width:`${pct}%`,background:"var(--accent)",borderRadius:3,transition:"width 0.3s"}} />
          </div>
          <span style={{fontSize:11,color:"var(--muted)",fontWeight:700,whiteSpace:"nowrap"}}>{checkedItems}/{totalItems} ({pct}%)</span>
        </div>
      </div>

      {/* Sections */}
      <div style={{padding:"12px 0"}}>
        {checklist.map(section => {
          const sChecked = section.items.filter(i => i.checked).length;
          return (
            <div key={section.id} style={{marginBottom:12,background:"rgba(0,0,0,0.03)",borderRadius:12,border:"1px solid var(--border)",overflow:"hidden",margin:"0 12px 12px"}}>
              {/* Section header */}
              <div className="cl-section-hdr" onClick={() => toggleSection(section.id)}>
                <span style={{fontSize:13,color:"var(--muted)",transition:"transform 0.2s",display:"inline-block",transform:section.collapsed?"rotate(-90deg)":"rotate(0deg)"}}>▾</span>
                <input
                  value={section.title}
                  onChange={e => { e.stopPropagation(); updateSectionTitle(section.id, e.target.value); }}
                  onClick={e => e.stopPropagation()}
                  style={{flex:1,background:"transparent",border:"none",outline:"none",color:"var(--accent)",fontWeight:800,fontSize:13,fontFamily:"var(--font)",textTransform:"uppercase",letterSpacing:"0.06em",cursor:"text"}}
                />
                <span style={{fontSize:11,color:"var(--dim)",fontWeight:700,whiteSpace:"nowrap"}}>{sChecked}/{section.items.length}</span>
                <button onClick={e=>{e.stopPropagation();deleteSection(section.id);}} style={{background:"none",border:"none",cursor:"pointer",color:"var(--dim)",fontSize:14,padding:"0 2px",opacity:0.5,marginLeft:4}} title="Delete section">🗑</button>
              </div>

              {!section.collapsed && (
                <>
                  {/* Column headers */}
                  <div style={{display:"flex",gap:10,padding:"5px 14px",background:"rgba(0,0,0,0.04)",borderBottom:"1px solid rgba(0,0,0,0.06)"}}>
                    <div style={{width:26,minWidth:26}} />
                    <div style={{flex:1,fontSize:9,color:"var(--dim)",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.1em"}}>Item</div>
                    <div style={{flex:1.2,fontSize:9,color:"var(--dim)",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.1em"}}>Notes</div>
                    <div style={{width:22}} />
                  </div>

                  {/* Items */}
                  {section.items.map(item => (
                    <div key={item.id} className="cl-item-row">
                      <button
                        className={"cl-check" + (item.checked ? " checked" : "")}
                        onClick={() => toggleItem(section.id, item.id)}
                      >
                        {item.checked ? "✓" : ""}
                      </button>
                      <input
                        className={"cl-item-text" + (item.checked ? " checked-text" : "")}
                        value={item.text}
                        onChange={e => updateItemText(section.id, item.id, e.target.value)}
                      />
                      <textarea
                        className="cl-notes"
                        value={item.notes}
                        placeholder="Notes…"
                        rows={1}
                        onChange={e => updateNotes(section.id, item.id, e.target.value)}
                      />
                      <button className="cl-del-btn" onClick={() => deleteItem(section.id, item.id)} title="Remove item">✕</button>
                    </div>
                  ))}

                  {/* Add Item */}
                  <button className="cl-add-btn" onClick={() => addItem(section.id)}>+ Add Item</button>
                </>
              )}
            </div>
          );
        })}

        {/* Add Section */}
        <div style={{padding:"0 12px"}}>
          <button
            onClick={addSection}
            style={{width:"100%",background:"rgba(255,165,0,0.06)",border:"1px dashed rgba(255,165,0,0.3)",borderRadius:10,padding:12,color:"var(--accent)",fontSize:13,fontWeight:700,cursor:"pointer",fontFamily:"var(--font)"}}>
            + Add Section
          </button>
        </div>
      </div>

      <NavBar />
    </div>
  );
}

// ======== MENU OVERLAY ========

// ======== PHOTOS PAGE ========
function PhotosPage({photos, setPhotos, proj, NavBar}) {
  const fileInputRef = React.useRef(null);
  const cameraInputRef = React.useRef(null);

  // Upload files to Firebase Storage, store download URL in photo record
  const addPhotos = (files) => {
    const storage = getStorage();
    const arr = Array.from(files);
    arr.forEach(file => {
      const photoId = Date.now() + "_" + Math.random().toString(36).slice(2,8);
      const timestamp = Date.now();
      // Add placeholder immediately so user sees it loading
      const placeholder = {
        id: photoId,
        timestamp,
        description: "",
        addToDaily: false,
        addToFinal: false,
        uploadProgress: 0,
        storageUrl: null,
        dataUrl: null,
      };
      setPhotos(prev => [placeholder, ...prev]);

      if (storage) {
        // Upload to Firebase Storage
        const projectId = proj?.id || "unknown";
        const path = `photos/${COMPANY}/${projectId}/${photoId}`;
        const ref = storage.ref(path);
        const task = ref.put(file);
        task.on("state_changed",
          snap => {
            const pct = Math.round((snap.bytesTransferred / snap.totalBytes) * 100);
            setPhotos(prev => prev.map(p => p.id === photoId ? {...p, uploadProgress: pct} : p));
          },
          err => {
            console.error("Photo upload error:", err);
            // Fall back to local dataUrl if upload fails
            const reader = new FileReader();
            reader.onload = e => {
              setPhotos(prev => prev.map(p => p.id === photoId ? {...p, dataUrl: e.target.result, uploadProgress: null, uploadError: true} : p));
            };
            reader.readAsDataURL(file);
          },
          async () => {
            const url = await task.snapshot.ref.getDownloadURL();
            setPhotos(prev => prev.map(p => p.id === photoId ? {...p, storageUrl: url, uploadProgress: null} : p));
          }
        );
      } else {
        // No storage available — fall back to dataUrl
        const reader = new FileReader();
        reader.onload = e => {
          setPhotos(prev => prev.map(p => p.id === photoId ? {...p, dataUrl: e.target.result, uploadProgress: null} : p));
        };
        reader.readAsDataURL(file);
      }
    });
  };

  const updatePhoto = (id, updates) => {
    setPhotos(prev => prev.map(p => p.id === id ? {...p, ...updates} : p));
  };

  const deletePhoto = async (id) => {
    if (!window.confirm("Delete this photo?")) return;
    const photo = photos.find(p => p.id === id);
    // Delete from Firebase Storage if it has a storage path
    if (photo?.storageUrl && getStorage()) {
      try {
        const projectId = proj?.id || "unknown";
        const path = `photos/${COMPANY}/${projectId}/${id}`;
        await getStorage().ref(path).delete();
      } catch(e) { /* ignore — file may already be gone */ }
    }
    setPhotos(prev => prev.filter(p => p.id !== id));
  };

  const fmtTs = (ts) => {
    const d = new Date(ts);
    return d.toLocaleDateString("en-US", {month:"short",day:"numeric",year:"numeric"}) + " " +
      d.toLocaleTimeString("en-US", {hour:"numeric",minute:"2-digit",hour12:true});
  };

  const imgSrc = (photo) => photo.storageUrl || photo.dataUrl || null;

  const dailyCount = (photos||[]).filter(p=>p.addToDaily).length;
  const finalCount = (photos||[]).filter(p=>p.addToFinal).length;

  return (
    <div style={{minHeight:"100vh",background:"var(--bg)",paddingBottom:100}}>
      <style>{`
        .photo-card { background:rgba(0,0,0,0.04); border:1px solid var(--border); border-radius:14px; overflow:hidden; margin:0 12px 14px; }
        .photo-img { width:100%; max-height:260px; object-fit:cover; display:block; }
        .photo-body { padding:12px 14px; }
        .photo-desc { width:100%; background:rgba(0,0,0,0.06); border:1px solid rgba(0,0,0,0.08); border-radius:8px; color:var(--text); font-size:13px; font-family:var(--font); padding:8px 10px; outline:none; resize:none; min-height:48px; box-sizing:border-box; }
        .photo-desc:focus { border-color:rgba(255,165,0,0.4); background:rgba(255,165,0,0.04); }
        .photo-toggle { display:flex; align-items:center; gap:8px; padding:8px 0; cursor:pointer; user-select:none; }
        .photo-toggle-box { width:22px; height:22px; border-radius:6px; border:2px solid rgba(0,0,0,0.25); background:transparent; display:flex; align-items:center; justify-content:center; font-size:13px; transition:all 0.15s; flex-shrink:0; }
        .photo-toggle-box.on { background:rgba(255,165,0,0.9); border-color:var(--accent); }
        .photo-toggle-label { font-size:12px; color:var(--muted); font-weight:700; }
        @media print { .no-print{display:none!important} }
      `}</style>

      {/* Header */}
      <div style={{padding:"18px 16px 14px",background:"rgba(245,246,248,0.97)",borderBottom:"1px solid var(--border)",position:"sticky",top:0,zIndex:100}}>
        <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:12}}>
          <div style={{fontSize:15,fontWeight:900,color:"var(--accent)",letterSpacing:"0.06em",textTransform:"uppercase"}}>📷 Photos</div>
          <div style={{fontSize:11,color:"var(--dim)",fontWeight:700}}>{(photos||[]).length} photo{(photos||[]).length!==1?"s":""}</div>
        </div>
        <div style={{display:"flex",gap:8}}>
          <button onClick={()=>cameraInputRef.current?.click()} style={{flex:1,background:"rgba(255,165,0,0.15)",border:"1px solid rgba(255,165,0,0.4)",borderRadius:12,padding:"12px 8px",color:"var(--accent)",fontSize:13,fontWeight:800,cursor:"pointer",fontFamily:"var(--font)",display:"flex",alignItems:"center",justifyContent:"center",gap:6}}>
            📷 Camera
          </button>
          <button onClick={()=>fileInputRef.current?.click()} style={{flex:1,background:"rgba(0,0,0,0.06)",border:"1px solid var(--border)",borderRadius:12,padding:"12px 8px",color:"var(--muted)",fontSize:13,fontWeight:800,cursor:"pointer",fontFamily:"var(--font)",display:"flex",alignItems:"center",justifyContent:"center",gap:6}}>
            🖼 Library
          </button>
        </div>
        {(dailyCount > 0 || finalCount > 0) && (
          <div style={{marginTop:10,display:"flex",gap:8}}>
            {dailyCount > 0 && <span style={{fontSize:10,fontWeight:800,color:"var(--accent)",background:"rgba(255,165,0,0.1)",border:"1px solid rgba(255,165,0,0.3)",borderRadius:8,padding:"3px 8px"}}>{dailyCount} → Daily</span>}
            {finalCount > 0 && <span style={{fontSize:10,fontWeight:800,color:"#60c0ff",background:"rgba(96,192,255,0.1)",border:"1px solid rgba(96,192,255,0.3)",borderRadius:8,padding:"3px 8px"}}>{finalCount} → Final</span>}
          </div>
        )}
        <input ref={cameraInputRef} type="file" accept="image/*" capture="environment" multiple style={{display:"none"}} onChange={e=>{addPhotos(e.target.files);e.target.value="";}} />
        <input ref={fileInputRef} type="file" accept="image/*" multiple style={{display:"none"}} onChange={e=>{addPhotos(e.target.files);e.target.value="";}} />
      </div>

      {/* Photo list */}
      <div style={{padding:"14px 0"}}>
        {(photos||[]).length === 0 && (
          <div style={{textAlign:"center",padding:"60px 24px",color:"var(--dim)"}}>
            <div style={{fontSize:48,marginBottom:12}}>📷</div>
            <div style={{fontSize:14,fontWeight:700,marginBottom:6}}>No photos yet</div>
            <div style={{fontSize:12}}>Tap Camera to take a photo or Library to upload one.</div>
          </div>
        )}
        {(photos||[]).map(photo => (
          <div key={photo.id} className="photo-card">
            <div style={{position:"relative"}}>
              {/* Upload progress bar */}
              {photo.uploadProgress != null && (
                <div style={{background:"rgba(0,0,0,0.7)",padding:"24px 16px",textAlign:"center"}}>
                  <div style={{fontSize:12,color:"var(--accent)",fontWeight:800,marginBottom:8}}>Uploading… {photo.uploadProgress}%</div>
                  <div style={{background:"rgba(0,0,0,0.08)",borderRadius:8,height:8,overflow:"hidden"}}>
                    <div style={{background:"var(--accent)",height:"100%",width:photo.uploadProgress+"%",transition:"width 0.2s",borderRadius:8}} />
                  </div>
                </div>
              )}
              {/* Photo image — show once uploaded */}
              {photo.uploadProgress == null && imgSrc(photo) && (
                <>
                  <img src={imgSrc(photo)} alt="" className="photo-img" />
                  <button onClick={()=>deletePhoto(photo.id)} style={{position:"absolute",top:8,right:8,background:"rgba(0,0,0,0.65)",border:"none",borderRadius:8,color:"#fff",fontSize:16,padding:"5px 8px",cursor:"pointer",backdropFilter:"blur(4px)"}}>🗑</button>
                  <div style={{position:"absolute",bottom:8,left:8,background:"rgba(0,0,0,0.65)",borderRadius:8,padding:"4px 8px",fontSize:10,color:"rgba(255,255,255,0.85)",fontWeight:700,backdropFilter:"blur(4px)"}}>{fmtTs(photo.timestamp)}</div>
                  {photo.uploadError && <div style={{position:"absolute",top:8,left:8,background:"rgba(255,80,80,0.85)",borderRadius:8,padding:"3px 8px",fontSize:10,color:"#fff",fontWeight:700}}>⚠ Saved locally only</div>}
                </>
              )}
            </div>
            {photo.uploadProgress == null && (
              <div className="photo-body">
                <textarea className="photo-desc" placeholder="Add a description..." value={photo.description} onChange={e=>updatePhoto(photo.id,{description:e.target.value})} rows={2} />
                <div style={{display:"flex",gap:16,marginTop:6}}>
                  <div className="photo-toggle" onClick={()=>updatePhoto(photo.id,{addToDaily:!photo.addToDaily})}>
                    <div className={"photo-toggle-box"+(photo.addToDaily?" on":"")}>
                      {photo.addToDaily && <span style={{color:"#000",fontWeight:900,fontSize:12}}>✓</span>}
                    </div>
                    <span className="photo-toggle-label">Add to Daily Report</span>
                  </div>
                  <div className="photo-toggle" onClick={()=>updatePhoto(photo.id,{addToFinal:!photo.addToFinal})}>
                    <div className={"photo-toggle-box"+(photo.addToFinal?" on":"")}>
                      {photo.addToFinal && <span style={{color:"#000",fontWeight:900,fontSize:12}}>✓</span>}
                    </div>
                    <span className="photo-toggle-label">Add to Final Report</span>
                  </div>
                </div>
              </div>
            )}
          </div>
        ))}
      </div>
      <NavBar />
    </div>
  );
}

function MenuOverlay({page, setPage, onClose, clearRun, isPrimary, tabPermissions, onCrewPage}) {
  const ALL_NAV = [
    {id:"runs",l:"Runs",i:"▶"},
    {id:"runsheet",l:"Sheet",i:"▤"},
    {id:"results",l:"Results",i:"◈"},
    {id:"notes",l:"Notes",i:"✎"},
    {id:"report",l:"Daily",i:"▻"},
    {id:"final",l:"Final",i:"▪"},
    {id:"archive",l:"Archive",i:"🗄"},
    {id:"coating",l:"Coat",i:"◎"},
    {id:"jsa",l:"JSA",i:"🛡"},
    {id:"deliveries",l:"Deliveries",i:"🚛"},
    {id:"comps",l:"Comps",i:"⚙️"},
    {id:"inspect",l:"DFT",i:"📏"},
    {id:"checklist",l:"Check",i:"☑"},
    {id:"photos",l:"Photos",i:"📷"},
    {id:"manhours",l:"Hours",i:"⏱"},
    {id:"setup",l:"Setup",i:"⚙"},
  ];

  const perms = tabPermissions || {};
  const NAV = isPrimary ? ALL_NAV : ALL_NAV.filter(n => perms[n.id] !== false);

  return (
    <div style={{position:"fixed",inset:0,zIndex:500,display:"flex",alignItems:"flex-end"}} onClick={onClose}>
      <div onClick={e=>e.stopPropagation()} style={{width:"100%",maxWidth:460,margin:"0 auto",background:"rgba(245,246,248,0.99)",backdropFilter:"blur(20px)",borderRadius:"20px 20px 0 0",border:"1px solid var(--border)",padding:"20px 16px 32px",paddingBottom:"calc(32px + env(safe-area-inset-bottom,0))"}}>
        <div style={{width:36,height:4,background:"var(--border)",borderRadius:2,margin:"0 auto 16px"}} />
        <div style={{fontSize:11,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.1em",textAlign:"center",marginBottom:14}}>Navigation</div>
        <div style={{display:"grid",gridTemplateColumns:"repeat(5,1fr)",gap:8}}>
          {NAV.map(n=>(
            <button key={n.id} onClick={()=>{setPage(n.id);onClose()}} style={{background:page===n.id?"rgba(255,165,0,0.15)":"rgba(0,0,0,0.05)",border:`1px solid ${page===n.id?"rgba(255,165,0,0.4)":"var(--border)"}`,borderRadius:12,padding:"12px 6px",cursor:"pointer",display:"flex",flexDirection:"column",alignItems:"center",gap:4,color:page===n.id?"var(--accent)":"var(--muted)",fontFamily:"var(--font)"}}>
              <span style={{fontSize:18}}>{n.i}</span>
              <span style={{fontSize:9,fontWeight:700,textTransform:"uppercase"}}>{n.l}</span>
            </button>
          ))}
        </div>
        {isPrimary&&<button onClick={()=>{onClose();onCrewPage();}} style={{marginTop:14,width:"100%",background:"rgba(255,165,0,0.08)",border:"1px solid rgba(255,165,0,0.25)",borderRadius:10,padding:"11px",color:"var(--accent)",fontSize:12,fontWeight:800,cursor:"pointer",fontFamily:"var(--font)"}}>👥 Crew Management</button>}
        <div style={{marginTop:10,fontSize:10,color:"var(--dim)",textAlign:"center"}}>Device: {window._debugDeviceId||"?"} | Role: {isPrimary?"Manager":"Crew"}</div>
      </div>
    </div>
  );
}

// ======== MAN HOURS PAGE ========
function ManHoursPage({jsas, setJSAs, NavBar}) {
  const { useState, useMemo } = React;

  // ── helpers ──────────────────────────────────────────────────────────────────
  const msToHours = (ms) => ms / 3600000;
  const fmtHrs = (h) => {
    if (!h || h <= 0) return "—";
    const totalMin = Math.round(h * 60);
    const hr = Math.floor(totalMin / 60);
    const mn = totalMin % 60;
    return hr > 0 ? `${hr}h ${mn}m` : `${mn}m`;
  };
  const fmtDecimal = (h) => (!h || h <= 0) ? "—" : h.toFixed(2) + " hrs";

  // Parse a time-string stored in crewSignIn/Out into a Date on a given day-string
  // sign.time is a timestamp (ms). sign.timeStr might not exist — use sign.time.
  const getTs = (sign) => {
    if (sign.time && typeof sign.time === "number") return sign.time;
    return null;
  };

  // ── collect all dates that have JSA data ────────────────────────────────────
  const allDates = useMemo(() => {
    const s = new Set();
    (jsas || []).forEach(j => { if (j.date) s.add(j.date); });
    return [...s].sort((a, b) => new Date(b) - new Date(a));
  }, [jsas]);

  const todayStr = new Date().toLocaleDateString("en-US");
  const [selDate, setSelDate] = useState(allDates[0] || todayStr);
  const [showPicker, setShowPicker] = useState(false);

  // ── JSAs for selected day ───────────────────────────────────────────────────
  const dayJSAs = useMemo(() =>
    (jsas || []).filter(j => j.date === selDate),
    [jsas, selDate]
  );

  // ── calculate per-person hours for a JSA ───────────────────────────────────
  const calcPersonHours = (jsa) => {
    const signInMap = {};
    (jsa.crewSignIn || []).forEach(s => {
      const ts = getTs(s);
      if (s.name && ts) signInMap[s.name] = ts;
    });
    const signOutMap = {};
    (jsa.crewSignOut || []).forEach(s => {
      const ts = getTs(s);
      if (s.name && ts) signOutMap[s.name] = ts;
    });

    const names = [...new Set([...Object.keys(signInMap), ...Object.keys(signOutMap)])];
    return names.map(name => {
      const inTs = signInMap[name] || null;
      const outTs = signOutMap[name] || null;
      const ms = (inTs && outTs && outTs > inTs) ? outTs - inTs : null;
      return { name, inTs, outTs, ms, hours: ms ? msToHours(ms) : null };
    }).sort((a, b) => a.name.localeCompare(b.name));
  };

  // ── day totals ──────────────────────────────────────────────────────────────
  const dayPersonHours = useMemo(() => {
    const map = {};
    dayJSAs.forEach(jsa => {
      calcPersonHours(jsa).forEach(({ name, ms }) => {
        if (!map[name]) map[name] = 0;
        if (ms) map[name] += ms;
      });
    });
    return map;
  }, [dayJSAs]);

  const dayTotalMs = Object.values(dayPersonHours).reduce((s, ms) => s + ms, 0);

  // ── project totals ──────────────────────────────────────────────────────────
  const projectPersonHours = useMemo(() => {
    const map = {};
    (jsas || []).forEach(jsa => {
      calcPersonHours(jsa).forEach(({ name, ms }) => {
        if (!map[name]) map[name] = 0;
        if (ms) map[name] += ms;
      });
    });
    return map;
  }, [jsas]);

  const projectTotalMs = Object.values(projectPersonHours).reduce((s, ms) => s + ms, 0);

  // ── toggle include-in-report for the whole selected day ────────────────────
  // dayIncluded is true by default — only false if user has explicitly unchecked it (hoursReportSet === true && includeHoursInReport === false)
  const dayIncluded = dayJSAs.length > 0 && dayJSAs.every(j => !(j.hoursReportSet === true && j.includeHoursInReport === false));
  const toggleDayInclude = () => {
    const next = !dayIncluded;
    setJSAs(prev => prev.map(j => j.date === selDate ? { ...j, includeHoursInReport: next, hoursReportSet: true } : j));
  };

  const displayDate = selDate || todayStr;

  return (
    <div style={{padding:"12px 16px",maxWidth:CONTAINER_MAX,margin:"0 auto",paddingBottom:100}}>
      <div style={{fontSize:16,fontWeight:900,fontFamily:"var(--display)",textAlign:"center",marginBottom:16}}>MAN HOURS</div>

      {/* Day selector */}
      <div style={{...S.card,padding:"10px 14px",marginBottom:12}}>
        <div style={S.ct}>Select Day</div>
        <button onClick={()=>setShowPicker(true)} style={{...S.ba,width:"100%",padding:"12px",fontSize:14,textAlign:"left"}}>
          📅 {displayDate}{displayDate===todayStr?" (Today)":""}
        </button>
        {showPicker && (
          <PopupMenu
            title="Select Day"
            options={allDates.length > 0 ? allDates.map(d => d + (d===todayStr?" (Today)":"")) : [todayStr+" (Today)"]}
            onSelect={v => {
              const raw = v.replace(" (Today)","");
              setSelDate(raw);
              setShowPicker(false);
            }}
            onClose={()=>setShowPicker(false)}
          />
        )}
      </div>

      {/* Day summary card */}
      <div style={{...S.card,background:"linear-gradient(135deg,rgba(255,165,0,0.07),rgba(180,70,0,0.04))",border:"1px solid rgba(255,165,0,0.22)",marginBottom:12}}>
        <div style={{...S.ct,marginBottom:10}}>Day Total — {displayDate}</div>
        {Object.keys(dayPersonHours).length === 0 ? (
          <div style={{fontSize:13,color:"var(--muted)",textAlign:"center",padding:"8px 0"}}>No sign-in / sign-out data for this day</div>
        ) : (
          <>
            <div style={{display:"grid",gridTemplateColumns:"1fr auto auto",gap:"6px 12px",alignItems:"center",marginBottom:8}}>
              <div style={{fontSize:9,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.08em"}}>Name</div>
              <div style={{fontSize:9,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",textAlign:"right",letterSpacing:"0.08em"}}>Time</div>
              <div style={{fontSize:9,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",textAlign:"right",letterSpacing:"0.08em"}}>Decimal</div>
              {Object.entries(dayPersonHours).sort((a,b)=>a[0].localeCompare(b[0])).map(([name, ms])=>(
                <React.Fragment key={name}>
                  <div style={{fontSize:13,fontWeight:600,color:"var(--text)"}}>{name}</div>
                  <div style={{fontSize:13,fontWeight:800,color:"var(--text)",fontFamily:"var(--mono)",textAlign:"right"}}>{fmtHrs(msToHours(ms))}</div>
                  <div style={{fontSize:11,color:"var(--muted)",fontFamily:"var(--mono)",textAlign:"right"}}>{fmtDecimal(msToHours(ms))}</div>
                </React.Fragment>
              ))}
            </div>
            <div style={{borderTop:"1px solid var(--border)",paddingTop:8,display:"flex",justifyContent:"space-between",alignItems:"center"}}>
              <div style={{fontSize:12,fontWeight:900,color:"var(--accent)",textTransform:"uppercase",letterSpacing:"0.08em"}}>Day Total</div>
              <div style={{display:"flex",gap:16,alignItems:"center"}}>
                <div style={{fontSize:16,fontWeight:900,color:"var(--accent)",fontFamily:"var(--mono)"}}>{fmtHrs(msToHours(dayTotalMs))}</div>
                <div style={{fontSize:12,color:"var(--muted)",fontFamily:"var(--mono)"}}>{fmtDecimal(msToHours(dayTotalMs))}</div>
              </div>
            </div>
          </>
        )}
      </div>

      {/* Single include-in-daily-report button for the selected day */}
      {dayJSAs.length > 0 && Object.keys(dayPersonHours).length > 0 && (
        <div
          onClick={toggleDayInclude}
          style={{
            ...S.card,
            marginBottom:12,
            cursor:"pointer",
            display:"flex",alignItems:"center",justifyContent:"space-between",
            padding:"12px 16px",
            border:`2px solid ${dayIncluded?"var(--accent)":"var(--border)"}`,
            background:dayIncluded?"rgba(255,165,0,0.08)":"transparent",
          }}
        >
          <div>
            <div style={{fontSize:13,fontWeight:800,color:dayIncluded?"var(--accent)":"var(--text)"}}>
              {dayIncluded ? "✓ Included in Daily Report" : "Include Hours in Daily Report"}
            </div>
            <div style={{fontSize:11,color:"var(--muted)",marginTop:2}}>
              {Object.keys(dayPersonHours).length} crew · {fmtHrs(msToHours(dayTotalMs))} total
            </div>
          </div>
          <div style={{
            width:28,height:28,borderRadius:8,flexShrink:0,
            border:`2px solid ${dayIncluded?"var(--accent)":"var(--border)"}`,
            background:dayIncluded?"var(--accent)":"transparent",
            display:"flex",alignItems:"center",justifyContent:"center"
          }}>
            {dayIncluded && <span style={{color:"#000",fontSize:15,fontWeight:900,lineHeight:1}}>✓</span>}
          </div>
        </div>
      )}

      {/* Per-JSA breakdown for day */}
      {dayJSAs.length > 0 && (
        <div style={{marginBottom:12}}>
          <div style={{fontSize:11,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.08em",marginBottom:8}}>
            JSA Breakdown — {dayJSAs.length} JSA{dayJSAs.length>1?"s":""} this day
          </div>
          {dayJSAs.map((jsa, ji) => {
            const persons = calcPersonHcoursForJSA(jsa);
            const jsaTotalMs = persons.reduce((s, p) => s + (p.ms||0), 0);
            return (
              <div key={jsa.id} style={{...S.card,padding:"12px 14px",marginBottom:8,border:"1px solid var(--border)"}}>
                <div style={{marginBottom:10}}>
                  <div style={{fontSize:12,fontWeight:800,color:"var(--accent)"}}>
                    JSA #{ji+1}{jsa.tasks&&jsa.tasks.length>0?" — "+jsa.tasks.slice(0,2).map(t=>t.type==="Manual Entry"?t.customLabel||"Manual":t.type).join(", "):""}
                  </div>
                  {jsa.supervisor && <div style={{fontSize:10,color:"var(--muted)"}}>Supervisor: {jsa.supervisor}</div>}
                </div>

                {/* Sign-in / out table */}
                {persons.length === 0 ? (
                  <div style={{fontSize:12,color:"var(--muted)",fontStyle:"italic"}}>No sign-in data</div>
                ) : (
                  <>
                    <div style={{display:"grid",gridTemplateColumns:"1fr auto auto auto",gap:"5px 10px",alignItems:"center",marginBottom:6}}>
                      {["Name","In","Out","Hours"].map(h=>(
                        <div key={h} style={{fontSize:9,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.06em",textAlign:h==="Name"?"left":"right"}}>{h}</div>
                      ))}
                      {persons.map(p=>(
                        <React.Fragment key={p.name}>
                          <div style={{fontSize:12,fontWeight:600,color:"var(--text)"}}>{p.name}</div>
                          <div style={{fontSize:11,color:"var(--muted)",fontFamily:"var(--mono)",textAlign:"right"}}>{p.inTs?Fmt.timeShort(p.inTs):"—"}</div>
                          <div style={{fontSize:11,color:"var(--muted)",fontFamily:"var(--mono)",textAlign:"right"}}>{p.outTs?Fmt.timeShort(p.outTs):"—"}</div>
                          <div style={{fontSize:12,fontWeight:800,color:p.hours?"var(--text)":"#ff6b6b",fontFamily:"var(--mono)",textAlign:"right"}}>
                            {p.hours ? fmtHrs(p.hours) : "—"}
                          </div>
                        </React.Fragment>
                      ))}
                    </div>
                    {jsaTotalMs > 0 && (
                      <div style={{borderTop:"1px solid var(--border)",paddingTop:6,display:"flex",justifyContent:"space-between"}}>
                        <div style={{fontSize:11,color:"var(--muted)",fontWeight:700}}>JSA Total</div>
                        <div style={{fontSize:13,fontWeight:900,color:"var(--accent)",fontFamily:"var(--mono)"}}>{fmtHrs(msToHours(jsaTotalMs))}</div>
                      </div>
                    )}
                  </>
                )}
              </div>
            );
          })}
        </div>
      )}

      {dayJSAs.length === 0 && (
        <div style={{textAlign:"center",color:"var(--dim)",padding:"32px 0",fontSize:13}}>
          No JSAs recorded for {displayDate}
        </div>
      )}

      {/* Project running total */}
      <div style={{...S.card,border:"2px solid rgba(255,165,0,0.3)",marginTop:8}}>
        <div style={{...S.ct,marginBottom:10}}>Project Running Total</div>
        {Object.keys(projectPersonHours).length === 0 ? (
          <div style={{fontSize:13,color:"var(--muted)",textAlign:"center",padding:"8px 0"}}>No hours recorded yet</div>
        ) : (
          <>
            <div style={{display:"grid",gridTemplateColumns:"1fr auto auto",gap:"6px 12px",alignItems:"center",marginBottom:8}}>
              <div style={{fontSize:9,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.08em"}}>Name</div>
              <div style={{fontSize:9,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",textAlign:"right"}}>Time</div>
              <div style={{fontSize:9,color:"var(--muted)",fontWeight:700,textTransform:"uppercase",textAlign:"right"}}>Decimal</div>
              {Object.entries(projectPersonHours).sort((a,b)=>a[0].localeCompare(b[0])).map(([name,ms])=>(
                <React.Fragment key={name}>
                  <div style={{fontSize:13,fontWeight:600,color:"var(--text)"}}>{name}</div>
                  <div style={{fontSize:13,fontWeight:800,color:"var(--text)",fontFamily:"var(--mono)",textAlign:"right"}}>{fmtHrs(msToHours(ms))}</div>
                  <div style={{fontSize:11,color:"var(--muted)",fontFamily:"var(--mono)",textAlign:"right"}}>{fmtDecimal(msToHours(ms))}</div>
                </React.Fragment>
              ))}
            </div>
            <div style={{borderTop:"2px solid rgba(255,165,0,0.3)",paddingTop:8,display:"flex",justifyContent:"space-between",alignItems:"center"}}>
              <div style={{fontSize:13,fontWeight:900,color:"var(--accent)",textTransform:"uppercase",letterSpacing:"0.06em"}}>Project Total</div>
              <div style={{display:"flex",gap:16,alignItems:"center"}}>
                <div style={{fontSize:20,fontWeight:900,color:"var(--accent)",fontFamily:"var(--mono)"}}>{fmtHrs(msToHours(projectTotalMs))}</div>
                <div style={{fontSize:12,color:"var(--muted)",fontFamily:"var(--mono)"}}>{fmtDecimal(msToHours(projectTotalMs))}</div>
              </div>
            </div>
          </>
        )}
      </div>

      <NavBar />
    </div>
  );
}

// helper used inside ManHoursPage (hoisted so JSX can call it)
function calcPersonHcoursForJSA(jsa) {
  const getTs = (sign) => (sign.time && typeof sign.time === "number") ? sign.time : null;
  const msToHours = (ms) => ms / 3600000;
  const signInMap = {};
  (jsa.crewSignIn || []).forEach(s => { const ts = getTs(s); if (s.name && ts) signInMap[s.name] = ts; });
  const signOutMap = {};
  (jsa.crewSignOut || []).forEach(s => { const ts = getTs(s); if (s.name && ts) signOutMap[s.name] = ts; });
  const names = [...new Set([...Object.keys(signInMap), ...Object.keys(signOutMap)])];
  return names.map(name => {
    const inTs = signInMap[name] || null;
    const outTs = signOutMap[name] || null;
    const ms = (inTs && outTs && outTs > inTs) ? outTs - inTs : null;
    return { name, inTs, outTs, ms, hours: ms ? msToHours(ms) : null };
  }).sort((a, b) => a.name.localeCompare(b.name));
}

