/* ============================================================
   NeuroRoute — Customer: Org Routing Rules

   The org-level half of the task routing rules table. Precedence, enforced
   by the router (GetPin, org row before the global row):

     your org's rule  >  platform default (SISL-set)  >  strategy scoring

   So each task row here is in one of three states: "your rule" (this org
   overrides), "platform default" (inherited from SISL — what applies when
   the org hasn't defined its own), or "auto" (no rule anywhere; score-based
   routing). Removing an org rule reverts that task to the platform default.

   Mutations require org_admin + the custom_routing_rules entitlement
   (Standard+); a 403's real message (feature not in plan + required tier)
   is surfaced, not swallowed. Reuses admin.jsx's CascadeBuilder /
   ROUTING_TASK_TYPES / _suggestChain globals — this file loads after it.
   ============================================================ */

function OrgRoutingRulesPage(){
  var t=useToast();
  var _loading=useState(true); var loading=_loading[0], setLoading=_loading[1];
  /* own: task_type -> chain[] (this org's rules); platform: task_type -> chain[] */
  var _own=useState({}); var own=_own[0], setOwn=_own[1];
  var _platform=useState({}); var platform=_platform[0], setPlatform=_platform[1];
  var _models=useState([]); var models=_models[0], setModels=_models[1];
  /* editing: task_type -> chain[] draft while that row's editor is open */
  var _editing=useState({}); var editing=_editing[0], setEditing=_editing[1];
  var _saving=useState({}); var saving=_saving[0], setSaving=_saving[1];
  var _loadFailed=useState(false); var loadFailed=_loadFailed[0], setLoadFailed=_loadFailed[1];

  var toChain=function(r){
    return (r.cascade_models&&r.cascade_models.length>0) ? r.cascade_models
         : (r.model_id ? [r.model_id] : []);
  };

  var load=function(){
    setLoading(true); setLoadFailed(false);
    Promise.all([NR_API.customerRoutingRules(), NR_API.models()]).then(function(res){
      if(res[0]===null){ setLoadFailed(true); setLoading(false); return; }
      var ownMap={}, platMap={};
      ((res[0]&&res[0].rules)||[]).forEach(function(r){ ownMap[r.task_type]=toChain(r); });
      ((res[0]&&res[0].platform_defaults)||[]).forEach(function(r){ platMap[r.task_type]=toChain(r); });
      setOwn(ownMap); setPlatform(platMap);
      var m=res[1]; var list=(m&&(m.data||m.models||m))||[];
      if(!Array.isArray(list)) list=[];
      setModels(list.filter(function(x){return (x.id||x)!=='auto';})
                    .map(function(x){var id=x.id||x; return {id:id, name:(DATA.modelById(id).name)||id};}));
      setLoading(false);
    }).catch(function(){ setLoadFailed(true); setLoading(false); });
  };
  useEffect(load,[]);

  var save=function(task, chain){
    setSaving(function(s){return Object.assign({},s,{[task]:true});});
    NR_API.setCustomerRoutingRule(task,'',chain).then(function(res){
      setSaving(function(s){var n=Object.assign({},s); delete n[task]; return n;});
      if(res&&res.ok){
        t({title:chain.length>0?'Rule saved':'Reverted to platform default',
           msg:chain.length>0?(task+' → '+chain.join(' → ')):task});
        setEditing(function(e){var n=Object.assign({},e); delete n[task]; return n;});
        load();
      } else {
        /* 403 carries {"error":"feature not in plan","feature","required_tier"} —
           show the real reason (usually: upgrade needed), not a generic failure. */
        var msg=(res&&res.data&&res.data.error)||'';
        if(res&&res.status===403&&res.data&&res.data.required_tier){
          msg='Custom routing rules require the '+res.data.required_tier+' plan or higher.';
        }
        t({kind:'error',title:'Failed to save rule',msg:msg});
      }
    }).catch(function(){
      setSaving(function(s){var n=Object.assign({},s); delete n[task]; return n;});
      t({kind:'error',title:'Failed to save rule'});
    });
  };

  if(loading) return <LoadingPage/>;

  var overrideCount=Object.keys(own).length;

  return (
    <div className="grid" style={{gap:18}}>
      <PageHead desc="Pin tasks to your own models or cascade chains. Your rule supersedes the platform default for that task; removing it reverts to the platform default (or automatic score-based routing when none exists)."/>

      <div className="card card-pad" style={{background:'var(--blue-t)',borderColor:'rgba(59,130,246,.3)'}}>
        <div className="row" style={{gap:10}}>
          <Icon name="filter" size={17} style={{color:'var(--blue)'}}/>
          <span><b>{overrideCount} of {ROUTING_TASK_TYPES.length} tasks overridden by your organization.</b> Tasks without your own rule follow the platform default. Rules apply to every request from your org, across all routing strategies.</span>
        </div>
      </div>

      {loadFailed ? <EvalLoadError what="routing rules" onRetry={load}/> :
      <SectionCard title="Task routing" sub="Your rule > platform default > automatic (score-based)." pad={false}>
        <div>
          {ROUTING_TASK_TYPES.map(function(tt){
            var mine=own[tt.v]||[];
            var plat=platform[tt.v]||[];
            var draft=editing[tt.v]; /* undefined = editor closed */
            var isSaving=!!saving[tt.v];
            return (
              <div key={tt.v} style={{borderBottom:'1px solid var(--line)',padding:'8px 14px'}}>
                <div className="row" style={{gap:10,alignItems:'center'}}>
                  <div style={{minWidth:170,fontSize:12.5,fontWeight:600,color:'var(--tx-0)'}} title={tt.v}>{tt.label}</div>
                  {/* Effective state */}
                  {mine.length>0 && <Badge color="blue">your rule</Badge>}
                  {mine.length===0 && plat.length>0 && <Badge color="gray">platform default</Badge>}
                  {mine.length===0 && plat.length===0 && <span className="faint" style={{fontSize:11.5}}>auto</span>}
                  {/* The effective chain, whoever owns it */}
                  {(mine.length>0||plat.length>0) &&
                    <span className="mono faint" style={{fontSize:11,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',minWidth:0}}
                      title={(mine.length>0?mine:plat).join(' → ')}>
                      {(mine.length>0?mine:plat).join(' → ')}
                    </span>}
                  <div style={{flex:1}}/>
                  {draft===undefined && <button className="btn btn-xs btn-outline"
                    onClick={function(){setEditing(function(e){return Object.assign({},e,{[tt.v]:mine.slice()});});}}>
                    {mine.length>0?'Edit':'Override'}
                  </button>}
                  {mine.length>0 && draft===undefined && <button className="btn btn-xs btn-ghost" disabled={isSaving}
                    title="Remove your rule — this task reverts to the platform default"
                    onClick={function(){save(tt.v,[]);}}>
                    {isSaving?'…':'Use platform default'}
                  </button>}
                </div>
                {draft!==undefined && (
                  <div style={{marginTop:8}}>
                    <CascadeBuilder
                      chain={draft}
                      models={models}
                      onChange={function(chain){setEditing(function(e){return Object.assign({},e,{[tt.v]:chain});});}}
                      onSuggest={function(strategy){
                        var chain=_suggestChain(strategy,models);
                        if(chain.length>0) setEditing(function(e){return Object.assign({},e,{[tt.v]:chain});});
                        else t({kind:'error',title:'No models available for this strategy'});
                      }}
                    />
                    <div className="row" style={{gap:6,marginTop:8}}>
                      <button className="btn btn-xs btn-primary" disabled={isSaving||draft.length===0}
                        onClick={function(){save(tt.v,draft);}}>
                        {isSaving?'Saving…':'Apply'}
                      </button>
                      <button className="btn btn-xs btn-ghost"
                        onClick={function(){setEditing(function(e){var n=Object.assign({},e); delete n[tt.v]; return n;});}}>Cancel</button>
                    </div>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </SectionCard>}
    </div>
  );
}

window.PAGES = Object.assign(window.PAGES||{}, {orgrouting: OrgRoutingRulesPage});
