/* ASM workspace screens. Persistence and classification are owned by store/API. */
function WorkspaceBadge({ id, className = '' }) {
  const { workspaceConfig } = useStore();
  const w = id === 'all' ? {name:t("ws.all"),color:'#6b727c'} : workspaceConfig.workspaces.find(w => w.id === (id || ASM_WORKSPACES.DEFAULT_ID));
  if (!w) return null;
  return <span className={'asm-chip ' + className} style={{color:w.color,background:w.color+'12'}}><span className="asm-chip-dot" style={{background:w.color}}/><span className="asm-chip-label" title={w.name}>{w.name}</span></span>;
}

function WorkspacePicker() {
  const { workspaceId, workspaceConfig, switchWorkspace, workspaceInbox, can, navigate, canManageWorkspaces, joinedWorkspaces } = useStore();
  const [open,setOpen] = React.useState(false);
  const [pos,setPos] = React.useState({top:90,left:14});
  const ref = React.useRef(null), menu = React.useRef(null);
  const w = workspaceConfig.workspaces.find(w => w.id === workspaceId) || {name:joinedWorkspaces.length?t("ws.all"):t("ws.noMembershipShort"),color:'#7de3f7'};
  const count = workspaceInbox.filter(i => i.status === 'pending').length;
  React.useEffect(() => {
    const close = e => { if (e.key === 'Escape' || (e.type === 'mousedown' && !ref.current?.contains(e.target) && !menu.current?.contains(e.target))) setOpen(false); };
    document.addEventListener('mousedown',close); document.addEventListener('keydown',close);
    return () => { document.removeEventListener('mousedown',close); document.removeEventListener('keydown',close); };
  },[]);
  return <div className="asm-workspace-picker" ref={ref}>
    <button className="asm-workspace-trigger" aria-label={t("ws.switch")} aria-expanded={open} onClick={() => {const r=ref.current.getBoundingClientRect();setPos({top:r.bottom+6,left:r.left});setOpen(!open);}}>
      <span className="asm-chip-dot" style={{background:w.color,boxShadow:'0 0 0 3px '+w.color+'33'}}/><span style={{flex:1,minWidth:0}}><small>{t("ws.label")}</small><strong>{w.name}</strong></span>
      {!!count && <span className="asm-count" style={{background:'#7de3f7',color:'#191c28'}}>{count}</span>}<Icon name="chevronDown" size={14}/>
    </button>
    {open && ReactDOM.createPortal(<div ref={menu} className="asm-ws-menu" style={{...pos,width:216,maxHeight:'60vh',overflowY:'auto'}}>
      {[...joinedWorkspaces.filter(w=>w.active),{id:'all',name:t("ws.all"),color:'#6b727c'}].map(w=><button key={w.id} onClick={()=>{switchWorkspace(w.id);setOpen(false);}}><span className="asm-chip-dot" style={{background:w.color}}/><span style={{flex:1}}>{w.name}</span>{workspaceId===w.id&&<Icon name="check" size={14}/>}</button>)}
      {canManageWorkspaces&&<button onClick={()=>{navigate('settings',null,'workspaces');setOpen(false);}} style={{borderTop:'1px solid #e9eaee',color:'#4a5af0'}}>{t("ws.manage")}<Icon name="arrowRight" size={12}/></button>}
    </div>,document.body)}
  </div>;
}

function WorkspaceSelect({ value, onChange, disabled = false }) {
  const { workspaceConfig } = useStore();
  return <select aria-label={t("ws.business")} style={inputStyle} value={value || ASM_WORKSPACES.DEFAULT_ID} onChange={e=>onChange(e.target.value)} disabled={disabled}>
    {workspaceConfig.workspaces.filter(w=>w.active || w.id===value).map(w=><option key={w.id} value={w.id}>{w.name}{w.deleted?t("ws.deletedSuffix"):!w.active?t("ws.pausedSuffix"):''}</option>)}
  </select>;
}

function CaseWorkspaceField({ caseData }) {
  const { can, moveCaseWorkspace, workspaceConfig } = useStore();
  const [busy,setBusy]=React.useState(false),[error,setError]=React.useState(''),[editing,setEditing]=React.useState(false);
  const [selected,setSelected]=React.useState(ASM_WORKSPACES.idsOf(caseData));
  React.useEffect(()=>{setSelected(ASM_WORKSPACES.idsOf(caseData));},[caseData]);
  const save=async()=>{setBusy(true);setError('');try{await moveCaseWorkspace(caseData.id,selected);setEditing(false);}catch(e){setError(e.message);}finally{setBusy(false);}};
  return <div style={{marginBottom:16}}><div className="asm-muted" style={{marginBottom:6}}>{t("ws.label")}</div><div style={{display:'flex',gap:6,flexWrap:'wrap',alignItems:'center'}}>{ASM_WORKSPACES.idsOf(caseData).map(id=><WorkspaceBadge key={id} id={id}/>)}{can('workspaceTriage')&&<Button size="sm" onClick={()=>setEditing(true)}>{t("cd.change")}</Button>}</div>
    {editing&&<Modal open title={t("ws.moveCase")} onClose={busy?()=>{}:()=>setEditing(false)} width={500} footer={<><Button disabled={busy} onClick={()=>setEditing(false)}>{t("btn.cancel")}</Button><Button variant="primary" disabled={busy||!selected.length} onClick={save}>{t("btn.save")}</Button></>}><p className="asm-muted">{t("ws.sharedHint")}</p>{workspaceConfig.workspaces.filter(w=>w.active).map(w=><label key={w.id} className="asm-workspace-option"><input type="checkbox" checked={selected.includes(w.id)} onChange={e=>setSelected(v=>e.target.checked?[...v,w.id]:v.filter(id=>id!==w.id))}/><WorkspaceBadge id={w.id}/></label>)}{error&&<div role="alert" className="asm-error">{localizeMessage(error)}</div>}</Modal>}
  </div>;
}

function WorkspaceEditor({ workspace, onClose, onDelete }) {
  const { workspaceConfig, saveWorkspaceConfig, currentUser, defaultWorkspaceId } = useStore();
  const [baseConfig] = React.useState(workspaceConfig);
  const [form,setForm] = React.useState(workspace || {id:'ws-'+crypto.randomUUID(),name:'',description:'',color:'#0f9d7a',threshold:85,memberIds:currentUser.role==='admin'?[]:[currentUser.id],active:true});
  const [draftRules,setDraftRules]=React.useState(()=>{
    const existing=baseConfig.rules.filter(r=>r.workspaceId===workspace?.id);
    return (existing.length?existing:[{id:'rule-'+crypto.randomUUID(),workspaceId:form.id,name:'',sources:['gmail'],keywords:[],domains:[],enabled:true,isNew:true}]).map(r=>({...r,keywordsText:r.keywords.join(', '),domainsText:r.domains.join(', ')}));
  });
  const [busy,setBusy]=React.useState(false),[error,setError]=React.useState('');
  const set=(key,v)=>setForm(f=>({...f,[key]:v}));
  const setRule=(index,patch)=>setDraftRules(rs=>rs.map((r,i)=>i===index?{...r,...patch}:r));
  const split=s=>s.split(/[\n,、]/).map(x=>x.trim()).filter(Boolean);
  const save=async()=>{setBusy(true);setError('');try{
    const rules=draftRules.filter(r=>!r.isNew||r.keywordsText.trim()||r.domainsText.trim()).map(({keywordsText,domainsText,isNew,...r})=>({...r,name:r.name||form.name+t("ws.ruleSuffix"),keywords:split(keywordsText),domains:split(domainsText)}));
    await saveWorkspaceConfig({...baseConfig,workspaces:workspace?baseConfig.workspaces.map(w=>w.id===form.id?form:w):[...baseConfig.workspaces,form],rules:[...baseConfig.rules.filter(r=>r.workspaceId!==form.id),...rules]});onClose();
  }catch(e){setError(e.message);}finally{setBusy(false);}};
  return <Modal open onClose={busy?()=>{}:onClose} className="asm-workspace-modal" title={<span className="asm-workspace-modal-title"><span className="asm-chip-dot" style={{background:form.color}}/>{workspace?t("ws.edit"):t("ws.add")}</span>} width={580} footer={<><div style={{marginRight:'auto'}}>{workspace&&workspace.id!==ASM_WORKSPACES.DEFAULT_ID&&onDelete&&<button className="asm-workspace-delete-link" disabled={busy} onClick={()=>onDelete(workspace)}>{t("ws.deleteThis")}</button>}</div><Button disabled={busy} onClick={onClose}>{t("btn.cancel")}</Button><Button variant="primary" disabled={busy||!form.name.trim()} onClick={save}>{busy?t("common.savingMore"):workspace?t("common.saveMore"):t("ws.create")}</Button></>}>
    <div className="asm-workspace-editor">
      {error&&<div role="alert" className="asm-error">{localizeMessage(error)}</div>}
      <div className="asm-workspace-name-color"><Field label={t("ws.name")} required><TextInput aria-label={t("ws.name")} maxLength={80} value={form.name} onChange={e=>set('name',e.target.value)} placeholder={t("ws.nameExample")}/></Field><Field label={t("ws.color")}><div className="asm-color-options">{['#4a5af0','#0ea5c6','#0f9d7a','#d97706','#c2410c','#7c3aed'].map(color=><button key={color} aria-label={(""+t("ws.color")+" ")+color} aria-pressed={form.color===color} style={{background:color,'--workspace-color':color}} onClick={()=>set('color',color)}/>)}<input title={t("ws.customColor")} aria-label={t("ws.customColor")} type="color" value={form.color} onChange={e=>set('color',e.target.value)}/></div></Field></div>
      {draftRules.map((r,index)=><div className="asm-workspace-rule-fields" key={r.id}>
        {draftRules.length>1&&<strong className="asm-workspace-rule-title">{r.name}</strong>}
        <Field label={t("ws.source")}><div className="asm-choice-chips">{[['readycrew','ReadyCrew'],['gmail','Gmail'],['fireflies','Fireflies'],['hnavi','発注ナビ'],['manual',t("ws.manual")]].map(([key,label])=>{
          const fixed=!ASM_WORKSPACES.RULE_SOURCES.includes(key), selected=fixed?(key==='manual'||form.id===ASM_WORKSPACES.DEFAULT_ID):r.sources.includes(key);
          return <button key={key} aria-label={label+(draftRules.length>1?' '+(index+1):'')} aria-pressed={selected} disabled={fixed} style={{'--workspace-color':form.color}} title={fixed?t("ws.fixedSourceHint"):label} onClick={()=>setRule(index,{sources:r.sources.includes(key)?r.sources.filter(s=>s!==key):[...r.sources,key]})}>{label}</button>;
        })}</div><p className="asm-field-hint">{t("ws.sourceHint")}</p></Field>
        <Field label={t("ws.keywordsComma")}><TextInput aria-label={t("ws.keywords")+(draftRules.length>1?' '+(index+1):'')} value={r.keywordsText} onChange={e=>setRule(index,{keywordsText:e.target.value})} placeholder={t("ws.keywordExample")}/></Field>
        <div className="asm-workspace-domain-threshold"><Field label={t("ws.senderDomain")}><TextInput aria-label={t("ws.senderDomain")+(draftRules.length>1?' '+(index+1):'')} value={r.domainsText} onChange={e=>setRule(index,{domainsText:e.target.value})} placeholder="*.tw, *.kr, partner.example.com"/></Field>{index===0&&<Field label={t("ws.threshold")}><div className="asm-threshold-input"><TextInput aria-label={t("ws.threshold")} type="number" min={50} max={100} value={form.threshold} onChange={e=>set('threshold',Number(e.target.value))}/><span>%</span></div></Field>}</div>
        <label className="asm-muted"><input type="checkbox" aria-label={t("ws.enableRuleLabel")+(draftRules.length>1?' '+(index+1):'')} checked={r.enabled} onChange={e=>setRule(index,{enabled:e.target.checked})}/>{t("ws.enableRule")}</label>
        <p className="asm-field-hint">{r.isNew?t("ws.newRuleHint"):t("ws.anySourceHint")}{t("ws.matchHint")}</p>
      </div>)}
      <Field label={t("ws.team")} hint={t("ws.memberHint")}><div className="asm-choice-chips">{APP_DATA.users.map(u=><button key={u.id} aria-pressed={form.memberIds.includes(u.id)} onClick={()=>set('memberIds',form.memberIds.includes(u.id)?form.memberIds.filter(id=>id!==u.id):[...form.memberIds,u.id])} style={{'--workspace-color':form.color}}><Avatar user={u} size={18}/>{u.name}</button>)}</div></Field>
      <details className="asm-workspace-extra"><summary>{t("ws.extraSettings")}</summary><Field label={t("ws.description")} hint={t("ws.descriptionHint")}><textarea aria-label={t("ws.description")} rows={3} style={inputStyle} maxLength={1000} value={form.description} onChange={e=>set('description',e.target.value)}/></Field>{form.id!==ASM_WORKSPACES.DEFAULT_ID&&<label className="asm-muted"><input type="checkbox" checked={form.active} onChange={e=>set('active',e.target.checked)}/>{t("ws.activeHint")}</label>}</details>
    </div>
  </Modal>;
}

function WorkspaceRuleEditor({ rule, onClose }) {
  const { workspaceConfig, saveWorkspaceConfig, currentUser, defaultWorkspaceId } = useStore();
  const [baseConfig] = React.useState(workspaceConfig);
  const [form,setForm]=React.useState(rule||{id:'rule-'+crypto.randomUUID(),name:'',workspaceId:defaultWorkspaceId,sources:['gmail','fireflies'],keywords:[],domains:[],enabled:true});
  const [keywords,setKeywords]=React.useState(form.keywords.join('\n')),[domains,setDomains]=React.useState(form.domains.join('\n'));
  const [busy,setBusy]=React.useState(false),[error,setError]=React.useState('');
  const split=s=>s.split(/[\n,、]/).map(x=>x.trim()).filter(Boolean);
  const save=async()=>{setBusy(true);setError('');try{const r={...form,keywords:split(keywords),domains:split(domains)};await saveWorkspaceConfig({...baseConfig,rules:rule?baseConfig.rules.map(x=>x.id===r.id?r:x):[...baseConfig.rules,r]});onClose();}catch(e){setError(e.message);}finally{setBusy(false);}};
  return <Modal open onClose={busy?()=>{}:onClose} title={rule?t("ws.editRule"):t("ws.addRule")} width={660} footer={<><Button disabled={busy} onClick={onClose}>{t("btn.cancel")}</Button><Button variant="primary" disabled={busy||!form.name.trim()} onClick={save}>{busy?t("common.savingMore"):t("btn.save")}</Button></>}>
    {error&&<div role="alert" className="asm-error">{localizeMessage(error)}</div>}
    <Field label={t("ws.ruleName")} required><TextInput aria-label={t("ws.ruleName")} value={form.name} maxLength={100} onChange={e=>setForm({...form,name:e.target.value})}/></Field>
    <Field label={t("ws.destination")}><WorkspaceSelect value={form.workspaceId} onChange={workspaceId=>setForm({...form,workspaceId})}/></Field>
    <Field label={t("ws.source")}><div style={{display:'flex',flexWrap:'wrap',gap:12}}>{ASM_WORKSPACES.RULE_SOURCES.map(s=><label key={s} style={{fontSize:12}}><input type="checkbox" checked={form.sources.includes(s)} onChange={e=>setForm({...form,sources:e.target.checked?[...form.sources,s]:form.sources.filter(x=>x!==s)})}/>{s}</label>)}</div></Field>
    <div className="asm-form-grid"><Field label={t("ws.keywords")} hint={t("ws.keywordLinesHint")}><textarea aria-label={t("ws.keywordLabel")} rows={5} style={inputStyle} value={keywords} onChange={e=>setKeywords(e.target.value)}/></Field><Field label={t("ws.senderDomain")} hint={t("ws.domainHint")}><textarea aria-label={t("ws.senderDomain")} rows={5} style={inputStyle} value={domains} onChange={e=>setDomains(e.target.value)}/></Field></div>
    <p className="asm-muted">{t("ws.conflictHint")}</p>
    <label className="asm-muted"><input type="checkbox" checked={form.enabled} onChange={e=>setForm({...form,enabled:e.target.checked})}/>{t("ws.enableRule")}</label>
  </Modal>;
}

function WorkspaceRulePreview() {
  const { previewWorkspace }=useStore();
  const [form,setForm]=React.useState({source:'gmail',title:'',body:'',from:''});
  const [result,setResult]=React.useState(null),[busy,setBusy]=React.useState(false),[error,setError]=React.useState('');
  const run=async()=>{setBusy(true);setError('');try{setResult(await previewWorkspace(form));}catch(e){setError(e.message);}finally{setBusy(false);}};
  return <Card title={t("ws.preview")} action={<span className="asm-muted">{t("ws.previewHint")}</span>}>
    <div className="asm-form-grid"><Field label={t("ws.source")}><select aria-label={t("ws.previewSource")} style={inputStyle} value={form.source} onChange={e=>setForm({...form,source:e.target.value})}>{ASM_WORKSPACES.RULE_SOURCES.map(s=><option key={s}>{s}</option>)}</select></Field><Field label={t("ws.sender")}><TextInput aria-label={t("ws.previewSender")} value={form.from} onChange={e=>setForm({...form,from:e.target.value})} placeholder="name@example.com"/></Field></div>
    <Field label={t("cd.mail.subject")}><TextInput aria-label={t("ws.previewSubject")} value={form.title} onChange={e=>setForm({...form,title:e.target.value})}/></Field>
    <Field label={t("cd.mail.body")}><textarea aria-label={t("ws.previewBody")} rows={3} style={inputStyle} value={form.body} onChange={e=>setForm({...form,body:e.target.value})}/></Field>
    {error&&<div role="alert" className="asm-error">{localizeMessage(error)}</div>}
    <Button variant="primary" disabled={busy||(!form.title.trim()&&!form.body.trim())} onClick={run}>{busy?t("ws.evaluating"):t("ws.test")}</Button>
    {result&&<div role="status" style={{marginTop:16,padding:14,background:'#f6f7fa',borderRadius:10}}><strong style={{fontSize:13}}>{result.status==='assigned'?t("ws.assignable"):t("ws.needsReview")}</strong>{result.workspaceId&&<span style={{marginLeft:10}}><WorkspaceBadge id={result.workspaceId}/></span>}<p className="asm-muted">{localizeMessage(result.reason)}</p>{typeof result.confidence==='number'&&result.method==='ai'&&<p className="asm-muted">{t("ws.confidence")}{Math.round(result.confidence*100)}%</p>}</div>}
  </Card>;
}

function WorkspaceSettings() {
  const { workspaceConfig, saveWorkspaceConfig, allCases, isAdmin, can }=useStore();
  const [edit,setEdit]=React.useState(null),[rule,setRule]=React.useState(null),[busy,setBusy]=React.useState(false),[error,setError]=React.useState(''),[deleting,setDeleting]=React.useState(null),[showDeleted,setShowDeleted]=React.useState(false);
  const save=async cfg=>{if(busy)return false;setBusy(true);setError('');try{await saveWorkspaceConfig(cfg);return true;}catch(e){setError(e.message);return false;}finally{setBusy(false);}};
  const remove=async()=>{if(await save({...workspaceConfig,workspaces:workspaceConfig.workspaces.map(w=>w.id===deleting.id?{...w,deleted:true,active:false}:w),rules:workspaceConfig.rules.map(r=>r.workspaceId===deleting.id?{...r,enabled:false}:r)}))setDeleting(null);};
  const visible=workspaceConfig.workspaces.filter(w=>!!w.deleted===showDeleted);
  return <div>
    <div className="asm-workspaces-heading"><div><h2>{t("ws.heading")}</h2><p className="asm-muted">{t("ws.headingHint")}</p></div><Button icon="plus" variant="primary" disabled={!can("workspaceCreate")||busy} onClick={()=>setEdit({})}>{t("ws.add")}</Button></div>
    {!isAdmin&&<p className="asm-muted">{t("ws.visibleHint")}</p>}
    {error&&!deleting&&<div role="alert" className="asm-error">{localizeMessage(error)}</div>}
    <div className="asm-workspaces-tabs"><button aria-pressed={!showDeleted} onClick={()=>setShowDeleted(false)}>{t("ws.list")}</button><button aria-pressed={showDeleted} onClick={()=>setShowDeleted(true)}>{t('ws.deletedCount',{n:workspaceConfig.workspaces.filter(w=>w.deleted).length})}</button></div>
    <div className="asm-workspace-list">{!visible.length&&<p className="asm-muted" style={{padding:18}}>{showDeleted?t("ws.deletedEmpty"):t("ws.visibleEmpty")}</p>}{visible.map(w=>{
      const rules=workspaceConfig.rules.filter(r=>r.workspaceId===w.id&&r.enabled), unique=key=>[...new Set(rules.flatMap(r=>r[key]))];
      const members=w.memberIds.map(id=>APP_DATA.user(id)).filter(Boolean), remaining=members.slice(4);
      return <section key={w.id} className="asm-workspace-row" style={{'--workspace-color':w.color}}>
        <div className="asm-workspace-summary">
          <h3>{w.name} {!w.active&&<span className="asm-muted">{w.deleted?t("ws.deleted"):t("ws.paused")}</span>}</h3>
          <p className="asm-muted">{w.description||t("ws.noDescription")}</p>
          <div className="asm-workspace-members">
            {!!members.length&&<div className="asm-workspace-member-avatars"><AvatarGroup users={members.slice(0,4)} size={23}/>{!!remaining.length&&<span className="asm-workspace-member-more" title={remaining.map(u=>u.name).join('、')} aria-label={t('ws.moreMembers',{n:remaining.length})}>+{remaining.length}</span>}</div>}
            <span className="asm-muted asm-workspace-member-count">{w.memberIds.length?t('ws.teamCount',{n:w.memberIds.length}):t("ws.noTeam")}</span>
          </div>
        </div>
        <div className="asm-workspace-conditions">{[[t("ws.source"),unique('sources')],[t("ws.keywordLabel"),unique('keywords')],[t("ws.senderDomain"),unique('domains')]].map(([label,items])=><div key={label}><small>{label}</small><div className="asm-rule-tags">{items.length?items.map(v=><span key={v}>{v}</span>):<span className="asm-muted">{t("ws.unspecified")}</span>}</div></div>)}</div>
        <div className="asm-workspace-controls"><span className="asm-muted">{t("ws.threshold")}<strong style={{color:w.color}}>{w.threshold}%</strong><br/>{t("an.col.cases")}{allCases.filter(c=>ASM_WORKSPACES.contains(c,w.id)).length}{t("unit.count")}</span>{w.id===ASM_WORKSPACES.DEFAULT_ID&&<small className="asm-muted">{t("ws.defaultProtected")}</small>}{w.deleted&&<small className="asm-muted">{t("ws.restoreHint")}</small>}</div><div className="asm-workspace-row-actions">{w.deleted?<Button size="sm" disabled={busy||!can("workspaceDelete")} onClick={()=>save({...workspaceConfig,workspaces:workspaceConfig.workspaces.map(x=>x.id===w.id?{...x,deleted:false,active:true}:x)})}>{t("ws.restore")}</Button>:<><button className="asm-workspace-icon" aria-label={t('ws.editName',{name:w.name})} title={t("btn.edit")} disabled={!can("workspaceEdit")||busy} onClick={()=>setEdit(w)}><Icon name="edit" size={15}/></button><button className="asm-workspace-icon asm-workspace-remove" aria-label={t('ws.deleteName',{name:w.name})} title={t("btn.delete")} disabled={!can("workspaceDelete")||busy||w.id===ASM_WORKSPACES.DEFAULT_ID} onClick={()=>{setError('');setDeleting(w);}}><Icon name="trash" size={15}/></button></>}</div>
      </section>;
    })}</div>
    <p className="asm-muted" style={{margin:'12px 0 20px'}}>{t("ws.deletedCasesHint")}</p>
    <Card title={t("ws.rules")} pad={0} action={<Button size="sm" icon="plus" disabled={!can("workspaceEdit")||busy} onClick={()=>setRule({})}>{t("ws.addRule")}</Button>}>
      {!workspaceConfig.rules.length&&<p className="asm-muted" style={{padding:18}}>{t("ws.rulesEmpty")}</p>}
      {workspaceConfig.rules.filter(r=>!workspaceConfig.workspaces.find(w=>w.id===r.workspaceId)?.deleted).map(r=><div className="asm-rule-row" key={r.id}><div style={{flex:1,minWidth:180}}><strong style={{fontSize:13}}>{r.name}</strong><p className="asm-muted">{r.sources.join('・')} / {r.keywords.join('、')||t("ws.noKeywords")} / {r.domains.join('、')||t("ws.noDomains")}</p></div><WorkspaceBadge id={r.workspaceId}/><label className="asm-muted"><input aria-label={r.name+(" "+t("ws.enabled")+"")} type="checkbox" disabled={busy||!can("workspaceEdit")} checked={r.enabled} onChange={e=>save({...workspaceConfig,rules:workspaceConfig.rules.map(x=>x.id===r.id?{...x,enabled:e.target.checked}:x)})}/>{t("ws.enabled")}</label><Button size="sm" disabled={!can("workspaceEdit")||busy} onClick={()=>setRule(r)}>{t("btn.edit")}</Button><Button size="sm" variant="danger" disabled={busy||!can("workspaceEdit")} onClick={()=>{if(confirm(t('ws.deleteRuleConfirm',{name:r.name})))save({...workspaceConfig,rules:workspaceConfig.rules.filter(x=>x.id!==r.id)});}}>{t("btn.delete")}</Button></div>)}
    </Card>
    <div style={{margin:'18px 0'}}><label style={{display:'flex',alignItems:'center',gap:8,fontSize:13,fontWeight:600}}><input type="checkbox" aria-label={t("ws.aiAssist")} checked={workspaceConfig.aiEnabled} disabled={busy||!isAdmin} onChange={e=>save({...workspaceConfig,aiEnabled:e.target.checked})}/>{t("ws.aiAssistHint")}</label><p className="asm-muted" style={{marginTop:6}}>{t("ws.aiBehavior")}</p></div>
    {can("workspaceEdit")&&<WorkspaceRulePreview/>}
    {edit&&<WorkspaceEditor workspace={edit.id?edit:null} onClose={()=>setEdit(null)} onDelete={can("workspaceDelete")?w=>{setEdit(null);setError('');setDeleting(w);}:undefined}/>}
    {rule&&<WorkspaceRuleEditor rule={rule.id?rule:null} onClose={()=>setRule(null)}/>}
    {deleting&&<Modal open title={t('ws.deleteName',{name:deleting.name})} width={510} onClose={busy?()=>{}:()=>setDeleting(null)} footer={<><Button disabled={busy} onClick={()=>setDeleting(null)}>{t("btn.cancel")}</Button><Button variant="danger" disabled={busy} onClick={remove}>{busy?t("ws.deleting"):t("ws.delete")}</Button></>}><p style={{fontSize:13,lineHeight:1.9}}>{t('ws.deleteHint',{n:allCases.filter(c=>ASM_WORKSPACES.contains(c,deleting.id)).length})}</p>{error&&<div className="asm-error" role="alert">{localizeMessage(error)}</div>}</Modal>}
  </div>;
}

function WorkspaceTriage() {
  const { workspaceInbox, workspaceConfig, refreshWorkspaceInbox, resolveWorkspaceItem, ignoreWorkspaceItem, createWorkspaceCase, can, navigate }=useStore();
  const [tab,setTab]=React.useState('pending'),[source,setSource]=React.useState('all'),[method,setMethod]=React.useState('all'),[busy,setBusy]=React.useState(''),[error,setError]=React.useState(''),[detail,setDetail]=React.useState(null),[limit,setLimit]=React.useState(50),[choose,setChoose]=React.useState(null),[selected,setSelected]=React.useState([]);
  const active=workspaceConfig.workspaces.filter(w=>w.active);
  const {counts,items}=ASM_WORKSPACES.triageView(workspaceInbox,{tab,source,method,day:new Date(Date.now()+9*3600000).toISOString().slice(0,10)});
  React.useEffect(()=>setLimit(50),[tab,source,method]);
  const run=async(id,fn)=>{if(busy)return;setBusy(id);setError('');try{await fn();}catch(e){setError(e.message);}finally{setBusy('');}};
  const assign=(item,ids)=>run(item.id,()=>resolveWorkspaceItem(item.id,ids));
  const renderRow=item=>{
    const suggestion=item.workspaceId||(item.method==='ai'?item.candidates?.[0]?.workspaceId:null), target=active.find(w=>w.id===suggestion);
    const ai=item.status!=='ignored'&&item.method==='ai'&&typeof item.confidence==='number', color=target?.color||'#b45309';
    return <div className="asm-triage-row" key={item.id}>
      <span className={'asm-source-badge '+item.source}>{item.source==='gmail'?'Gmail':'Fireflies'}</span>
      <div className="asm-triage-copy"><button title={item.title} onClick={()=>setDetail(item)}>{item.title}</button><div className="asm-triage-meta">{item.date?fmtDate(item.date)+' '+fmtTime(item.date):t("triage.noDate")} · {item.from||t("triage.noSender")}</div></div>
      <div className="asm-triage-decision" title={localizeMessage(item.reason)}><strong style={{color:item.status==='pending'?'#b45309':color}}>{ai?t("triage.aiPrefix")+(target?.name||t("triage.pending"))+' '+Math.round(item.confidence*100)+'%':item.status==='ignored'?t("triage.ignore"):item.status==='assigned'?t("triage.assignedPrefix")+ASM_WORKSPACES.idsOf(item).map(id=>workspaceConfig.workspaces.find(w=>w.id===id)?.name).join('・'):item.method==='conflict'?t("triage.conflictReview"):t("triage.selectRequired")}</strong>{ai?<div className="asm-confidence"><span style={{width:item.confidence*100+'%',background:color}}/><span style={{flex:1,background:'#e2e5ea'}}/></div>:<small>{item.status==='ignored'?t("triage.ignoredHint"):localizeMessage(item.reason)}</small>}</div>
      <div className="asm-triage-actions asm-triage-destinations">
        {item.status==='ignored'?<>{can('workspaceTriage')&&<button disabled={!!busy} onClick={()=>run(item.id,()=>ignoreWorkspaceItem(item.id,false))}>{t("triage.unignore")}</button>}</>:<>
          {item.status==='pending'&&can('workspaceTriage')?<>{active.map(w=><button className="asm-triage-destination" key={w.id} title={w.name} disabled={!!busy} style={{color:suggestion===w.id?'white':undefined,background:suggestion===w.id?w.color:undefined,borderColor:suggestion===w.id?w.color:undefined}} onClick={()=>assign(item,w.id)}>{w.name}</button>)}{active.length>=2&&<button className="asm-triage-both" disabled={!!busy} onClick={()=>{setSelected([]);setChoose(item);}}>{t("triage.multiple")}</button>}</>:item.status==='pending'?<span className="asm-muted">{t("triage.waitOwner")}</span>:item.caseId?<Button size="sm" onClick={()=>navigate('case',item.caseId)}>{t("triage.openCase")}</Button>:can('caseCreate')?<Button size="sm" disabled={!!busy} onClick={()=>run(item.id,async()=>{const c=await createWorkspaceCase(item.id);navigate('case',c.id);})}>{busy===item.id?t("triage.importingMeeting"):t("triage.createCase")}</Button>:null}
          {!item.caseId&&can('workspaceTriage')&&<button className="asm-triage-ignore" disabled={!!busy} title={t("triage.ignoreHint")} onClick={()=>run(item.id,()=>ignoreWorkspaceItem(item.id,true))}>{t("triage.ignore")}</button>}
        </>}
      </div>
    </div>;
  };
  return <Page title={t("triage.title")}>
    <section className="asm-triage-intro" aria-label={t("triage.about")}><span className="asm-triage-spark"><Icon name="spark" size={15}/></span><div className="asm-triage-explainer"><strong>{t(workspaceConfig.aiEnabled?'triage.introAi':'triage.introRules')}</strong><p>{t("triage.scopeHint")}{workspaceConfig.aiEnabled?t("triage.aiPendingHint"):t("triage.rulePendingHint")}</p></div><div className="asm-triage-intro-actions">{can('workspaceEdit')&&<Button onClick={()=>navigate('settings',null,'workspaces')}>{t("triage.editRules")}</Button>}{can('workspaceTriage')&&<Button variant="primary" icon="spark" disabled={!!busy} onClick={()=>run('refresh',()=>refreshWorkspaceInbox(true))}>{busy==='refresh'?t("triage.reevaluating"):workspaceConfig.aiEnabled?t("triage.reevaluateAi"):t("triage.reevaluateRules")}</Button>}</div></section>
    <div className="asm-triage-toolbar"><div className="asm-triage-tabs" role="tablist" aria-label={t("triage.status")}>{[['pending',t("triage.unassigned")],['today',t("triage.today")],['both',t("triage.shared")],['ignored',t("triage.ignore")],['all',t("cases.all")]].map(([id,label])=><button key={id} role="tab" aria-selected={tab===id} onClick={()=>setTab(id)}>{label}<span className="asm-count">{counts[id]}</span></button>)}</div><div className="asm-triage-filters"><label>{t("ws.source")}<select aria-label={t("triage.filterSource")} value={source} onChange={e=>setSource(e.target.value)}><option value="all">{t("cases.all")}</option><option value="gmail">Gmail</option><option value="fireflies">Fireflies</option></select></label><label>{t("triage.decision")}<select aria-label={t("triage.filterDecision")} value={method} onChange={e=>setMethod(e.target.value)}>{[['all',t("cases.all")],['ai',t("triage.ai")],['rule',t("triage.rule")],['manual',t("triage.manual")],['linked',t("triage.linked")],['conflict',t("triage.conflict")],['unmatched',t("triage.unmatched")],['ai-error',t("triage.aiError")]].map(([id,label])=><option key={id} value={id}>{label}</option>)}</select></label></div></div>
    {error&&!choose&&<div role="alert" className="asm-error">{localizeMessage(error)}</div>}
    {items.length?<section className="asm-triage-table" aria-label={t("triage.list")}><div className="asm-triage-columns"><span className="asm-triage-source-heading">{t("ws.source")}</span><span style={{flex:1}}>{t("triage.subjectBody")}</span><span className="asm-triage-decision">{t("triage.result")}</span><span className="asm-triage-actions">{t("ws.destination")}</span></div>{items.slice(0,limit).map(renderRow)}</section>:<section className="asm-triage-empty" role="status"><span><Icon name="check" size={18}/></span><strong>{tab==='pending'&&source==='all'&&method==='all'?t("triage.empty"):t("triage.noMatch")}</strong><p>{tab==='pending'?t("triage.emptyHint"):t("triage.noMatchHint")}</p></section>}
    {items.length>0&&<div className="asm-triage-pagination"><span>{t('triage.pagination',{total:items.length,n:Math.min(limit,items.length)})}</span>{items.length>limit&&<Button size="sm" onClick={()=>setLimit(n=>n+50)}>{t("triage.loadMore")}</Button>}</div>}
    {tab==='today'&&<p className="asm-muted">{t("triage.todayHint")}</p>}
    {choose&&<Modal open title={t("triage.selectDestination")} width={500} onClose={()=>setChoose(null)} footer={<Button variant="primary" disabled={!selected.length||!!busy} onClick={()=>run(choose.id,async()=>{await resolveWorkspaceItem(choose.id,selected);setChoose(null);})}>{t("triage.confirm")}</Button>}><p className="asm-muted">{t("triage.multipleHint")}</p>{active.map(w=><label key={w.id} className="asm-workspace-option"><input type="checkbox" checked={selected.includes(w.id)} onChange={e=>setSelected(v=>e.target.checked?[...v,w.id]:v.filter(id=>id!==w.id))}/><WorkspaceBadge id={w.id}/></label>)}{error&&<div role="alert" className="asm-error">{localizeMessage(error)}</div>}</Modal>}
    {detail&&<Modal open onClose={()=>setDetail(null)} title={detail.title} subtitle={detail.source+' · '+(detail.from||'')} width={700}><div style={{whiteSpace:'pre-wrap',fontSize:13,lineHeight:1.85,maxHeight:'55vh',overflowY:'auto'}}>{detail.body||detail.summary||t("triage.noBody")}</div></Modal>}
  </Page>;
}

// Explicit Fireflies-created cases know their source ID; do not guess by company name.
function WorkspaceFirefliesImport({caseData}) {
  const {importWorkspaceMeeting,can}=useStore();
  const [busy,setBusy]=React.useState(false),[error,setError]=React.useState('');
  const attempted=React.useRef(null);
  const sourceId=caseData.source==='fireflies'&&String(caseData.sourceNo||'').startsWith('FF-')?caseData.sourceNo.slice(3):null;
  const doc=sourceId&&(caseData.meetingDocs||[]).find(d=>d.ffId===sourceId);
  const allowed=can('caseEdit');
  const run=async()=>{setBusy(true);setError('');try{await importWorkspaceMeeting(caseData.id);}catch(e){setError(e.message);}finally{setBusy(false);}};
  React.useEffect(()=>{if(attempted.current===caseData.id)return;attempted.current=caseData.id;if(sourceId&&!doc&&allowed)run();},[caseData.id,sourceId,!!doc,allowed]);
  if(!sourceId||(doc&&doc.importStatus!=='partial'&&!error))return null;
  return <div className="asm-meeting-import" role="status"><Icon name="spark" size={17}/><span>{busy?t("ws.importing"):localizeMessage(error||doc?.importError)||t("ws.importHint")}</span>{allowed&&!busy&&<Button size="sm" onClick={run}>{doc?t("ws.reimport"):t("ws.import")}</Button>}</div>;
}

function WorkspaceNoMembership(){const {canManageWorkspaces,navigate}=useStore();return <Page title={t("ws.workspace")}><section className="asm-triage-empty"><strong>{t("ws.noMembership")}</strong><p>{t("ws.noMembershipHint")}</p>{canManageWorkspaces&&<Button onClick={()=>navigate('settings',null,'workspaces')}>{t("ws.management")}</Button>}</section></Page>;}

Object.assign(window,{WorkspaceNoMembership,WorkspaceBadge,WorkspacePicker,WorkspaceSelect,CaseWorkspaceField,WorkspaceEditor,WorkspaceRuleEditor,WorkspaceRulePreview,WorkspaceSettings,WorkspaceTriage,WorkspaceFirefliesImport});
