qBitrr2 5.6.2__py3-none-any.whl → 5.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qBitrr/arss.py +237 -88
- qBitrr/bundled_data.py +2 -2
- qBitrr/main.py +232 -10
- qBitrr/static/assets/ArrView.js +1 -1
- qBitrr/static/assets/ArrView.js.map +1 -1
- qBitrr/static/assets/ConfigView.js +5 -4
- qBitrr/static/assets/ConfigView.js.map +1 -1
- qBitrr/static/assets/LogsView.js +1 -1
- qBitrr/static/assets/LogsView.js.map +1 -1
- qBitrr/static/assets/ProcessesView.js +1 -1
- qBitrr/static/assets/ProcessesView.js.map +1 -1
- qBitrr/static/assets/app.js +2 -2
- qBitrr/static/assets/app.js.map +1 -1
- qBitrr/static/assets/vendor.js +1 -1
- qBitrr/static/assets/vendor.js.map +1 -1
- qBitrr/tables.py +7 -0
- qBitrr/webui.py +48 -1
- {qbitrr2-5.6.2.dist-info → qbitrr2-5.7.0.dist-info}/METADATA +24 -2
- {qbitrr2-5.6.2.dist-info → qbitrr2-5.7.0.dist-info}/RECORD +23 -23
- {qbitrr2-5.6.2.dist-info → qbitrr2-5.7.0.dist-info}/WHEEL +0 -0
- {qbitrr2-5.6.2.dist-info → qbitrr2-5.7.0.dist-info}/entry_points.txt +0 -0
- {qbitrr2-5.6.2.dist-info → qbitrr2-5.7.0.dist-info}/licenses/LICENSE +0 -0
- {qbitrr2-5.6.2.dist-info → qbitrr2-5.7.0.dist-info}/top_level.txt +0 -0
qBitrr/static/assets/ArrView.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as e,u as is,h as rs,i as os,k as cs,l as Je,m as ds,I as qe,R as Ue,n as Xe,o as es}from"./app.js";import{r as a,u as ze,g as Te,f as Pe,a as gs,b as vs,c as ys}from"./table.js";import{u as Ke}from"./useInterval.js";import"./vendor.js";function Ss({data:r,columns:t,getRowKey:u}){const h=ze({data:r,columns:t,getCoreRowModel:Te()});return e.jsx("div",{className:"table-wrapper",children:e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:h.getHeaderGroups().map(y=>e.jsx("tr",{children:y.headers.map(v=>e.jsx("th",{children:v.isPlaceholder?null:Pe(v.column.columnDef.header,v.getContext())},v.id))},y.id))}),e.jsx("tbody",{children:h.getRowModel().rows.map(y=>{const v=u?u(y.original):y.id;return e.jsx("tr",{children:y.getVisibleCells().map(F=>e.jsx("td",{"data-label":String(F.column.columnDef.header),children:Pe(F.column.columnDef.cell,F.getContext())},F.id))},v)})})]})})}const Rs=a.memo(Ss,(r,t)=>r.data===t.data&&r.columns===t.columns);function Cs(r){let t=2166136261;for(let u=0;u<r.length;u++)t^=r.charCodeAt(u),t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24);return(t>>>0).toString(36)}function ls(r,t){const u=t.map(h=>{const y=r[h];return y==null?"":typeof y=="boolean"?y?"1":"0":typeof y=="object"?JSON.stringify(y):String(y)});return Cs(u.join("|"))}function ws(r,t,u,h){const y=[],v=[],F=[],N=new Set;for(const n of t){const M=u(n),b=ls(n,h);N.add(M);const B=r.byId.get(M),K=r.byHash.get(M);B?K!==b&&v.push(n):y.push(n)}for(const n of r.allIds)N.has(n)||F.push(n);const m=t.length-y.length-v.length,T=y.length>0||v.length>0||F.length>0;return{added:y,updated:v,removed:F,unchanged:m,hasChanges:T}}function Fs(r,t,u,h){if(!t.hasChanges)return r;const y=new Map(r.byId),v=new Map(r.byHash),F=[...r.allIds];for(const N of t.added){const m=u(N),T=ls(N,h);y.set(m,N),v.set(m,T),F.push(m)}for(const N of t.updated){const m=u(N),T=ls(N,h);y.set(m,N),v.set(m,T)}for(const N of t.removed){y.delete(N),v.delete(N);const m=F.indexOf(N);m!==-1&&F.splice(m,1)}return{byId:y,byHash:v,allIds:F,lastUpdate:Date.now()}}function ss(r){return r.allIds.map(t=>r.byId.get(t)).filter(Boolean)}function ms(){return{byId:new Map,byHash:new Map,allIds:[],lastUpdate:0}}function _e(r){const{getKey:t,hashFields:u}=r,h=a.useRef(ms()),[y,v]=a.useState(0),F=a.useCallback(T=>{const n=ws(h.current,T,t,u);if(!n.hasChanges)return{data:ss(h.current),hasChanges:!1,changes:null,lastUpdate:h.current.lastUpdate};const M=Fs(h.current,n,t,u);return h.current=M,v(M.lastUpdate),{data:ss(M),hasChanges:!0,changes:n,lastUpdate:M.lastUpdate}},[t,u]),N=a.useCallback(()=>ss(h.current),[]),m=a.useCallback(()=>{h.current=ms(),v(0)},[]);return{syncData:F,getData:N,reset:m,lastUpdate:y}}const as=50,Be=50,fs=500,Ms=a.memo(function({loading:t,rows:u,total:h,page:y,totalPages:v,onPageChange:F,onRefresh:N,lastUpdated:m,sort:T,onSort:n,summary:M,instanceCount:b,isAggFiltered:B=!1}){const K=a.useMemo(()=>[...b>1?[{accessorKey:"__instance",header:"Instance",size:150}]:[],{accessorKey:"title",header:"Title",cell:A=>A.getValue()},{accessorKey:"year",header:"Year",size:80},{accessorKey:"monitored",header:"Monitored",cell:A=>{const L=A.getValue();return e.jsx("span",{className:`track-status ${L?"available":"missing"}`,children:L?"✓":"✗"})},size:100},{accessorKey:"hasFile",header:"Has File",cell:A=>{const L=A.getValue();return e.jsx("span",{className:`track-status ${L?"available":"missing"}`,children:L?"✓":"✗"})},size:100},{accessorKey:"qualityProfileName",header:"Quality Profile",cell:A=>A.getValue()||"—",size:150},{accessorKey:"reason",header:"Reason",cell:A=>{const L=A.getValue();return L?e.jsx("span",{className:"table-badge table-badge-reason",children:L}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})},size:120}],[b]);return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:["Aggregated movies across all instances"," ",m?`(updated ${m})`:"",e.jsx("br",{}),e.jsx("strong",{children:"Available:"})," ",M.available.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",M.monitored.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",M.missing.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total:"})," ",M.total.toLocaleString(void 0,{maximumFractionDigits:0}),B&&h<M.total&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",h.toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",M.total.toLocaleString(void 0,{maximumFractionDigits:0})]})]}),e.jsxs("button",{className:"btn ghost",onClick:N,disabled:t,children:[e.jsx(qe,{src:Ue}),"Refresh"]})]}),t?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading Radarr library…"]}):h?e.jsx(Rs,{data:u,columns:K,getRowKey:A=>`${A.__instance}-${A.title}-${A.year}`}):e.jsx("div",{className:"hint",children:"No movies found."}),h>0&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",y+1," of ",v," (",h.toLocaleString()," items · page size"," ",Be,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>F(Math.max(0,y-1)),disabled:y===0||t,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>F(Math.min(v-1,y+1)),disabled:y>=v-1||t,children:"Next"})]})]})]})}),Ps=a.memo(function({loading:t,data:u,page:h,totalPages:y,pageSize:v,allMovies:F,onlyMissing:N,reasonFilter:m,onPageChange:T,onRefresh:n,onRestart:M,lastUpdated:b}){const B=a.useMemo(()=>{let g=F;return N&&(g=g.filter(j=>!j.hasFile)),g},[F,N]),K=a.useMemo(()=>m==="all"?B:m==="Not being searched"?B.filter(g=>g.reason==="Not being searched"||!g.reason):B.filter(g=>g.reason===m),[B,m]),A=a.useMemo(()=>F.length,[F]),L=m!=="all"||N,ge=K.length,J=a.useMemo(()=>[{accessorKey:"title",header:"Title",cell:g=>g.getValue()},{accessorKey:"year",header:"Year",size:80},{accessorKey:"monitored",header:"Monitored",cell:g=>{const j=g.getValue();return e.jsx("span",{className:`track-status ${j?"available":"missing"}`,children:j?"✓":"✗"})},size:100},{accessorKey:"hasFile",header:"Has File",cell:g=>{const j=g.getValue();return e.jsx("span",{className:`track-status ${j?"available":"missing"}`,children:j?"✓":"✗"})},size:100},{accessorKey:"qualityProfileName",header:"Quality Profile",cell:g=>g.getValue()||"—",size:150},{accessorKey:"reason",header:"Reason",cell:g=>{const j=g.getValue();return j?e.jsx("span",{className:"table-badge table-badge-reason",children:j}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})},size:120}],[]),C=ze({data:K.slice(h*v,h*v+v),columns:J,getCoreRowModel:Te(),getSortedRowModel:gs()});return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:[u?.counts?e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:"Available:"})," ",(u.counts.available??0).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",(u.counts.monitored??0).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",((u.counts.monitored??0)-(u.counts.available??0)).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total:"})," ",A.toLocaleString(void 0,{maximumFractionDigits:0}),L&&ge<A&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",ge.toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",A.toLocaleString(void 0,{maximumFractionDigits:0})]})]}):"Loading movie information...",b?` (updated ${b})`:""]}),e.jsxs("button",{className:"btn ghost",onClick:M,disabled:t,children:[e.jsx(qe,{src:Ue}),"Restart"]})]}),t?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading…"]}):F.length?e.jsx("div",{className:"table-wrapper",children:e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:C.getHeaderGroups().map(g=>e.jsx("tr",{children:g.headers.map(j=>e.jsx("th",{children:j.isPlaceholder?null:Pe(j.column.columnDef.header,j.getContext())},j.id))},g.id))}),e.jsx("tbody",{children:C.getRowModel().rows.map(g=>{const j=g.original,q=`${j.title}-${j.year}`;return e.jsx("tr",{children:g.getVisibleCells().map(G=>e.jsx("td",{"data-label":String(G.column.columnDef.header),children:Pe(G.column.columnDef.cell,G.getContext())},G.id))},q)})})]})}):e.jsx("div",{className:"hint",children:"No movies found."}),K.length>v&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",h+1," of ",y," (",K.length.toLocaleString()," items · page size"," ",v,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>T(Math.max(0,h-1)),disabled:h===0||t,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>T(Math.min(y-1,h+1)),disabled:h>=y-1||t,children:"Next"})]})]})]})});function As({active:r}){const{push:t}=is(),{value:u,setValue:h,register:y,clearHandler:v}=rs(),{liveArr:F,setLiveArr:N}=os(),[m,T]=a.useState([]),[n,M]=a.useState(""),[b,B]=a.useState(null),[K,A]=a.useState(0),[L,ge]=a.useState(""),[J,C]=a.useState(!1),[g,j]=a.useState(null),[q,G]=a.useState({}),[Q,le]=a.useState(as),[te,W]=a.useState(1),Z=a.useRef(""),l=a.useRef({}),S=a.useRef(u),D=a.useRef(!1),P=_e({getKey:s=>`${s.title}-${s.year}`,hashFields:["title","year","hasFile","monitored","reason"]}),[X,ie]=a.useState([]),[ee,f]=a.useState(!1),[i,x]=a.useState(0),[R,I]=a.useState(""),[$,U]=a.useState(null),he=_e({getKey:s=>`${s.__instance}-${s.title}-${s.year}`,hashFields:["__instance","title","year","hasFile","monitored","reason"]}),[re,we]=a.useState({key:"__instance",direction:"asc"}),[ye,Re]=a.useState(!1),[me,Y]=a.useState("all"),[fe,Ae]=a.useState({available:0,monitored:0,missing:0,total:0}),be=a.useCallback(async()=>{try{const s=await cs();s.ready===!1&&!D.current?(D.current=!0,t("Radarr backend is still initialising. Check the logs if this persists.","info")):s.ready&&(D.current=!0);const o=(s.arr||[]).filter(c=>c.type==="radarr");if(T(o),!o.length){M("aggregate"),B(null),ie([]),Ae({available:0,monitored:0,missing:0,total:0});return}n===""?M(o.length===1?o[0].category:"aggregate"):n!=="aggregate"&&!o.some(c=>c.category===n)&&M(o[0].category)}catch(s){t(s instanceof Error?s.message:"Unable to load Radarr instances","error")}},[t,n]),De=a.useCallback(async(s,o,c,E,_)=>{if(E.length)try{const O=[];for(const k of E){const z=await Je(s,k,c,o),H=z.page??k;if(O.push({page:H,movies:z.movies??[]}),Z.current!==_)return}if(Z.current!==_)return;G(k=>{const z={...k};let H=!1;for(const{page:oe,movies:w}of O){const se=P.syncData(w);se.hasChanges&&(z[oe]=se.data,H=!0)}return l.current=z,H?z:k})}catch(O){t(O instanceof Error?O.message:`Failed to load additional pages for ${s}`,"error")}},[t]),pe=a.useCallback(async(s,o,c,E={})=>{const _=E.preloadAll!==!1;(E.showLoading??!0)&&C(!0);try{const k=`${s}::${c}`,z=Z.current!==k;z&&(Z.current=k,G(()=>(l.current={},{})));const H=await Je(s,o,as,c);B(H);const oe=H.page??o;A(oe),ge(c);const w=H.page_size??as,se=H.total??(H.movies??[]).length,ue=Math.max(1,Math.ceil((se||0)/w));le(w),W(ue);const xe=H.movies??[],ae=z?{}:l.current,V=P.syncData(xe),de=V.hasChanges;if(z&&P.reset(),(z||de)&&(G(je=>{const Ee={...z?{}:je,[oe]:V.data};return l.current=Ee,Ee}),j(new Date().toLocaleTimeString())),_){const je=[];for(let ce=0;ce<ue;ce+=1)ce!==oe&&(ae[ce]||je.push(ce));De(s,c,w,je,k)}}catch(k){t(k instanceof Error?k.message:`Failed to load ${s} movies`,"error")}finally{C(!1)}},[t,De]),Se=a.useCallback(async s=>{if(!m.length){ie([]),Ae({available:0,monitored:0,missing:0,total:0});return}(s?.showLoading??!0)&&f(!0);try{const c=[];let E=0,_=0;for(const oe of m){let w=0,se=!1;const ue=oe.name||oe.category;for(;w<100;){const xe=await Je(oe.category,w,fs,"");if(!se){const V=xe.counts;V&&(E+=V.available??0,_+=V.monitored??0),se=!0}const ae=xe.movies??[];if(ae.forEach(V=>{c.push({...V,__instance:ue})}),!ae.length||ae.length<fs)break;w+=1}}const O=he.syncData(c),k=O.hasChanges;k&&ie(O.data);const z={available:E,monitored:_,missing:c.length-E,total:c.length},H=fe.available!==z.available||fe.monitored!==z.monitored||fe.missing!==z.missing||fe.total!==z.total;H&&Ae(z),R!==u&&(x(0),I(u)),(k||H)&&U(new Date().toLocaleTimeString())}catch(c){ie([]),Ae({available:0,monitored:0,missing:0,total:0}),t(c instanceof Error?c.message:"Failed to load aggregated Radarr data","error")}finally{f(!1)}},[m,u,t,R]);a.useEffect(()=>{r&&be()},[r,be]),a.useEffect(()=>{if(!r||!n||n==="aggregate")return;l.current={},G({}),W(1),A(0);const s=S.current;pe(n,0,s,{preloadAll:!0,showLoading:!0})},[r,n,pe]),a.useEffect(()=>{r&&n==="aggregate"&&Se()},[r,n,Se]),Ke(()=>{n==="aggregate"&&F&&Se({showLoading:!1})},n==="aggregate"&&F?1e3:null),a.useEffect(()=>{if(!r)return;const s=o=>{n==="aggregate"?(I(o),x(0)):n&&(A(0),pe(n,0,o,{preloadAll:!0,showLoading:!0}))};return y(s),()=>{v(s)}},[r,n,y,v,pe]),Ke(()=>{if(n&&n!=="aggregate"){if(S.current?.trim?.()||"")return;pe(n,K,L,{preloadAll:!1,showLoading:!1})}},r&&n&&n!=="aggregate"&&F?1e3:null),a.useEffect(()=>{S.current=u},[u]),a.useEffect(()=>{n==="aggregate"&&I(u)},[n,u]);const Ce=a.useMemo(()=>{let s=X;if(R){const o=R.toLowerCase();s=s.filter(c=>{const E=(c.title??"").toString().toLowerCase(),_=(c.__instance??"").toLowerCase();return E.includes(o)||_.includes(o)})}return ye&&(s=s.filter(o=>!o.hasFile)),me!=="all"&&(me==="Not being searched"?s=s.filter(o=>o.reason==="Not being searched"||!o.reason):s=s.filter(o=>o.reason===me)),s},[X,R,ye,me]),Ne=!!R||me!=="all",Fe=a.useMemo(()=>{const s=[...Ce],o=(c,E)=>{switch(E){case"__instance":return(c.__instance||"").toLowerCase();case"title":return(c.title||"").toLowerCase();case"year":return c.year??0;case"monitored":return c.monitored?1:0;case"hasFile":return c.hasFile?1:0;default:return""}};return s.sort((c,E)=>{const _=o(c,re.key),O=o(E,re.key);let k=0;return typeof _=="number"&&typeof O=="number"?k=_-O:typeof _=="string"&&typeof O=="string"?k=_.localeCompare(O):k=String(_).localeCompare(String(O)),re.direction==="asc"?k:-k}),s},[Ce,re]),Oe=Math.max(1,Math.ceil(Fe.length/Be)),He=a.useMemo(()=>Fe.slice(i*Be,i*Be+Be),[Fe,i]),$e=a.useMemo(()=>{const s=Object.keys(q).map(Number).sort((c,E)=>c-E),o=[];return s.forEach(c=>{q[c]&&o.push(...q[c])}),o},[q]),Ve=a.useCallback(async()=>{if(!(!n||n==="aggregate"))try{await ds(n),t(`Restarted ${n}`,"success")}catch(s){t(s instanceof Error?s.message:`Failed to restart ${n}`,"error")}},[n,t]),Qe=a.useCallback(()=>{Se({showLoading:!0})},[Se]),We=a.useCallback(s=>{we(o=>o.key===s?{key:s,direction:o.direction==="asc"?"desc":"asc"}:{key:s,direction:"asc"})},[]),Ie=a.useCallback(()=>{n&&n!=="aggregate"&&pe(n,K,L,{preloadAll:!1,showLoading:!0})},[n,K,L,pe]),d=a.useCallback(s=>{const o=s.target.value||"aggregate";M(o),o!=="aggregate"&&h("")},[M,h]),p=n==="aggregate";return e.jsxs("section",{className:"card",children:[e.jsx("div",{className:"card-header",children:"Radarr"}),e.jsx("div",{className:"card-body",children:e.jsxs("div",{className:"split",children:[e.jsxs("aside",{className:"pane sidebar",children:[m.length>1&&e.jsx("button",{className:`btn ${p?"active":""}`,onClick:()=>M("aggregate"),children:"All Radarr"}),m.map(s=>e.jsx("button",{className:`btn ghost ${n===s.category?"active":""}`,onClick:()=>{M(s.category),h("")},children:s.name||s.category},s.category))]}),e.jsxs("div",{className:"pane",children:[e.jsxs("div",{className:"field mobile-instance-select",children:[e.jsx("label",{children:"Instance"}),e.jsxs("select",{value:n||"aggregate",onChange:d,disabled:!m.length,children:[m.length>1&&e.jsx("option",{value:"aggregate",children:"All Radarr"}),m.map(s=>e.jsx("option",{value:s.category,children:s.name||s.category},s.category))]})]}),e.jsxs("div",{className:"row",style:{alignItems:"flex-end",gap:"12px",flexWrap:"wrap"},children:[e.jsxs("div",{className:"col field",style:{flex:"1 1 200px"},children:[e.jsx("label",{children:"Search"}),e.jsx("input",{placeholder:"Filter movies",value:u,onChange:s=>h(s.target.value)})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Status"}),e.jsxs("select",{onChange:s=>{const o=s.target.value;Re(o==="missing")},value:ye?"missing":"all",children:[e.jsx("option",{value:"all",children:"All Movies"}),e.jsx("option",{value:"missing",children:"Missing Only"})]})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Search Reason"}),e.jsxs("select",{onChange:s=>Y(s.target.value),value:me,children:[e.jsx("option",{value:"all",children:"All Reasons"}),e.jsx("option",{value:"Not being searched",children:"Not Being Searched"}),e.jsx("option",{value:"Missing",children:"Missing"}),e.jsx("option",{value:"Quality",children:"Quality"}),e.jsx("option",{value:"CustomFormat",children:"Custom Format"}),e.jsx("option",{value:"Upgrade",children:"Upgrade"})]})]})]}),p?e.jsx(Ms,{loading:ee,rows:He,total:Fe.length,page:i,totalPages:Oe,onPageChange:x,onRefresh:Qe,lastUpdated:$,sort:re,onSort:We,summary:fe,instanceCount:m.length,isAggFiltered:Ne}):e.jsx(Ps,{loading:J,data:b,page:K,totalPages:te,pageSize:Q,allMovies:$e,onlyMissing:ye,reasonFilter:me,onPageChange:s=>{A(s),pe(n,s,L,{preloadAll:!0})},onRefresh:Ie,onRestart:()=>void Ve(),lastUpdated:g})]})]})})]})}const ts=25,Ge=50,bs=200;function Ds(r,t){if(!t)return r;const u=[];for(const h of r){const y=h.seasons??{},v={};for(const[F,N]of Object.entries(y)){const m=(N.episodes??[]).filter(T=>!T.hasFile);m.length&&(v[F]={...N,episodes:m})}Object.keys(v).length!==0&&u.push({...h,seasons:v})}return u}function Ye(r,t){return JSON.stringify(Ds(r,t))}function $s({active:r}){const{push:t}=is(),{value:u,setValue:h,register:y,clearHandler:v}=rs(),{liveArr:F,setLiveArr:N,groupSonarr:m,setGroupSonarr:T}=os(),[n,M]=a.useState([]),[b,B]=a.useState(""),[K,A]=a.useState(null),[L,ge]=a.useState(0),[J,C]=a.useState(""),[g,j]=a.useState(!1),[q,G]=a.useState(null),[Q,le]=a.useState({}),te=a.useRef({}),W=a.useRef(null),Z=a.useRef(""),[l,S]=a.useState(ts),[D,P]=a.useState(1),[X,ie]=a.useState(0),ee=a.useRef(u),f=a.useRef(!1),i=a.useRef(b),[x,R]=a.useState([]),[I,$]=a.useState(!1),[U,he]=a.useState(0),[re,we]=a.useState(""),[ye,Re]=a.useState(null),me=_e({getKey:s=>`${s.__instance}-${s.series}-${s.season}-${s.episode}`,hashFields:["__instance","series","season","episode","title","hasFile","monitored","airDate","reason","qualityProfileId","qualityProfileName"]}),[Y,fe]=a.useState(!1),Ae=a.useRef(Y),[be,De]=a.useState("all"),[pe,Se]=a.useState({available:0,monitored:0,missing:0,total:0}),Ce=a.useCallback(async()=>{try{const s=await cs();s.ready===!1&&!f.current?(f.current=!0,t("Sonarr backend is still initialising. Check the logs if this persists.","info")):s.ready&&(f.current=!0);const o=(s.arr||[]).filter(c=>c.type==="sonarr");if(M(o),!o.length){B("aggregate"),A(null),R([]),Se({available:0,monitored:0,missing:0,total:0});return}b===""?B(o.length===1?o[0].category:"aggregate"):b!=="aggregate"&&!o.some(c=>c.category===b)&&B(o[0].category)}catch(s){t(s instanceof Error?s.message:"Unable to load Sonarr instances","error")}},[t,b]),Ne=a.useCallback(async(s,o,c,E={})=>{const{preloadAll:_=!0,showLoading:O=!0,missingOnly:k}=E,z=k??Y;O&&j(!0);try{const H=`${s}::${c}::${z?"missing":"all"}`,oe=Z.current!==H;oe&&(Z.current=H,le(()=>(te.current={},{})),ie(0),P(1));const w=await Xe(s,o,ts,c,{missingOnly:z});console.log(`[Sonarr Instance] Response for ${s} page ${o}:`,{total:w.total,page:w.page,page_size:w.page_size,series_count:w.series?.length??0,counts:w.counts,missingOnly:z,firstSeries:w.series?.[0]?{title:w.series[0].series?.title,seasonsCount:Object.keys(w.series[0].seasons??{}).length,firstSeasonEpisodes:Object.values(w.series[0].seasons??{})[0]?.episodes?.length??0}:null});const se=w.page??o,ue=w.page_size??ts,xe=w.total??(w.series??[]).length,ae=Math.max(1,Math.ceil((xe||0)/ue)),V=w.series??[],de=oe?{}:te.current,je={...de,[se]:V},ce=Ye(de[se]??[],z),Ee=Ye(V,z),ke=oe||ce!==Ee;if(te.current=je,ke&&le(je),A(ne=>{const ve=ne?.counts??null,Le=w.counts??null;return!ne||ne.total!==w.total||ne.page!==w.page||ne.page_size!==w.page_size||(ve?.available??null)!==(Le?.available??null)||(ve?.monitored??null)!==(Le?.monitored??null)||(ve?.missing??null)!==(Le?.missing??null)||ke?(W.current=w,w):ne}),ge(ne=>ne===se?ne:se),C(ne=>ne===c?ne:c),S(ne=>ne===ue?ne:ue),P(ne=>ne===ae?ne:ae),ie(ne=>ne===xe?ne:xe),ke&&G(new Date().toLocaleTimeString()),_){const ne=[];for(let ve=0;ve<ae;ve+=1)ve!==se&&(je[ve]||ne.push(ve));for(const ve of ne)try{const Le=await Xe(s,ve,ue,c,{missingOnly:z});if(Z.current!==H)break;const Me=Le.page??ve,Ze=Le.series??[],us=te.current,js=Ye(us[Me]??[],z),ps=Ye(Ze,z);if(js===ps){te.current={...us,[Me]:Ze};continue}le(Ns=>{const hs={...Ns,[Me]:Ze};return te.current=hs,hs})}catch{break}}}catch(H){t(H instanceof Error?H.message:`Failed to load ${s} series`,"error")}finally{O&&j(!1)}},[t,Y]),Fe=a.useCallback(async s=>{if(!n.length){R([]),Se({available:0,monitored:0,missing:0,total:0});return}console.log(`[Sonarr Aggregate] Starting aggregation for ${n.length} instances`),(s?.showLoading??!0)&&$(!0);try{const c=[];let E=0,_=0,O=0;for(const se of n){let ue=0,xe=!1;const ae=se.name||se.category;for(console.log(`[Sonarr Aggregate] Processing instance: ${ae}`);ue<200;){const V=await Xe(se.category,ue,bs,"",{missingOnly:Y});if(console.log(`[Sonarr Aggregate] Response for ${ae} page ${ue}:`,{total:V.total,page:V.page,page_size:V.page_size,series_count:V.series?.length??0,counts:V.counts,missingOnly:Y,firstSeries:V.series?.[0]?{title:V.series[0].series?.title,seasonsCount:Object.keys(V.series[0].seasons??{}).length,firstSeasonEpisodes:Object.values(V.series[0].seasons??{})[0]?.episodes?.length??0,firstEpisode:Object.values(V.series[0].seasons??{})[0]?.episodes?.[0]}:null}),!xe){const ce=V.counts;ce&&(E+=ce.available??0,_+=ce.monitored??0,O+=ce.missing??0),xe=!0}const de=V.series??[];let je=0;if(de.forEach(ce=>{const Ee=Object.keys(ce.seasons??{}).length;let ke=0;Object.values(ce.seasons??{}).forEach(ne=>{ke+=(ne.episodes??[]).length}),je+=ke}),console.log(`[Sonarr Aggregate] Instance: ${ae}, Page: ${ue}, Series count: ${de.length}, Total episodes so far: ${c.length}, Episodes in this response: ${je}`),de.forEach(ce=>{const Ee=ce.series?.title||"",ke=ce.series?.qualityProfileId??null,ne=ce.series?.qualityProfileName??null;Object.entries(ce.seasons??{}).forEach(([ve,Le])=>{(Le.episodes??[]).forEach(Me=>{const Ze=Me.reason??null;c.push({__instance:ae,series:Ee,season:ve,episode:Me.episodeNumber??"",title:Me.title??"",monitored:!!Me.monitored,hasFile:!!Me.hasFile,airDate:Me.airDateUtc??"",reason:Ze,qualityProfileId:ke,qualityProfileName:ne})})})}),!de.length||de.length<bs){console.log(`[Sonarr Aggregate] Breaking pagination for ${ae} - series.length=${de.length}`);break}ue+=1}}const k=me.syncData(c),z=k.hasChanges,H=new Map;c.forEach(se=>{const ue=se.reason||"null/empty";H.set(ue,(H.get(ue)||0)+1)}),console.log("[Sonarr Aggregate] Reason distribution:",Object.fromEntries(H)),z?(console.log(`[Sonarr Aggregate] Data changed, updating from ${x.length} to ${c.length} episodes`),R(k.data)):console.log("[Sonarr Aggregate] Data unchanged, skipping update");const oe={available:E,monitored:_,missing:O,total:c.length},w=pe.available!==oe.available||pe.monitored!==oe.monitored||pe.missing!==oe.missing||pe.total!==oe.total;w&&Se(oe),re!==u&&(he(0),we(u)),(z||w)&&Re(new Date().toLocaleTimeString())}catch(c){R([]),Se({available:0,monitored:0,missing:0,total:0}),t(c instanceof Error?c.message:"Failed to load aggregated Sonarr data","error")}finally{$(!1)}},[n,u,t,Y,re]);a.useEffect(()=>{r&&Ce()},[r,Ce]),a.useEffect(()=>{if(!r||!b||b==="aggregate")return;const s=i.current!==b,o=Ae.current!==Y;s&&(ge(0),i.current=b),o&&(Ae.current=Y);const c=ee.current;Ne(b,s?0:L,c,{preloadAll:!0,showLoading:!0,missingOnly:Y})},[r,b,Y,Ne,L]),a.useEffect(()=>{r&&b==="aggregate"&&Fe()},[r,b,Fe]),Ke(()=>{b==="aggregate"&&F&&Fe({showLoading:!1})},b==="aggregate"&&F?1e3:null),a.useEffect(()=>{if(!r)return;const s=o=>{b==="aggregate"?(we(o),he(0)):b&&(ge(0),Ne(b,0,o,{preloadAll:!0,showLoading:!0,missingOnly:Y}))};return y(s),()=>v(s)},[r,b,y,v,Ne,Y]),Ke(()=>{if(b&&b!=="aggregate"){if(ee.current?.trim?.()||"")return;Ne(b,L,J,{preloadAll:!1,showLoading:!1,missingOnly:Y})}},r&&b&&b!=="aggregate"&&F?1e3:null),a.useEffect(()=>{ee.current=u},[u]),a.useEffect(()=>{b==="aggregate"&&we(u)},[b,u]);const Oe=a.useMemo(()=>{let s=x;if(re){const o=re.toLowerCase();s=s.filter(c=>c.series.toLowerCase().includes(o)||c.title.toLowerCase().includes(o)||c.__instance.toLowerCase().includes(o))}if(Y&&(s=s.filter(o=>!o.hasFile)),be!=="all"){console.log(`[Sonarr Filter] Applying reason filter: "${be}"`);const o=s.length;be==="Not being searched"?s=s.filter(c=>c.reason==="Not being searched"||!c.reason):s=s.filter(c=>c.reason===be),console.log(`[Sonarr Filter] Filtered from ${o} to ${s.length} episodes for reason "${be}"`),s.length<10&&console.log("[Sonarr Filter] Sample filtered rows:",s.slice(0,5).map(c=>({series:c.series,episode:c.episode,reason:c.reason})))}return s},[x,re,Y,be]),He=!!re||Y||be!=="all",$e=Oe,Ve=Math.max(1,Math.ceil($e.length/Ge));a.useMemo(()=>$e.slice(U*Ge,U*Ge+Ge),[$e,U]);const Qe=Q[L]??[],We=a.useMemo(()=>{const s=Object.keys(Q).map(Number).sort((c,E)=>c-E),o=[];return s.forEach(c=>{Q[c]&&o.push(...Q[c])}),o},[Q]),Ie=a.useCallback(async()=>{if(!(!b||b==="aggregate"))try{await ds(b),t(`Restarted ${b}`,"success")}catch(s){t(s instanceof Error?s.message:`Failed to restart ${b}`,"error")}},[b,t]),d=a.useCallback(s=>{const o=s.target.value||"aggregate";B(o),o!=="aggregate"&&h("")},[B,h]),p=b==="aggregate";return e.jsxs("section",{className:"card",children:[e.jsx("div",{className:"card-header",children:"Sonarr"}),e.jsx("div",{className:"card-body",children:e.jsxs("div",{className:"split",children:[e.jsxs("aside",{className:"pane sidebar",children:[n.length>1&&e.jsx("button",{className:`btn ${p?"active":""}`,onClick:()=>B("aggregate"),children:"All Sonarr"}),n.map(s=>e.jsx("button",{className:`btn ghost ${b===s.category?"active":""}`,onClick:()=>{B(s.category),h("")},children:s.name||s.category},s.category))]}),e.jsxs("div",{className:"pane",children:[e.jsxs("div",{className:"field mobile-instance-select",children:[e.jsx("label",{children:"Instance"}),e.jsxs("select",{value:b||"aggregate",onChange:d,disabled:!n.length,children:[n.length>1&&e.jsx("option",{value:"aggregate",children:"All Sonarr"}),n.map(s=>e.jsx("option",{value:s.category,children:s.name||s.category},s.category))]})]}),e.jsxs("div",{className:"row",style:{alignItems:"flex-end",gap:"12px",flexWrap:"wrap"},children:[e.jsxs("div",{className:"col field",style:{flex:"1 1 200px"},children:[e.jsx("label",{children:"Search"}),e.jsx("input",{placeholder:"Filter series or episodes",value:u,onChange:s=>h(s.target.value)})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Status"}),e.jsxs("select",{onChange:s=>{const c=s.target.value==="missing";fe(c),b&&b!=="aggregate"&&Ne(b,0,ee.current||"",{preloadAll:!0,showLoading:!0,missingOnly:c})},value:Y?"missing":"all",children:[e.jsx("option",{value:"all",children:"All Episodes"}),e.jsx("option",{value:"missing",children:"Missing Only"})]})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Search Reason"}),e.jsxs("select",{onChange:s=>De(s.target.value),value:be,children:[e.jsx("option",{value:"all",children:"All Reasons"}),e.jsx("option",{value:"Not being searched",children:"Not Being Searched"}),e.jsx("option",{value:"Missing",children:"Missing"}),e.jsx("option",{value:"Quality",children:"Quality"}),e.jsx("option",{value:"CustomFormat",children:"Custom Format"}),e.jsx("option",{value:"Upgrade",children:"Upgrade"})]})]})]}),p?e.jsx(ks,{loading:I,rows:$e,total:$e.length,page:U,totalPages:Ve,onPageChange:he,onRefresh:()=>void Fe({showLoading:!0}),lastUpdated:ye,groupSonarr:m,summary:pe,instanceCount:n.length,isAggFiltered:He}):e.jsx(Ls,{loading:g,counts:K?.counts??null,series:m?Qe:We,page:L,pageSize:l,totalPages:D,totalItems:X,onlyMissing:Y,reasonFilter:be,onPageChange:s=>{ge(s),Ne(b,s,J,{preloadAll:!1,showLoading:!0,missingOnly:Y})},onRestart:()=>void Ie(),lastUpdated:q,groupSonarr:m,instances:n,selection:b})]})]})})]})}function ks({loading:r,rows:t,total:u,page:h,totalPages:y,onPageChange:v,onRefresh:F,lastUpdated:N,groupSonarr:m,summary:T,instanceCount:n,isAggFiltered:M=!1}){const b=a.useRef([]),B=a.useRef([]),K=a.useRef(new Map),A=a.useMemo(()=>{if(t===b.current)return B.current;const l=new Map;t.forEach(P=>{const X=P.__instance,ie=P.series,ee=String(P.season);l.has(X)||l.set(X,new Map);const f=l.get(X);f.has(ie)||f.set(ie,new Map);const i=f.get(ie);i.has(ee)||i.set(ee,[]),i.get(ee).push(P)});const S=[],D=new Map;return l.forEach((P,X)=>{P.forEach((ie,ee)=>{const f=`${X}-${ee}`,i=new Set;ie.forEach(($,U)=>{$.forEach(he=>{const re=`${U}-${he.episode}`;i.add(re)})});const x=K.current.get(f);if(x&&x.episodeKeys.size===i.size){let $=!0;for(const U of i)if(!x.episodeKeys.has(U)){$=!1;break}if($){S.push(x),D.set(f,x);return}}const R=Array.from(ie.values())[0]?.[0];console.log(`[Sonarr Grouped] Series: ${ee}, QualityProfile: ${R?.qualityProfileName}, FirstEpisode:`,R);const I={instance:X,series:ee,qualityProfileId:R?.qualityProfileId,qualityProfileName:R?.qualityProfileName,subRows:Array.from(ie.entries()).map(([$,U])=>({seasonNumber:$,isSeason:!0,subRows:U.map(he=>({...he,isEpisode:!0}))})),episodeKeys:i};S.push(I),D.set(f,I)})}),b.current=t,B.current=S,K.current=D,S},[t]),L=a.useMemo(()=>A.slice(h*50,(h+1)*50),[A,h]),ge=a.useMemo(()=>t.slice(h*50,(h+1)*50),[t,h]),J=m?L:ge,C=a.useMemo(()=>[{accessorKey:"title",header:"Title",cell:({row:l})=>{if(l.original.isEpisode)return l.original.title;if(l.original.isSeason)return`Season ${l.original.seasonNumber}`;const S=[l.original.series];return l.original.instance&&S.push(`(${l.original.instance})`),l.original.qualityProfileName&&S.push(`• ${l.original.qualityProfileName}`),S.join(" ")}},{accessorKey:"monitored",header:"Monitored",cell:({row:l})=>{const S=(l.original.isEpisode,l.original.monitored);return e.jsx("span",{className:`track-status ${S?"available":"missing"}`,children:S?"✓":"✗"})}},{accessorKey:"hasFile",header:"Has File",cell:({row:l})=>{if(l.original.isEpisode){const S=l.original.hasFile;return e.jsx("span",{className:`track-status ${S?"available":"missing"}`,children:S?"✓":"✗"})}return null}},{accessorKey:"airDate",header:"Air Date",cell:({row:l})=>l.original.isEpisode?l.original.airDate||"—":null}],[]),g=a.useMemo(()=>[...n>1?[{accessorKey:"__instance",header:"Instance"}]:[],{accessorKey:"series",header:"Series"},{accessorKey:"season",header:"Season"},{accessorKey:"episode",header:"Episode"},{accessorKey:"title",header:"Title"},{accessorKey:"monitored",header:"Monitored",cell:({getValue:l})=>{const S=l();return e.jsx("span",{className:`track-status ${S?"available":"missing"}`,children:S?"✓":"✗"})}},{accessorKey:"hasFile",header:"Has File",cell:({getValue:l})=>{const S=l();return e.jsx("span",{className:`track-status ${S?"available":"missing"}`,children:S?"✓":"✗"})}},{accessorKey:"airDate",header:"Air Date",cell:({getValue:l})=>l()||"—"},{accessorKey:"qualityProfileName",header:"Quality Profile",cell:({getValue:l})=>l()||"—"},{accessorKey:"reason",header:"Reason",cell:({getValue:l})=>{const S=l();return S?e.jsx("span",{className:"table-badge table-badge-reason",children:S}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})}}],[n]),j=m?C:g,q=ze({data:J,columns:j,getCoreRowModel:Te(),getExpandedRowModel:vs()}),G=ze({data:J,columns:j,getCoreRowModel:Te(),getSortedRowModel:gs(),getPaginationRowModel:ys(),state:{pagination:{pageIndex:h,pageSize:50}},manualPagination:!0,pageCount:y}),Q=m?q:G,le=50,te=Math.ceil(m?A.length/le:t.length/le),W=Math.min(h,Math.max(0,te-1)),Z=m?`${A.length} series`:t.length.toLocaleString();return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:["Aggregated episodes across all instances"," ",N?`(updated ${N})`:"",e.jsx("br",{}),e.jsx("strong",{children:"Available:"})," ",T.available.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",T.monitored.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",T.missing.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total Episodes:"})," ",T.total.toLocaleString(void 0,{maximumFractionDigits:0}),M&&t.length<T.total&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",t.length.toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",T.total.toLocaleString(void 0,{maximumFractionDigits:0})]})]}),e.jsxs("button",{className:"btn ghost",onClick:F,disabled:r,children:[e.jsx(qe,{src:Ue}),"Refresh"]})]}),r?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading Sonarr library…"]}):m?e.jsx("div",{className:"sonarr-hierarchical-view",children:L.map(l=>{console.log(`[Sonarr Render] Series: ${l.series}, QualityProfile: ${l.qualityProfileName}`);let S=0;return l.subRows.forEach(D=>{S+=D.subRows.length}),e.jsxs("details",{className:"series-details",children:[e.jsxs("summary",{className:"series-summary",children:[e.jsx("span",{className:"series-title",children:l.series}),e.jsxs("span",{className:"series-instance",children:["(",l.instance,")"]}),e.jsxs("span",{className:"series-count",children:["(",S," episodes)"]}),l.qualityProfileName?e.jsxs("span",{className:"series-quality",children:["• ",l.qualityProfileName]}):null]}),e.jsx("div",{className:"series-content",children:l.subRows.map(D=>e.jsxs("details",{className:"season-details",children:[e.jsxs("summary",{className:"season-summary",children:[e.jsxs("span",{className:"season-title",children:["Season ",D.seasonNumber]}),e.jsxs("span",{className:"season-count",children:["(",D.subRows.length," episodes)"]})]}),e.jsx("div",{className:"season-content",children:e.jsx("div",{className:"episodes-table-wrapper",children:e.jsxs("table",{className:"episodes-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Episode"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Monitored"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Air Date"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:D.subRows.map(P=>e.jsxs("tr",{children:[e.jsx("td",{"data-label":"Episode",children:P.episode}),e.jsx("td",{"data-label":"Title",children:P.title}),e.jsx("td",{"data-label":"Monitored",children:e.jsx("span",{className:`track-status ${P.monitored?"available":"missing"}`,children:P.monitored?"✓":"✗"})}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${P.hasFile?"available":"missing"}`,children:P.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Air Date",children:P.airDate||"—"}),e.jsx("td",{"data-label":"Reason",children:P.reason?e.jsx("span",{className:"table-badge table-badge-reason",children:P.reason}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${P.__instance}-${P.series}-${P.season}-${P.episode}`))})]})})})]},`${l.instance}-${l.series}-${D.seasonNumber}`))})]},`${l.instance}-${l.series}`)})}):!r&&T.total===0&&n>0?e.jsxs("div",{className:"hint",children:[e.jsx("p",{children:"No episodes found in the database."}),e.jsx("p",{children:"The backend may still be initializing and syncing data from your Sonarr instances. Please check the logs or wait a few moments and refresh."})]}):J.length?e.jsx("div",{className:"table-wrapper",children:e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:e.jsx("tr",{children:Q.getFlatHeaders().map(l=>e.jsxs("th",{className:l.column.getCanSort()?"sortable":"",onClick:l.column.getToggleSortingHandler(),children:[l.isPlaceholder?null:Pe(l.column.columnDef.header,l.getContext()),l.column.getCanSort()&&e.jsx("span",{className:"sort-arrow",children:{asc:"▲",desc:"▼"}[l.column.getIsSorted()]??null})]},l.id))})}),e.jsx("tbody",{children:Q.getRowModel().rows.map(l=>{const S=l.original,D=`${S.__instance}-${S.series}-${S.season}-${S.episode}`;return e.jsx("tr",{children:l.getVisibleCells().map(P=>e.jsx("td",{"data-label":P.column.columnDef.header,children:Pe(P.column.columnDef.cell,P.getContext())},P.id))},D)})})]})}):e.jsx("div",{className:"hint",children:"No series found."}),J.length>0&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",W+1," of ",te," (",Z," items · page size ",le,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>v(Math.max(0,W-1)),disabled:W===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>v(Math.min(te-1,W+1)),disabled:W>=te-1||r,children:"Next"})]})]})]})}function Ls({loading:r,counts:t,series:u,page:h,pageSize:y,totalPages:v,totalItems:F,onlyMissing:N,reasonFilter:m,onPageChange:T,onRestart:n,lastUpdated:M,groupSonarr:b,instances:B,selection:K}){const[A,L]=a.useState(0),ge=50,J=a.useRef([]),C=a.useRef([]),g=a.useMemo(()=>{if(u===J.current)return C.current;const i=[];for(const x of u){const R=x.series?.title||"",I=x.series?.qualityProfileId??null,$=x.series?.qualityProfileName??null;Object.entries(x.seasons??{}).forEach(([U,he])=>{(he.episodes??[]).forEach(re=>{i.push({__instance:"Instance",series:R,season:U,episode:re.episodeNumber??"",title:re.title??"",monitored:!!re.monitored,hasFile:!!re.hasFile,airDate:re.airDateUtc??"",reason:re.reason??null,qualityProfileId:I,qualityProfileName:$})})})}return J.current=u,C.current=i,i},[u]),j=a.useMemo(()=>{let i=g;if(N&&(i=i.filter(x=>!x.hasFile)),m!=="all"){console.log(`[Sonarr Instance Filter] Applying reason filter: "${m}"`);const x=i.length;m==="Not being searched"?i=i.filter(R=>R.reason==="Not being searched"||!R.reason):i=i.filter(R=>R.reason===m),console.log(`[Sonarr Instance Filter] Filtered from ${x} to ${i.length} episodes for reason "${m}"`),i.length<10&&console.log("[Sonarr Instance Filter] Sample filtered rows:",i.slice(0,5).map(R=>({series:R.series,episode:R.episode,reason:R.reason})))}return i},[g,N,m]);a.useEffect(()=>{L(0)},[N,m]);const q=a.useRef([]),G=a.useRef([]),Q=a.useMemo(()=>{if(j===q.current)return G.current;const i=new Map;j.forEach(R=>{const I=R.series;i.has(I)||i.set(I,new Map);const $=i.get(I),U=String(R.season);$.has(U)||$.set(U,[]),$.get(U).push(R)});const x=Array.from(i.entries()).map(([R,I])=>{const $=Array.from(I.values())[0]?.[0];return{series:R,qualityProfileId:$?.qualityProfileId,qualityProfileName:$?.qualityProfileName,subRows:Array.from(I.entries()).map(([U,he])=>({seasonNumber:U,isSeason:!0,subRows:he.map(re=>({...re,isEpisode:!0}))}))}});return q.current=j,G.current=x,x},[j]),le=a.useMemo(()=>g.length,[g]),te=m!=="all"||N,W=j.length,Z=Math.max(1,Math.ceil(j.length/ge)),l=Math.min(A,Math.max(0,Z-1)),S=a.useMemo(()=>j.slice(l*ge,(l+1)*ge),[j,l]),D=50,[P,X]=a.useState(0),ie=Math.max(1,Math.ceil(Q.length/D)),ee=Math.min(P,Math.max(0,ie-1)),f=a.useMemo(()=>Q.slice(ee*D,(ee+1)*D),[Q,ee]);return a.useEffect(()=>{X(0)},[N,m]),e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:[t?e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:"Available:"})," ",t.available.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",t.monitored.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",(t.missing??0).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total Episodes:"})," ",le.toLocaleString(void 0,{maximumFractionDigits:0}),te&&W<le&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",W.toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",le.toLocaleString(void 0,{maximumFractionDigits:0})]})]}):"Loading series information...",M?` (updated ${M})`:""]}),e.jsxs("button",{className:"btn ghost",onClick:n,disabled:r,children:[e.jsx(qe,{src:Ue}),"Restart"]})]}),r?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading series…"]}):b?e.jsx("div",{className:"sonarr-hierarchical-view",children:f.map(i=>{let x=0;i.subRows.forEach(I=>{x+=I.subRows.length});const R=B.find(I=>I.category===K)?.name||K;return e.jsxs("details",{className:"series-details",children:[e.jsxs("summary",{className:"series-summary",children:[e.jsx("span",{className:"series-title",children:i.series}),e.jsxs("span",{className:"series-instance",children:["(",R,")"]}),e.jsxs("span",{className:"series-count",children:["(",x," episodes)"]}),i.qualityProfileName?e.jsxs("span",{className:"series-quality",children:["• ",i.qualityProfileName]}):null]}),e.jsx("div",{className:"series-content",children:i.subRows.map(I=>e.jsxs("details",{className:"season-details",children:[e.jsxs("summary",{className:"season-summary",children:[e.jsxs("span",{className:"season-title",children:["Season ",I.seasonNumber]}),e.jsxs("span",{className:"season-count",children:["(",I.subRows.length," episodes)"]})]}),e.jsx("div",{className:"season-content",children:e.jsx("div",{className:"episodes-table-wrapper",children:e.jsxs("table",{className:"episodes-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Episode"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Monitored"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Air Date"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:I.subRows.map($=>e.jsxs("tr",{children:[e.jsx("td",{"data-label":"Episode",children:$.episode}),e.jsx("td",{"data-label":"Title",children:$.title}),e.jsx("td",{"data-label":"Monitored",children:e.jsx("span",{className:`track-status ${$.monitored?"available":"missing"}`,children:$.monitored?"✓":"✗"})}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${$.hasFile?"available":"missing"}`,children:$.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Air Date",children:$.airDate||"—"}),e.jsx("td",{"data-label":"Reason",children:$.reason?e.jsx("span",{className:"table-badge table-badge-reason",children:$.reason}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${$.series}-${$.season}-${$.episode}`))})]})})})]},`${i.series}-${I.seasonNumber}`))})]},`${i.series}`)})}):!r&&u.length>0&&j.length===0&&g.length===0?e.jsxs("div",{className:"hint",children:[e.jsx("p",{children:"No episodes found for these series."}),e.jsx("p",{children:"The backend may still be syncing episode data from Sonarr. Please check the logs or wait a few moments and refresh."})]}):!r&&u.length>0&&j.length===0&&g.length>0?e.jsx("div",{className:"hint",children:"No episodes match the current filter."}):!b&&j.length>0?e.jsxs("div",{className:"table-wrapper",children:[e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Series"}),e.jsx("th",{children:"Season"}),e.jsx("th",{children:"Episode"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Monitored"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Air Date"}),e.jsx("th",{children:"Quality Profile"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:S.map((i,x)=>e.jsxs("tr",{children:[e.jsx("td",{"data-label":"Series",children:i.series}),e.jsx("td",{"data-label":"Season",children:i.season}),e.jsx("td",{"data-label":"Episode",children:i.episode}),e.jsx("td",{"data-label":"Title",children:i.title}),e.jsx("td",{"data-label":"Monitored",children:e.jsx("span",{className:`track-status ${i.monitored?"available":"missing"}`,children:i.monitored?"✓":"✗"})}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${i.hasFile?"available":"missing"}`,children:i.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Air Date",children:i.airDate||"—"}),e.jsx("td",{"data-label":"Quality Profile",children:i.qualityProfileName||"—"}),e.jsx("td",{"data-label":"Reason",children:i.reason?e.jsx("span",{className:"table-badge table-badge-reason",children:i.reason}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${i.series}-${i.season}-${i.episode}-${x}`))})]}),Z>1&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",l+1," of ",Z," (",j.length.toLocaleString()," episodes · page size ",ge,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>L(Math.max(0,l-1)),disabled:l===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>L(Math.min(Z-1,l+1)),disabled:l>=Z-1||r,children:"Next"})]})]})]}):e.jsx("div",{className:"hint",children:"No series found."}),b&&Q.length>0&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",ee+1," of ",ie," (",Q.length.toLocaleString()," series · page size ",D,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>X(Math.max(0,ee-1)),disabled:ee===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>X(Math.min(ie-1,ee+1)),disabled:ee>=ie-1||r,children:"Next"})]})]})]})}const ns=50,xs=500;function Es({loading:r,rows:t,trackRows:u,page:h,onPageChange:y,onRefresh:v,lastUpdated:F,summary:N,instanceCount:m,groupLidarr:T,isAggFiltered:n=!1}){const M=a.useRef([]),b=a.useRef([]),B=a.useRef(new Map),K=a.useMemo(()=>{if(t===M.current)return b.current;const C=new Map;t.forEach(q=>{const G=q.__instance,Q=q.album?.artistName||"Unknown Artist";C.has(G)||C.set(G,new Map);const le=C.get(G);le.has(Q)||le.set(Q,[]),le.get(Q).push(q)});const g=[],j=new Map;return C.forEach((q,G)=>{q.forEach((Q,le)=>{const te=`${G}-${le}`,W=new Set;Q.forEach(P=>{const ie=`${P.album?.title}`;W.add(ie)});const Z=B.current.get(te);if(Z&&Z.albumKeys.size===W.size){let P=!0;for(const X of W)if(!Z.albumKeys.has(X)){P=!1;break}if(P){g.push(Z),j.set(te,Z);return}}const S=Q[0]?.album,D={instance:G,artist:le,qualityProfileId:S?.qualityProfileId??null,qualityProfileName:S?.qualityProfileName??null,albums:Q,albumKeys:W};g.push(D),j.set(te,D)})}),M.current=t,b.current=g,B.current=j,g},[t]),A=a.useMemo(()=>K.slice(h*50,(h+1)*50),[K,h]),L=a.useMemo(()=>{const g=h*50,j=g+50;return u.slice(g,j)},[u,h]),ge=a.useMemo(()=>[...m>1?[{accessorKey:"__instance",header:"Instance",size:120}]:[],{accessorKey:"artistName",header:"Artist",size:150},{accessorKey:"albumTitle",header:"Album",size:150},{accessorKey:"trackNumber",header:"#",size:50},{accessorKey:"title",header:"Track"},{accessorKey:"duration",header:"Duration",cell:C=>{const g=C.getValue();return g?`${Math.floor(g/60)}:${String(g%60).padStart(2,"0")}`:e.jsx("span",{className:"hint",children:"—"})},size:80},{accessorKey:"monitored",header:"Monitored",cell:C=>{const g=C.getValue();return e.jsx("span",{className:`track-status ${g?"available":"missing"}`,children:g?"✓":"✗"})},size:100},{accessorKey:"hasFile",header:"Has File",cell:C=>{const g=C.getValue();return e.jsx("span",{className:`track-status ${g?"available":"missing"}`,children:g?"✓":"✗"})},size:100},{accessorKey:"qualityProfileName",header:"Quality Profile",cell:C=>C.getValue()||"—",size:150},{accessorKey:"reason",header:"Reason",cell:C=>{const g=C.getValue();return g?e.jsx("span",{className:"table-badge table-badge-reason",children:g}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})},size:120}],[m]),J=ze({data:L,columns:ge,getCoreRowModel:Te()});return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:["Aggregated albums across all instances"," ",F?`(updated ${F})`:"",e.jsx("br",{}),e.jsx("strong",{children:"Available:"})," ",N.available.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",N.monitored.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",N.missing.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total:"})," ",N.total.toLocaleString(void 0,{maximumFractionDigits:0}),n&&(T?t.length:u.length)<N.total&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",(T?t.length:u.length).toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",N.total.toLocaleString(void 0,{maximumFractionDigits:0})]})]}),e.jsxs("button",{className:"btn ghost",onClick:v,disabled:r,children:[e.jsx(qe,{src:Ue}),"Refresh"]})]}),r?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading Lidarr library…"]}):T?e.jsx("div",{className:"lidarr-hierarchical-view",children:A.map(C=>e.jsxs("details",{className:"artist-details",children:[e.jsxs("summary",{className:"artist-summary",children:[e.jsx("span",{className:"artist-title",children:C.artist}),e.jsxs("span",{className:"artist-instance",children:["(",C.instance,")"]}),e.jsxs("span",{className:"artist-count",children:["(",C.albums.length," albums)"]}),C.qualityProfileName?e.jsxs("span",{className:"artist-quality",children:["• ",C.qualityProfileName]}):null]}),e.jsx("div",{className:"artist-content",children:C.albums.map(g=>{const j=g.album,q=j?.title||"Unknown Album",G=j?.id||0,Q=j?.artistName||"",le=j?.releaseDate,te=j?.monitored,W=j?.hasFile,Z=j?.reason,l=g.tracks||[],S=g.totals;return e.jsxs("details",{className:"album-details",children:[e.jsxs("summary",{className:"album-summary",children:[e.jsx("span",{className:"album-title",children:q}),le&&e.jsx("span",{className:"album-date",children:new Date(le).toLocaleDateString()}),l&&l.length>0&&e.jsxs("span",{className:"album-track-count",children:["(",S.available||0,"/",S.monitored||l.length," tracks)"]}),e.jsx("span",{className:`album-status ${W?"has-file":"missing"}`,children:W?"✓":"✗"})]}),e.jsx("div",{className:"album-content",children:l&&l.length>0?e.jsx("div",{className:"tracks-table-wrapper",children:e.jsxs("table",{className:"tracks-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"#"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Duration"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:l.map(D=>e.jsxs("tr",{className:D.hasFile?"track-available":"track-missing",children:[e.jsx("td",{"data-label":"#",children:D.trackNumber}),e.jsx("td",{"data-label":"Title",children:D.title}),e.jsx("td",{"data-label":"Duration",children:D.duration?`${Math.floor(D.duration/60)}:${String(D.duration%60).padStart(2,"0")}`:"—"}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${D.hasFile?"available":"missing"}`,children:D.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Reason",children:Z?e.jsx("span",{className:"table-badge table-badge-reason",children:Z}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${G}-${D.id}`))})]})}):e.jsxs("div",{className:"album-info",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Monitored:"})," ",te?"Yes":"No"," | ",e.jsx("strong",{children:"Has File:"})," ",W?"Yes":"No"]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Reason:"})," ",Z?e.jsx("span",{className:"table-badge table-badge-reason",children:Z}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})]})]})})]},`${g.__instance}-${Q}-${q}`)})})]},`${C.instance}-${C.artist}`))}):u.length?e.jsx("div",{className:"table-wrapper",children:e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:J.getHeaderGroups().map(C=>e.jsx("tr",{children:C.headers.map(g=>e.jsx("th",{children:g.isPlaceholder?null:Pe(g.column.columnDef.header,g.getContext())},g.id))},C.id))}),e.jsx("tbody",{children:J.getRowModel().rows.map(C=>{const g=C.original,j=`${g.__instance}-${g.artistName}-${g.albumTitle}-${g.trackNumber}`;return e.jsx("tr",{children:C.getVisibleCells().map(q=>e.jsx("td",{"data-label":String(q.column.columnDef.header),children:Pe(q.column.columnDef.cell,q.getContext())},q.id))},j)})})]})}):e.jsx("div",{className:"hint",children:"No tracks found."}),(T?A.length>0:L.length>0)&&e.jsxs("div",{className:"pagination",children:[e.jsx("div",{children:T?e.jsxs(e.Fragment,{children:["Page ",h+1," of ",Math.ceil(K.length/50)," (",K.length," artists · page size 50)"]}):e.jsxs(e.Fragment,{children:["Page ",h+1," of ",Math.ceil(u.length/50)," (",u.length.toLocaleString()," tracks · page size 50)"]})}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>y(Math.max(0,h-1)),disabled:h===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>y(Math.min(Math.ceil(T?K.length/50:u.length/50)-1,h+1)),disabled:h>=Math.ceil(T?K.length/50:u.length/50)-1||r,children:"Next"})]})]})]})}function Is({loading:r,data:t,page:u,totalPages:h,pageSize:y,allAlbums:v,onlyMissing:F,reasonFilter:N,onPageChange:m,onRestart:T,lastUpdated:n,groupLidarr:M,instances:b,selection:B}){const[K,A]=a.useState(0),L=50,ge=a.useMemo(()=>{let f=v;return F&&(f=f.filter(i=>!i.album?.hasFile)),f},[v,F]),J=a.useMemo(()=>N==="all"?ge:N==="Not being searched"?ge.filter(f=>{const i=f.album;return i?.reason==="Not being searched"||!i?.reason}):ge.filter(f=>f.album?.reason===N),[ge,N]),C=a.useMemo(()=>v.length,[v]),g=N!=="all"||F,j=J.length;a.useMemo(()=>{let f=0;return v.forEach(i=>{const x=i.tracks||[];f+=x.length}),f},[v]),a.useMemo(()=>{let f=0;return J.forEach(i=>{const x=i.tracks||[];f+=x.length}),f},[J]),a.useEffect(()=>{A(0)},[F,N]);const q=a.useRef([]),G=a.useRef([]),Q=a.useMemo(()=>{if(J===q.current)return G.current;const f=new Map;J.forEach(x=>{const I=x.album?.artistName||"Unknown Artist";f.has(I)||f.set(I,[]),f.get(I).push(x)});const i=Array.from(f.entries()).map(([x,R])=>{const $=R[0]?.album?.qualityProfileName??null;return{artist:x,albums:R,qualityProfileName:$}});return q.current=J,G.current=i,i},[J]),le=a.useMemo(()=>[{id:"title",header:"Album",cell:f=>f.row.original.album?.title||"Unknown Album"},{id:"artistName",header:"Artist",cell:f=>f.row.original.album?.artistName||"Unknown Artist",size:150},{id:"releaseDate",header:"Release Date",cell:f=>{const x=f.row.original.album?.releaseDate;return x?new Date(x).toLocaleDateString():e.jsx("span",{className:"hint",children:"—"})},size:120},{id:"monitored",header:"Monitored",cell:f=>{const x=f.row.original.album?.monitored;return e.jsx("span",{className:`track-status ${x?"available":"missing"}`,children:x?"✓":"✗"})},size:100},{id:"hasFile",header:"Has File",cell:f=>{const x=f.row.original.album?.hasFile;return e.jsx("span",{className:`track-status ${x?"available":"missing"}`,children:x?"✓":"✗"})},size:100},{id:"qualityProfileName",header:"Quality Profile",cell:f=>f.row.original.album?.qualityProfileName||"—",size:150},{id:"reason",header:"Reason",cell:f=>{const x=f.row.original.album?.reason;return x?e.jsx("span",{className:"table-badge table-badge-reason",children:x}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})},size:120}],[]),te=Math.max(1,Math.ceil(J.length/L)),W=Math.min(K,Math.max(0,te-1)),Z=a.useMemo(()=>J.slice(W*L,(W+1)*L),[J,W]),l=50,[S,D]=a.useState(0),P=Math.max(1,Math.ceil(Q.length/l)),X=Math.min(S,Math.max(0,P-1)),ie=a.useMemo(()=>Q.slice(X*l,(X+1)*l),[Q,X]);a.useEffect(()=>{D(0)},[F,N]);const ee=ze({data:Z,columns:le,getCoreRowModel:Te(),getSortedRowModel:gs()});return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:[t?.counts?e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:"Available:"})," ",(t.counts.available??0).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",(t.counts.monitored??0).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",((t.counts.monitored??0)-(t.counts.available??0)).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total:"})," ",C.toLocaleString(void 0,{maximumFractionDigits:0}),g&&j<C&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",j.toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",C.toLocaleString(void 0,{maximumFractionDigits:0})]})]}):"Loading album information...",n?` (updated ${n})`:""]}),e.jsxs("button",{className:"btn ghost",onClick:T,disabled:r,children:[e.jsx(qe,{src:Ue}),"Restart"]})]}),r?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading…"]}):M?e.jsx("div",{className:"lidarr-hierarchical-view",children:ie.map(f=>{const i=b.find(x=>x.category===B)?.name||B;return e.jsxs("details",{className:"artist-details",children:[e.jsxs("summary",{className:"artist-summary",children:[e.jsx("span",{className:"artist-title",children:f.artist}),e.jsxs("span",{className:"artist-instance",children:["(",i,")"]}),e.jsxs("span",{className:"artist-count",children:["(",f.albums.length," albums)"]}),f.qualityProfileName?e.jsxs("span",{className:"artist-quality",children:["• ",f.qualityProfileName]}):null]}),e.jsx("div",{className:"artist-content",children:f.albums.map(x=>{const R=x.album,I=R?.title||"Unknown Album",$=R?.id||0,U=R?.artistName||"",he=R?.releaseDate,re=R?.monitored,we=R?.hasFile,ye=R?.reason,Re=x.tracks||[],me=x.totals;return e.jsxs("details",{className:"album-details",children:[e.jsxs("summary",{className:"album-summary",children:[e.jsx("span",{className:"album-title",children:I}),he&&e.jsx("span",{className:"album-date",children:new Date(he).toLocaleDateString()}),Re&&Re.length>0&&e.jsxs("span",{className:"album-track-count",children:["(",me.available||0,"/",me.monitored||Re.length," tracks)"]}),e.jsx("span",{className:`album-status ${we?"has-file":"missing"}`,children:we?"✓":"✗"})]}),e.jsx("div",{className:"album-content",children:Re&&Re.length>0?e.jsx("div",{className:"tracks-table-wrapper",children:e.jsxs("table",{className:"tracks-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"#"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Duration"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:Re.map(Y=>e.jsxs("tr",{className:Y.hasFile?"track-available":"track-missing",children:[e.jsx("td",{"data-label":"#",children:Y.trackNumber}),e.jsx("td",{"data-label":"Title",children:Y.title}),e.jsx("td",{"data-label":"Duration",children:Y.duration?`${Math.floor(Y.duration/60)}:${String(Y.duration%60).padStart(2,"0")}`:"—"}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${Y.hasFile?"available":"missing"}`,children:Y.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Reason",children:ye?e.jsx("span",{className:"table-badge table-badge-reason",children:ye}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${$}-${Y.id}`))})]})}):e.jsxs("div",{className:"album-info",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Monitored:"})," ",re?"Yes":"No"," | ",e.jsx("strong",{children:"Has File:"})," ",we?"Yes":"No"]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Reason:"})," ",ye?e.jsx("span",{className:"table-badge table-badge-reason",children:ye}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})]})]})})]},`${U}-${I}`)})})]},f.artist)})}):!M&&v.length?e.jsxs("div",{className:"table-wrapper",children:[e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:ee.getHeaderGroups().map(f=>e.jsx("tr",{children:f.headers.map(i=>e.jsx("th",{children:i.isPlaceholder?null:Pe(i.column.columnDef.header,i.getContext())},i.id))},f.id))}),e.jsx("tbody",{children:ee.getRowModel().rows.map(f=>{const x=f.original.album,R=x?.title||"Unknown",I=x?.artistName||"Unknown",$=`${R}-${I}`;return e.jsx("tr",{children:f.getVisibleCells().map(U=>e.jsx("td",{"data-label":String(U.column.columnDef.header),children:Pe(U.column.columnDef.cell,U.getContext())},U.id))},$)})})]}),te>1&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",W+1," of ",te," (",J.length.toLocaleString()," albums · page size ",L,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>A(Math.max(0,W-1)),disabled:W===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>A(Math.min(te-1,W+1)),disabled:W>=te-1||r,children:"Next"})]})]})]}):e.jsx("div",{className:"hint",children:"No albums found."}),M&&Q.length>0&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",X+1," of ",P," (",Q.length.toLocaleString()," artists · page size ",l,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>D(Math.max(0,X-1)),disabled:X===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>D(Math.min(P-1,X+1)),disabled:X>=P-1||r,children:"Next"})]})]})]})}function _s({active:r}){const{push:t}=is(),{value:u,setValue:h,register:y,clearHandler:v}=rs(),{liveArr:F,groupLidarr:N}=os(),[m,T]=a.useState([]),[n,M]=a.useState(""),[b,B]=a.useState(null),[K,A]=a.useState(0),[L,ge]=a.useState(""),[J,C]=a.useState(!1),[g,j]=a.useState(null),[q,G]=a.useState({}),[Q,le]=a.useState(ns),[te,W]=a.useState(1),Z=a.useRef(""),l=a.useRef({}),S=a.useRef(u),D=a.useRef(!1),P=a.useRef(n),X=_e({getKey:d=>{const p=d.album,s=p?.artistName||"",o=p?.title||"";return`${s}-${o}`},hashFields:["album","tracks","totals"]}),[ie,ee]=a.useState([]),[f,i]=a.useState([]),[x,R]=a.useState(!1),[I,$]=a.useState(0),[U,he]=a.useState(""),[re,we]=a.useState(null),ye=_e({getKey:d=>{const p=d.album,s=p?.artistName||"",o=p?.title||"";return`${d.__instance}-${s}-${o}`},hashFields:["__instance","album","tracks","totals"]}),Re=_e({getKey:d=>`${d.__instance}-${d.artistName}-${d.albumTitle}-${d.trackNumber}`,hashFields:["__instance","artistName","albumTitle","trackNumber","title","hasFile","monitored","reason"]}),[me,Y]=a.useState(!1),[fe,Ae]=a.useState("all"),[be,De]=a.useState({available:0,monitored:0,missing:0,total:0}),pe=a.useCallback(async()=>{try{const d=await cs();d.ready===!1&&!D.current?(D.current=!0,t("Lidarr backend is still initialising. Check the logs if this persists.","info")):d.ready&&(D.current=!0);const p=(d.arr||[]).filter(s=>s.type==="lidarr");if(T(p),!p.length){M("aggregate"),B(null),ee([]),De({available:0,monitored:0,missing:0,total:0});return}n===""?M(p.length===1?p[0].category:"aggregate"):n!=="aggregate"&&!p.some(s=>s.category===n)&&M(p[0].category)}catch(d){t(d instanceof Error?d.message:"Unable to load Lidarr instances","error")}},[t,n]),Se=a.useCallback(async(d,p,s,o,c)=>{if(o.length)try{const E=[];for(const _ of o){const O=await es(d,_,s,p),k=O.page??_;if(E.push({page:k,albums:O.albums??[]}),Z.current!==c)return}if(Z.current!==c)return;G(_=>{const O={..._};let k=!1;for(const{page:z,albums:H}of E){const oe=X.syncData(H);oe.hasChanges&&(O[z]=oe.data,k=!0)}return l.current=O,k?O:_})}catch(E){t(E instanceof Error?E.message:`Failed to load additional pages for ${d}`,"error")}},[t]),Ce=a.useCallback(async(d,p,s,o={})=>{const c=o.preloadAll!==!1;(o.showLoading??!0)&&C(!0);try{const _=`${d}::${s}`,O=Z.current!==_;O&&(Z.current=_,G(()=>(l.current={},{})));const k=await es(d,p,ns,s);B(k);const z=k.page??p;A(z),ge(s);const H=k.page_size??ns,oe=k.total??(k.albums??[]).length,w=Math.max(1,Math.ceil((oe||0)/H));le(H),W(w);const se=k.albums??[],ue=O?{}:l.current,xe=X.syncData(se),ae=xe.hasChanges;if(O&&X.reset(),(O||ae)&&(G(V=>{const je={...O?{}:V,[z]:xe.data};return l.current=je,je}),j(new Date().toLocaleTimeString())),c){const V=[];for(let de=0;de<w;de+=1)de!==z&&(ue[de]||V.push(de));Se(d,s,H,V,_)}}catch(_){t(_ instanceof Error?_.message:`Failed to load ${d} albums`,"error")}finally{C(!1)}},[t,Se]),Ne=a.useCallback(async d=>{if(!m.length){ee([]),De({available:0,monitored:0,missing:0,total:0});return}(d?.showLoading??!0)&&R(!0);try{const s=[];let o=0,c=0;for(const w of m){let se=0,ue=!1;const xe=w.name||w.category;for(;se<100;){const ae=await es(w.category,se,xs,"");if(console.log("=== Lidarr API Response ==="),console.log("Instance:",w.category),console.log("Response:",ae),console.log("Albums count:",ae.albums?.length),ae.albums&&ae.albums.length>0&&(console.log("First album entry:",ae.albums[0]),console.log("First album.album:",ae.albums[0].album),console.log("First album.totals:",ae.albums[0].totals),console.log("First album.tracks:",ae.albums[0].tracks)),console.log("========================="),!ue){const de=ae.counts;de&&(o+=de.available??0,c+=de.monitored??0),ue=!0}const V=ae.albums??[];if(V.forEach(de=>{s.push({...de,__instance:xe})}),!V.length||V.length<xs)break;se+=1}}const E=[];s.forEach(w=>{const se=w.album,ue=se?.artistName||"Unknown Artist",xe=se?.title||"Unknown Album",ae=se?.reason,V=se?.qualityProfileId,de=se?.qualityProfileName,je=w.tracks||[];je&&je.length>0&&je.forEach(ce=>{E.push({__instance:w.__instance,artistName:ue,albumTitle:xe,trackNumber:ce.trackNumber||0,title:ce.title||"Unknown Track",duration:ce.duration,hasFile:ce.hasFile||!1,monitored:ce.monitored||!1,reason:ae,qualityProfileId:V,qualityProfileName:de})})});const _=ye.syncData(s),O=_.hasChanges,k=Re.syncData(E),z=k.hasChanges;O&&ee(_.data),z&&i(k.data);const H=N?{available:o,monitored:c,missing:s.length-o,total:s.length}:{available:E.filter(w=>w.hasFile).length,monitored:E.filter(w=>w.monitored).length,missing:E.filter(w=>!w.hasFile).length,total:E.length},oe=be.available!==H.available||be.monitored!==H.monitored||be.missing!==H.missing||be.total!==H.total;oe&&De(H),U!==u&&($(0),he(u)),(O||oe)&&we(new Date().toLocaleTimeString())}catch(s){ee([]),De({available:0,monitored:0,missing:0,total:0}),t(s instanceof Error?s.message:"Failed to load aggregated Lidarr data","error")}finally{R(!1)}},[m,u,t,U,N]);a.useEffect(()=>{r&&pe()},[r,pe]),a.useEffect(()=>{if(!r||!n||n==="aggregate")return;const d=P.current!==n;d&&(l.current={},G({}),W(1),A(0),P.current=n);const p=S.current;Ce(n,d?0:K,p,{preloadAll:!0,showLoading:!0})},[r,n,Ce,K]),a.useEffect(()=>{r&&n==="aggregate"&&Ne()},[r,n,Ne]),Ke(()=>{n==="aggregate"&&F&&Ne({showLoading:!1})},n==="aggregate"&&F?1e3:null),a.useEffect(()=>{if(!r)return;const d=p=>{n==="aggregate"?(he(p),$(0)):n&&(A(0),Ce(n,0,p,{preloadAll:!0,showLoading:!0}))};return y(d),()=>{v(d)}},[r,n,y,v,Ce]),Ke(()=>{if(n&&n!=="aggregate"){if(S.current?.trim?.()||"")return;Ce(n,K,L,{preloadAll:!1,showLoading:!1})}},r&&n&&n!=="aggregate"&&F?1e3:null),a.useEffect(()=>{S.current=u},[u]),a.useEffect(()=>{n==="aggregate"&&he(u)},[n,u]);const Fe=a.useMemo(()=>{let d=ie;if(U){const p=U.toLowerCase();d=d.filter(s=>{const o=s.album,c=(o?.title??"").toString().toLowerCase(),E=(o?.artistName??"").toString().toLowerCase(),_=(s.__instance??"").toLowerCase();return c.includes(p)||E.includes(p)||_.includes(p)})}return me&&(d=d.filter(p=>!p.album?.hasFile)),fe!=="all"&&(fe==="Not being searched"?d=d.filter(p=>{const s=p.album;return s?.reason==="Not being searched"||!s?.reason}):d=d.filter(p=>p.album?.reason===fe)),d},[ie,U,me,fe]),Oe=!!U||fe!=="all",He=a.useMemo(()=>{let d=f;if(U){const p=U.toLowerCase();d=d.filter(s=>s.artistName.toLowerCase().includes(p)||s.albumTitle.toLowerCase().includes(p)||s.title.toLowerCase().includes(p)||s.__instance.toLowerCase().includes(p))}return me&&(d=d.filter(p=>!p.hasFile)),fe!=="all"&&(fe==="Not being searched"?d=d.filter(p=>p.reason==="Not being searched"||!p.reason):d=d.filter(p=>p.reason===fe)),d},[f,U,me,fe]),$e=a.useMemo(()=>{const d=Object.keys(q).map(Number).sort((s,o)=>s-o),p=[];return d.forEach(s=>{q[s]&&p.push(...q[s])}),p},[q]),Ve=a.useMemo(()=>q[K]??[],[q,K]),Qe=a.useCallback(async()=>{if(!(!n||n==="aggregate"))try{await ds(n),t(`Restarted ${n}`,"success")}catch(d){t(d instanceof Error?d.message:`Failed to restart ${n}`,"error")}},[n,t]),We=a.useCallback(d=>{const p=d.target.value||"aggregate";M(p),p!=="aggregate"&&h("")},[M,h]),Ie=n==="aggregate";return e.jsxs("section",{className:"card",children:[e.jsx("div",{className:"card-header",children:"Lidarr"}),e.jsx("div",{className:"card-body",children:e.jsxs("div",{className:"split",children:[e.jsxs("aside",{className:"pane sidebar",children:[m.length>1&&e.jsx("button",{className:`btn ${Ie?"active":""}`,onClick:()=>M("aggregate"),children:"All Lidarr"}),m.map(d=>e.jsx("button",{className:`btn ghost ${n===d.category?"active":""}`,onClick:()=>{M(d.category),h("")},children:d.name||d.category},d.category))]}),e.jsxs("div",{className:"pane",children:[e.jsxs("div",{className:"field mobile-instance-select",children:[e.jsx("label",{children:"Instance"}),e.jsxs("select",{value:n||"aggregate",onChange:We,disabled:!m.length,children:[m.length>1&&e.jsx("option",{value:"aggregate",children:"All Lidarr"}),m.map(d=>e.jsx("option",{value:d.category,children:d.name||d.category},d.category))]})]}),e.jsxs("div",{className:"row",style:{alignItems:"flex-end",gap:"12px",flexWrap:"wrap"},children:[e.jsxs("div",{className:"col field",style:{flex:"1 1 200px"},children:[e.jsx("label",{children:"Search"}),e.jsx("input",{placeholder:"Filter albums",value:u,onChange:d=>h(d.target.value)})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Status"}),e.jsxs("select",{onChange:d=>{const p=d.target.value;Y(p==="missing")},value:me?"missing":"all",children:[e.jsx("option",{value:"all",children:"All Albums"}),e.jsx("option",{value:"missing",children:"Missing Only"})]})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Search Reason"}),e.jsxs("select",{onChange:d=>Ae(d.target.value),value:fe,children:[e.jsx("option",{value:"all",children:"All Reasons"}),e.jsx("option",{value:"Not being searched",children:"Not Being Searched"}),e.jsx("option",{value:"Missing",children:"Missing"}),e.jsx("option",{value:"Quality",children:"Quality"}),e.jsx("option",{value:"CustomFormat",children:"Custom Format"}),e.jsx("option",{value:"Upgrade",children:"Upgrade"})]})]})]}),Ie?e.jsx(Es,{loading:x,rows:Fe,trackRows:He,page:I,onPageChange:$,onRefresh:()=>void Ne({showLoading:!0}),lastUpdated:re,summary:be,instanceCount:m.length,groupLidarr:N,isAggFiltered:Oe}):e.jsx(Is,{loading:J,data:b,page:K,totalPages:te,pageSize:Q,allAlbums:N?Ve:$e,onlyMissing:me,reasonFilter:fe,onPageChange:d=>{A(d),Ce(n,d,L,{preloadAll:!0})},onRestart:()=>void Qe(),lastUpdated:g,groupLidarr:N,instances:m,selection:n})]})]})})]})}function Us({type:r,active:t}){return r==="radarr"?e.jsx(As,{active:t}):r==="lidarr"?e.jsx(_s,{active:t}):e.jsx($s,{active:t})}export{Us as ArrView};
|
|
1
|
+
import{j as e,u as is,h as rs,i as os,k as cs,l as Je,m as ds,I as qe,R as Ue,n as Xe,o as es}from"./app.js";import{r as a,u as ze,g as Te,f as Pe,a as gs,b as vs,c as ys}from"./table.js";import{u as Ke}from"./useInterval.js";import"./vendor.js";function Ss({data:r,columns:t,getRowKey:u}){const h=ze({data:r,columns:t,getCoreRowModel:Te()});return e.jsx("div",{className:"table-wrapper",children:e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:h.getHeaderGroups().map(y=>e.jsx("tr",{children:y.headers.map(v=>e.jsx("th",{children:v.isPlaceholder?null:Pe(v.column.columnDef.header,v.getContext())},v.id))},y.id))}),e.jsx("tbody",{children:h.getRowModel().rows.map(y=>{const v=u?u(y.original):y.id;return e.jsx("tr",{children:y.getVisibleCells().map(F=>e.jsx("td",{"data-label":String(F.column.columnDef.header),children:Pe(F.column.columnDef.cell,F.getContext())},F.id))},v)})})]})})}const Rs=a.memo(Ss,(r,t)=>r.data===t.data&&r.columns===t.columns);function Cs(r){let t=2166136261;for(let u=0;u<r.length;u++)t^=r.charCodeAt(u),t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24);return(t>>>0).toString(36)}function ls(r,t){const u=t.map(h=>{const y=r[h];return y==null?"":typeof y=="boolean"?y?"1":"0":typeof y=="object"?JSON.stringify(y):String(y)});return Cs(u.join("|"))}function ws(r,t,u,h){const y=[],v=[],F=[],N=new Set;for(const n of t){const M=u(n),b=ls(n,h);N.add(M);const B=r.byId.get(M),K=r.byHash.get(M);B?K!==b&&v.push(n):y.push(n)}for(const n of r.allIds)N.has(n)||F.push(n);const m=t.length-y.length-v.length,T=y.length>0||v.length>0||F.length>0;return{added:y,updated:v,removed:F,unchanged:m,hasChanges:T}}function Fs(r,t,u,h){if(!t.hasChanges)return r;const y=new Map(r.byId),v=new Map(r.byHash),F=[...r.allIds];for(const N of t.added){const m=u(N),T=ls(N,h);y.set(m,N),v.set(m,T),F.push(m)}for(const N of t.updated){const m=u(N),T=ls(N,h);y.set(m,N),v.set(m,T)}for(const N of t.removed){y.delete(N),v.delete(N);const m=F.indexOf(N);m!==-1&&F.splice(m,1)}return{byId:y,byHash:v,allIds:F,lastUpdate:Date.now()}}function ss(r){return r.allIds.map(t=>r.byId.get(t)).filter(Boolean)}function ms(){return{byId:new Map,byHash:new Map,allIds:[],lastUpdate:0}}function _e(r){const{getKey:t,hashFields:u}=r,h=a.useRef(ms()),[y,v]=a.useState(0),F=a.useCallback(T=>{const n=ws(h.current,T,t,u);if(!n.hasChanges)return{data:ss(h.current),hasChanges:!1,changes:null,lastUpdate:h.current.lastUpdate};const M=Fs(h.current,n,t,u);return h.current=M,v(M.lastUpdate),{data:ss(M),hasChanges:!0,changes:n,lastUpdate:M.lastUpdate}},[t,u]),N=a.useCallback(()=>ss(h.current),[]),m=a.useCallback(()=>{h.current=ms(),v(0)},[]);return{syncData:F,getData:N,reset:m,lastUpdate:y}}const as=50,Be=50,fs=500,Ms=a.memo(function({loading:t,rows:u,total:h,page:y,totalPages:v,onPageChange:F,onRefresh:N,lastUpdated:m,sort:T,onSort:n,summary:M,instanceCount:b,isAggFiltered:B=!1}){const K=a.useMemo(()=>[...b>1?[{accessorKey:"__instance",header:"Instance",size:150}]:[],{accessorKey:"title",header:"Title",cell:A=>A.getValue()},{accessorKey:"year",header:"Year",size:80},{accessorKey:"monitored",header:"Monitored",cell:A=>{const L=A.getValue();return e.jsx("span",{className:`track-status ${L?"available":"missing"}`,children:L?"✓":"✗"})},size:100},{accessorKey:"hasFile",header:"Has File",cell:A=>{const L=A.getValue();return e.jsx("span",{className:`track-status ${L?"available":"missing"}`,children:L?"✓":"✗"})},size:100},{accessorKey:"qualityProfileName",header:"Quality Profile",cell:A=>A.getValue()||"—",size:150},{accessorKey:"reason",header:"Reason",cell:A=>{const L=A.getValue();return L?e.jsx("span",{className:"table-badge table-badge-reason",children:L}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})},size:120}],[b]);return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:["Aggregated movies across all instances"," ",m?`(updated ${m})`:"",e.jsx("br",{}),e.jsx("strong",{children:"Available:"})," ",M.available.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",M.monitored.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",M.missing.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total:"})," ",M.total.toLocaleString(void 0,{maximumFractionDigits:0}),B&&h<M.total&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",h.toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",M.total.toLocaleString(void 0,{maximumFractionDigits:0})]})]}),e.jsxs("button",{className:"btn ghost",onClick:N,disabled:t,children:[e.jsx(qe,{src:Ue}),"Refresh"]})]}),t?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading Radarr library…"]}):h?e.jsx(Rs,{data:u,columns:K,getRowKey:A=>`${A.__instance}-${A.title}-${A.year}`}):e.jsx("div",{className:"hint",children:"No movies found."}),h>0&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",y+1," of ",v," (",h.toLocaleString()," items · page size"," ",Be,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>F(Math.max(0,y-1)),disabled:y===0||t,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>F(Math.min(v-1,y+1)),disabled:y>=v-1||t,children:"Next"})]})]})]})}),Ps=a.memo(function({loading:t,data:u,page:h,totalPages:y,pageSize:v,allMovies:F,onlyMissing:N,reasonFilter:m,onPageChange:T,onRefresh:n,onRestart:M,lastUpdated:b}){const B=a.useMemo(()=>{let g=F;return N&&(g=g.filter(j=>!j.hasFile)),g},[F,N]),K=a.useMemo(()=>m==="all"?B:m==="Not being searched"?B.filter(g=>g.reason==="Not being searched"||!g.reason):B.filter(g=>g.reason===m),[B,m]),A=a.useMemo(()=>F.length,[F]),L=m!=="all"||N,ge=K.length,J=a.useMemo(()=>[{accessorKey:"title",header:"Title",cell:g=>g.getValue()},{accessorKey:"year",header:"Year",size:80},{accessorKey:"monitored",header:"Monitored",cell:g=>{const j=g.getValue();return e.jsx("span",{className:`track-status ${j?"available":"missing"}`,children:j?"✓":"✗"})},size:100},{accessorKey:"hasFile",header:"Has File",cell:g=>{const j=g.getValue();return e.jsx("span",{className:`track-status ${j?"available":"missing"}`,children:j?"✓":"✗"})},size:100},{accessorKey:"qualityProfileName",header:"Quality Profile",cell:g=>g.getValue()||"—",size:150},{accessorKey:"reason",header:"Reason",cell:g=>{const j=g.getValue();return j?e.jsx("span",{className:"table-badge table-badge-reason",children:j}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})},size:120}],[]),C=ze({data:K.slice(h*v,h*v+v),columns:J,getCoreRowModel:Te(),getSortedRowModel:gs()});return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:[u?.counts?e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:"Available:"})," ",(u.counts.available??0).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",(u.counts.monitored??0).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",((u.counts.monitored??0)-(u.counts.available??0)).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total:"})," ",A.toLocaleString(void 0,{maximumFractionDigits:0}),L&&ge<A&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",ge.toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",A.toLocaleString(void 0,{maximumFractionDigits:0})]})]}):"Loading movie information...",b?` (updated ${b})`:""]}),e.jsxs("button",{className:"btn ghost",onClick:M,disabled:t,children:[e.jsx(qe,{src:Ue}),"Restart"]})]}),t?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading…"]}):F.length?e.jsx("div",{className:"table-wrapper",children:e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:C.getHeaderGroups().map(g=>e.jsx("tr",{children:g.headers.map(j=>e.jsx("th",{children:j.isPlaceholder?null:Pe(j.column.columnDef.header,j.getContext())},j.id))},g.id))}),e.jsx("tbody",{children:C.getRowModel().rows.map(g=>{const j=g.original,q=`${j.title}-${j.year}`;return e.jsx("tr",{children:g.getVisibleCells().map(G=>e.jsx("td",{"data-label":String(G.column.columnDef.header),children:Pe(G.column.columnDef.cell,G.getContext())},G.id))},q)})})]})}):e.jsx("div",{className:"hint",children:"No movies found."}),K.length>v&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",h+1," of ",y," (",K.length.toLocaleString()," items · page size"," ",v,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>T(Math.max(0,h-1)),disabled:h===0||t,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>T(Math.min(y-1,h+1)),disabled:h>=y-1||t,children:"Next"})]})]})]})});function As({active:r}){const{push:t}=is(),{value:u,setValue:h,register:y,clearHandler:v}=rs(),{liveArr:F,setLiveArr:N}=os(),[m,T]=a.useState([]),[n,M]=a.useState(""),[b,B]=a.useState(null),[K,A]=a.useState(0),[L,ge]=a.useState(""),[J,C]=a.useState(!1),[g,j]=a.useState(null),[q,G]=a.useState({}),[Q,le]=a.useState(as),[te,W]=a.useState(1),Z=a.useRef(""),l=a.useRef({}),S=a.useRef(u),D=a.useRef(!1),P=_e({getKey:s=>`${s.title}-${s.year}`,hashFields:["title","year","hasFile","monitored","reason"]}),[X,ie]=a.useState([]),[ee,f]=a.useState(!1),[i,x]=a.useState(0),[R,I]=a.useState(""),[$,U]=a.useState(null),he=_e({getKey:s=>`${s.__instance}-${s.title}-${s.year}`,hashFields:["__instance","title","year","hasFile","monitored","reason"]}),[re,we]=a.useState({key:"__instance",direction:"asc"}),[ye,Re]=a.useState(!1),[me,Y]=a.useState("all"),[fe,Ae]=a.useState({available:0,monitored:0,missing:0,total:0}),be=a.useCallback(async()=>{try{const s=await cs();s.ready===!1&&!D.current?(D.current=!0,t("Radarr backend is still initialising. Check the logs if this persists.","info")):s.ready&&(D.current=!0);const o=(s.arr||[]).filter(c=>c.type==="radarr");if(T(o),!o.length){M("aggregate"),B(null),ie([]),Ae({available:0,monitored:0,missing:0,total:0});return}n===""?M(o.length===1?o[0].category:"aggregate"):n!=="aggregate"&&!o.some(c=>c.category===n)&&M(o[0].category)}catch(s){t(s instanceof Error?s.message:"Unable to load Radarr instances","error")}},[t,n]),De=a.useCallback(async(s,o,c,E,_)=>{if(E.length)try{const O=[];for(const k of E){const z=await Je(s,k,c,o),H=z.page??k;if(O.push({page:H,movies:z.movies??[]}),Z.current!==_)return}if(Z.current!==_)return;G(k=>{const z={...k};let H=!1;for(const{page:oe,movies:w}of O){const se=P.syncData(w);se.hasChanges&&(z[oe]=se.data,H=!0)}return l.current=z,H?z:k})}catch(O){t(O instanceof Error?O.message:`Failed to load additional pages for ${s}`,"error")}},[t]),pe=a.useCallback(async(s,o,c,E={})=>{const _=E.preloadAll!==!1;(E.showLoading??!0)&&C(!0);try{const k=`${s}::${c}`,z=Z.current!==k;z&&(Z.current=k,G(()=>(l.current={},{})));const H=await Je(s,o,as,c);B(H);const oe=H.page??o;A(oe),ge(c);const w=H.page_size??as,se=H.total??(H.movies??[]).length,ue=Math.max(1,Math.ceil((se||0)/w));le(w),W(ue);const xe=H.movies??[],ae=z?{}:l.current,V=P.syncData(xe),de=V.hasChanges;if(z&&P.reset(),(z||de)&&(G(je=>{const Ee={...z?{}:je,[oe]:V.data};return l.current=Ee,Ee}),j(new Date().toLocaleTimeString())),_){const je=[];for(let ce=0;ce<ue;ce+=1)ce!==oe&&(ae[ce]||je.push(ce));De(s,c,w,je,k)}}catch(k){t(k instanceof Error?k.message:`Failed to load ${s} movies`,"error")}finally{C(!1)}},[t,De]),Se=a.useCallback(async s=>{if(!m.length){ie([]),Ae({available:0,monitored:0,missing:0,total:0});return}(s?.showLoading??!0)&&f(!0);try{const c=[];let E=0,_=0;for(const oe of m){let w=0,se=!1;const ue=oe.name||oe.category;for(;w<100;){const xe=await Je(oe.category,w,fs,"");if(!se){const V=xe.counts;V&&(E+=V.available??0,_+=V.monitored??0),se=!0}const ae=xe.movies??[];if(ae.forEach(V=>{c.push({...V,__instance:ue})}),!ae.length||ae.length<fs)break;w+=1}}const O=he.syncData(c),k=O.hasChanges;k&&ie(O.data);const z={available:E,monitored:_,missing:c.length-E,total:c.length},H=fe.available!==z.available||fe.monitored!==z.monitored||fe.missing!==z.missing||fe.total!==z.total;H&&Ae(z),R!==u&&(x(0),I(u)),(k||H)&&U(new Date().toLocaleTimeString())}catch(c){ie([]),Ae({available:0,monitored:0,missing:0,total:0}),t(c instanceof Error?c.message:"Failed to load aggregated Radarr data","error")}finally{f(!1)}},[m,u,t,R]);a.useEffect(()=>{r&&be()},[r,be]),a.useEffect(()=>{if(!r||!n||n==="aggregate")return;l.current={},G({}),W(1),A(0);const s=S.current;pe(n,0,s,{preloadAll:!0,showLoading:!0})},[r,n,pe]),a.useEffect(()=>{r&&n==="aggregate"&&Se()},[r,n,Se]),Ke(()=>{n==="aggregate"&&F&&Se({showLoading:!1})},n==="aggregate"&&F?1e3:null),a.useEffect(()=>{if(!r)return;const s=o=>{n==="aggregate"?(I(o),x(0)):n&&(A(0),pe(n,0,o,{preloadAll:!0,showLoading:!0}))};return y(s),()=>{v(s)}},[r,n,y,v,pe]),Ke(()=>{if(n&&n!=="aggregate"){if(S.current?.trim?.()||"")return;pe(n,K,L,{preloadAll:!1,showLoading:!1})}},r&&n&&n!=="aggregate"&&F?1e3:null),a.useEffect(()=>{S.current=u},[u]),a.useEffect(()=>{n==="aggregate"&&I(u)},[n,u]);const Ce=a.useMemo(()=>{let s=X;if(R){const o=R.toLowerCase();s=s.filter(c=>{const E=(c.title??"").toString().toLowerCase(),_=(c.__instance??"").toLowerCase();return E.includes(o)||_.includes(o)})}return ye&&(s=s.filter(o=>!o.hasFile)),me!=="all"&&(me==="Not being searched"?s=s.filter(o=>o.reason==="Not being searched"||!o.reason):s=s.filter(o=>o.reason===me)),s},[X,R,ye,me]),Ne=!!R||me!=="all",Fe=a.useMemo(()=>{const s=[...Ce],o=(c,E)=>{switch(E){case"__instance":return(c.__instance||"").toLowerCase();case"title":return(c.title||"").toLowerCase();case"year":return c.year??0;case"monitored":return c.monitored?1:0;case"hasFile":return c.hasFile?1:0;default:return""}};return s.sort((c,E)=>{const _=o(c,re.key),O=o(E,re.key);let k=0;return typeof _=="number"&&typeof O=="number"?k=_-O:typeof _=="string"&&typeof O=="string"?k=_.localeCompare(O):k=String(_).localeCompare(String(O)),re.direction==="asc"?k:-k}),s},[Ce,re]),Oe=Math.max(1,Math.ceil(Fe.length/Be)),He=a.useMemo(()=>Fe.slice(i*Be,i*Be+Be),[Fe,i]),$e=a.useMemo(()=>{const s=Object.keys(q).map(Number).sort((c,E)=>c-E),o=[];return s.forEach(c=>{q[c]&&o.push(...q[c])}),o},[q]),Ve=a.useCallback(async()=>{if(!(!n||n==="aggregate"))try{await ds(n),t(`Restarted ${n}`,"success")}catch(s){t(s instanceof Error?s.message:`Failed to restart ${n}`,"error")}},[n,t]),Qe=a.useCallback(()=>{Se({showLoading:!0})},[Se]),We=a.useCallback(s=>{we(o=>o.key===s?{key:s,direction:o.direction==="asc"?"desc":"asc"}:{key:s,direction:"asc"})},[]),Ie=a.useCallback(()=>{n&&n!=="aggregate"&&pe(n,K,L,{preloadAll:!1,showLoading:!0})},[n,K,L,pe]),d=a.useCallback(s=>{const o=s.target.value||"aggregate";M(o),o!=="aggregate"&&h("")},[M,h]),p=n==="aggregate";return e.jsxs("section",{className:"card",children:[e.jsx("div",{className:"card-header",children:"Radarr"}),e.jsx("div",{className:"card-body",children:e.jsxs("div",{className:"split",children:[e.jsxs("aside",{className:"pane sidebar",children:[m.length>1&&e.jsx("button",{className:`btn ${p?"active":""}`,onClick:()=>M("aggregate"),children:"All Radarr"}),m.map(s=>e.jsx("button",{className:`btn ghost ${n===s.category?"active":""}`,onClick:()=>{M(s.category),h("")},children:s.name||s.category},s.category))]}),e.jsxs("div",{className:"pane",children:[e.jsxs("div",{className:"field mobile-instance-select",children:[e.jsx("label",{children:"Instance"}),e.jsxs("select",{value:n||"aggregate",onChange:d,disabled:!m.length,children:[m.length>1&&e.jsx("option",{value:"aggregate",children:"All Radarr"}),m.map(s=>e.jsx("option",{value:s.category,children:s.name||s.category},s.category))]})]}),e.jsxs("div",{className:"row",style:{alignItems:"flex-end",gap:"12px",flexWrap:"wrap"},children:[e.jsxs("div",{className:"col field",style:{flex:"1 1 200px"},children:[e.jsx("label",{children:"Search"}),e.jsx("input",{placeholder:"Filter movies",value:u,onChange:s=>h(s.target.value)})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Status"}),e.jsxs("select",{onChange:s=>{const o=s.target.value;Re(o==="missing")},value:ye?"missing":"all",children:[e.jsx("option",{value:"all",children:"All Movies"}),e.jsx("option",{value:"missing",children:"Missing Only"})]})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Search Reason"}),e.jsxs("select",{onChange:s=>Y(s.target.value),value:me,children:[e.jsx("option",{value:"all",children:"All Reasons"}),e.jsx("option",{value:"Not being searched",children:"Not Being Searched"}),e.jsx("option",{value:"Missing",children:"Missing"}),e.jsx("option",{value:"Quality",children:"Quality"}),e.jsx("option",{value:"CustomFormat",children:"Custom Format"}),e.jsx("option",{value:"Upgrade",children:"Upgrade"})]})]})]}),p?e.jsx(Ms,{loading:ee,rows:He,total:Fe.length,page:i,totalPages:Oe,onPageChange:x,onRefresh:Qe,lastUpdated:$,sort:re,onSort:We,summary:fe,instanceCount:m.length,isAggFiltered:Ne}):e.jsx(Ps,{loading:J,data:b,page:K,totalPages:te,pageSize:Q,allMovies:$e,onlyMissing:ye,reasonFilter:me,onPageChange:s=>{A(s),pe(n,s,L,{preloadAll:!0})},onRefresh:Ie,onRestart:()=>{Ve()},lastUpdated:g})]})]})})]})}const ts=25,Ge=50,bs=200;function Ds(r,t){if(!t)return r;const u=[];for(const h of r){const y=h.seasons??{},v={};for(const[F,N]of Object.entries(y)){const m=(N.episodes??[]).filter(T=>!T.hasFile);m.length&&(v[F]={...N,episodes:m})}Object.keys(v).length!==0&&u.push({...h,seasons:v})}return u}function Ye(r,t){return JSON.stringify(Ds(r,t))}function $s({active:r}){const{push:t}=is(),{value:u,setValue:h,register:y,clearHandler:v}=rs(),{liveArr:F,setLiveArr:N,groupSonarr:m,setGroupSonarr:T}=os(),[n,M]=a.useState([]),[b,B]=a.useState(""),[K,A]=a.useState(null),[L,ge]=a.useState(0),[J,C]=a.useState(""),[g,j]=a.useState(!1),[q,G]=a.useState(null),[Q,le]=a.useState({}),te=a.useRef({}),W=a.useRef(null),Z=a.useRef(""),[l,S]=a.useState(ts),[D,P]=a.useState(1),[X,ie]=a.useState(0),ee=a.useRef(u),f=a.useRef(!1),i=a.useRef(b),[x,R]=a.useState([]),[I,$]=a.useState(!1),[U,he]=a.useState(0),[re,we]=a.useState(""),[ye,Re]=a.useState(null),me=_e({getKey:s=>`${s.__instance}-${s.series}-${s.season}-${s.episode}`,hashFields:["__instance","series","season","episode","title","hasFile","monitored","airDate","reason","qualityProfileId","qualityProfileName"]}),[Y,fe]=a.useState(!1),Ae=a.useRef(Y),[be,De]=a.useState("all"),[pe,Se]=a.useState({available:0,monitored:0,missing:0,total:0}),Ce=a.useCallback(async()=>{try{const s=await cs();s.ready===!1&&!f.current?(f.current=!0,t("Sonarr backend is still initialising. Check the logs if this persists.","info")):s.ready&&(f.current=!0);const o=(s.arr||[]).filter(c=>c.type==="sonarr");if(M(o),!o.length){B("aggregate"),A(null),R([]),Se({available:0,monitored:0,missing:0,total:0});return}b===""?B(o.length===1?o[0].category:"aggregate"):b!=="aggregate"&&!o.some(c=>c.category===b)&&B(o[0].category)}catch(s){t(s instanceof Error?s.message:"Unable to load Sonarr instances","error")}},[t,b]),Ne=a.useCallback(async(s,o,c,E={})=>{const{preloadAll:_=!0,showLoading:O=!0,missingOnly:k}=E,z=k??Y;O&&j(!0);try{const H=`${s}::${c}::${z?"missing":"all"}`,oe=Z.current!==H;oe&&(Z.current=H,le(()=>(te.current={},{})),ie(0),P(1));const w=await Xe(s,o,ts,c,{missingOnly:z});console.log(`[Sonarr Instance] Response for ${s} page ${o}:`,{total:w.total,page:w.page,page_size:w.page_size,series_count:w.series?.length??0,counts:w.counts,missingOnly:z,firstSeries:w.series?.[0]?{title:w.series[0].series?.title,seasonsCount:Object.keys(w.series[0].seasons??{}).length,firstSeasonEpisodes:Object.values(w.series[0].seasons??{})[0]?.episodes?.length??0}:null});const se=w.page??o,ue=w.page_size??ts,xe=w.total??(w.series??[]).length,ae=Math.max(1,Math.ceil((xe||0)/ue)),V=w.series??[],de=oe?{}:te.current,je={...de,[se]:V},ce=Ye(de[se]??[],z),Ee=Ye(V,z),ke=oe||ce!==Ee;if(te.current=je,ke&&le(je),A(ne=>{const ve=ne?.counts??null,Le=w.counts??null;return!ne||ne.total!==w.total||ne.page!==w.page||ne.page_size!==w.page_size||(ve?.available??null)!==(Le?.available??null)||(ve?.monitored??null)!==(Le?.monitored??null)||(ve?.missing??null)!==(Le?.missing??null)||ke?(W.current=w,w):ne}),ge(ne=>ne===se?ne:se),C(ne=>ne===c?ne:c),S(ne=>ne===ue?ne:ue),P(ne=>ne===ae?ne:ae),ie(ne=>ne===xe?ne:xe),ke&&G(new Date().toLocaleTimeString()),_){const ne=[];for(let ve=0;ve<ae;ve+=1)ve!==se&&(je[ve]||ne.push(ve));for(const ve of ne)try{const Le=await Xe(s,ve,ue,c,{missingOnly:z});if(Z.current!==H)break;const Me=Le.page??ve,Ze=Le.series??[],us=te.current,js=Ye(us[Me]??[],z),ps=Ye(Ze,z);if(js===ps){te.current={...us,[Me]:Ze};continue}le(Ns=>{const hs={...Ns,[Me]:Ze};return te.current=hs,hs})}catch{break}}}catch(H){t(H instanceof Error?H.message:`Failed to load ${s} series`,"error")}finally{O&&j(!1)}},[t,Y]),Fe=a.useCallback(async s=>{if(!n.length){R([]),Se({available:0,monitored:0,missing:0,total:0});return}console.log(`[Sonarr Aggregate] Starting aggregation for ${n.length} instances`),(s?.showLoading??!0)&&$(!0);try{const c=[];let E=0,_=0,O=0;for(const se of n){let ue=0,xe=!1;const ae=se.name||se.category;for(console.log(`[Sonarr Aggregate] Processing instance: ${ae}`);ue<200;){const V=await Xe(se.category,ue,bs,"",{missingOnly:Y});if(console.log(`[Sonarr Aggregate] Response for ${ae} page ${ue}:`,{total:V.total,page:V.page,page_size:V.page_size,series_count:V.series?.length??0,counts:V.counts,missingOnly:Y,firstSeries:V.series?.[0]?{title:V.series[0].series?.title,seasonsCount:Object.keys(V.series[0].seasons??{}).length,firstSeasonEpisodes:Object.values(V.series[0].seasons??{})[0]?.episodes?.length??0,firstEpisode:Object.values(V.series[0].seasons??{})[0]?.episodes?.[0]}:null}),!xe){const ce=V.counts;ce&&(E+=ce.available??0,_+=ce.monitored??0,O+=ce.missing??0),xe=!0}const de=V.series??[];let je=0;if(de.forEach(ce=>{const Ee=Object.keys(ce.seasons??{}).length;let ke=0;Object.values(ce.seasons??{}).forEach(ne=>{ke+=(ne.episodes??[]).length}),je+=ke}),console.log(`[Sonarr Aggregate] Instance: ${ae}, Page: ${ue}, Series count: ${de.length}, Total episodes so far: ${c.length}, Episodes in this response: ${je}`),de.forEach(ce=>{const Ee=ce.series?.title||"",ke=ce.series?.qualityProfileId??null,ne=ce.series?.qualityProfileName??null;Object.entries(ce.seasons??{}).forEach(([ve,Le])=>{(Le.episodes??[]).forEach(Me=>{const Ze=Me.reason??null;c.push({__instance:ae,series:Ee,season:ve,episode:Me.episodeNumber??"",title:Me.title??"",monitored:!!Me.monitored,hasFile:!!Me.hasFile,airDate:Me.airDateUtc??"",reason:Ze,qualityProfileId:ke,qualityProfileName:ne})})})}),!de.length||de.length<bs){console.log(`[Sonarr Aggregate] Breaking pagination for ${ae} - series.length=${de.length}`);break}ue+=1}}const k=me.syncData(c),z=k.hasChanges,H=new Map;c.forEach(se=>{const ue=se.reason||"null/empty";H.set(ue,(H.get(ue)||0)+1)}),console.log("[Sonarr Aggregate] Reason distribution:",Object.fromEntries(H)),z?(console.log(`[Sonarr Aggregate] Data changed, updating from ${x.length} to ${c.length} episodes`),R(k.data)):console.log("[Sonarr Aggregate] Data unchanged, skipping update");const oe={available:E,monitored:_,missing:O,total:c.length},w=pe.available!==oe.available||pe.monitored!==oe.monitored||pe.missing!==oe.missing||pe.total!==oe.total;w&&Se(oe),re!==u&&(he(0),we(u)),(z||w)&&Re(new Date().toLocaleTimeString())}catch(c){R([]),Se({available:0,monitored:0,missing:0,total:0}),t(c instanceof Error?c.message:"Failed to load aggregated Sonarr data","error")}finally{$(!1)}},[n,u,t,Y,re]);a.useEffect(()=>{r&&Ce()},[r,Ce]),a.useEffect(()=>{if(!r||!b||b==="aggregate")return;const s=i.current!==b,o=Ae.current!==Y;s&&(ge(0),i.current=b),o&&(Ae.current=Y);const c=ee.current;Ne(b,s?0:L,c,{preloadAll:!0,showLoading:!0,missingOnly:Y})},[r,b,Y,Ne,L]),a.useEffect(()=>{r&&b==="aggregate"&&Fe()},[r,b,Fe]),Ke(()=>{b==="aggregate"&&F&&Fe({showLoading:!1})},b==="aggregate"&&F?1e3:null),a.useEffect(()=>{if(!r)return;const s=o=>{b==="aggregate"?(we(o),he(0)):b&&(ge(0),Ne(b,0,o,{preloadAll:!0,showLoading:!0,missingOnly:Y}))};return y(s),()=>v(s)},[r,b,y,v,Ne,Y]),Ke(()=>{if(b&&b!=="aggregate"){if(ee.current?.trim?.()||"")return;Ne(b,L,J,{preloadAll:!1,showLoading:!1,missingOnly:Y})}},r&&b&&b!=="aggregate"&&F?1e3:null),a.useEffect(()=>{ee.current=u},[u]),a.useEffect(()=>{b==="aggregate"&&we(u)},[b,u]);const Oe=a.useMemo(()=>{let s=x;if(re){const o=re.toLowerCase();s=s.filter(c=>c.series.toLowerCase().includes(o)||c.title.toLowerCase().includes(o)||c.__instance.toLowerCase().includes(o))}if(Y&&(s=s.filter(o=>!o.hasFile)),be!=="all"){console.log(`[Sonarr Filter] Applying reason filter: "${be}"`);const o=s.length;be==="Not being searched"?s=s.filter(c=>c.reason==="Not being searched"||!c.reason):s=s.filter(c=>c.reason===be),console.log(`[Sonarr Filter] Filtered from ${o} to ${s.length} episodes for reason "${be}"`),s.length<10&&console.log("[Sonarr Filter] Sample filtered rows:",s.slice(0,5).map(c=>({series:c.series,episode:c.episode,reason:c.reason})))}return s},[x,re,Y,be]),He=!!re||Y||be!=="all",$e=Oe,Ve=Math.max(1,Math.ceil($e.length/Ge));a.useMemo(()=>$e.slice(U*Ge,U*Ge+Ge),[$e,U]);const Qe=Q[L]??[],We=a.useMemo(()=>{const s=Object.keys(Q).map(Number).sort((c,E)=>c-E),o=[];return s.forEach(c=>{Q[c]&&o.push(...Q[c])}),o},[Q]),Ie=a.useCallback(async()=>{if(!(!b||b==="aggregate"))try{await ds(b),t(`Restarted ${b}`,"success")}catch(s){t(s instanceof Error?s.message:`Failed to restart ${b}`,"error")}},[b,t]),d=a.useCallback(s=>{const o=s.target.value||"aggregate";B(o),o!=="aggregate"&&h("")},[B,h]),p=b==="aggregate";return e.jsxs("section",{className:"card",children:[e.jsx("div",{className:"card-header",children:"Sonarr"}),e.jsx("div",{className:"card-body",children:e.jsxs("div",{className:"split",children:[e.jsxs("aside",{className:"pane sidebar",children:[n.length>1&&e.jsx("button",{className:`btn ${p?"active":""}`,onClick:()=>B("aggregate"),children:"All Sonarr"}),n.map(s=>e.jsx("button",{className:`btn ghost ${b===s.category?"active":""}`,onClick:()=>{B(s.category),h("")},children:s.name||s.category},s.category))]}),e.jsxs("div",{className:"pane",children:[e.jsxs("div",{className:"field mobile-instance-select",children:[e.jsx("label",{children:"Instance"}),e.jsxs("select",{value:b||"aggregate",onChange:d,disabled:!n.length,children:[n.length>1&&e.jsx("option",{value:"aggregate",children:"All Sonarr"}),n.map(s=>e.jsx("option",{value:s.category,children:s.name||s.category},s.category))]})]}),e.jsxs("div",{className:"row",style:{alignItems:"flex-end",gap:"12px",flexWrap:"wrap"},children:[e.jsxs("div",{className:"col field",style:{flex:"1 1 200px"},children:[e.jsx("label",{children:"Search"}),e.jsx("input",{placeholder:"Filter series or episodes",value:u,onChange:s=>h(s.target.value)})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Status"}),e.jsxs("select",{onChange:s=>{const c=s.target.value==="missing";fe(c),b&&b!=="aggregate"&&Ne(b,0,ee.current||"",{preloadAll:!0,showLoading:!0,missingOnly:c})},value:Y?"missing":"all",children:[e.jsx("option",{value:"all",children:"All Episodes"}),e.jsx("option",{value:"missing",children:"Missing Only"})]})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Search Reason"}),e.jsxs("select",{onChange:s=>De(s.target.value),value:be,children:[e.jsx("option",{value:"all",children:"All Reasons"}),e.jsx("option",{value:"Not being searched",children:"Not Being Searched"}),e.jsx("option",{value:"Missing",children:"Missing"}),e.jsx("option",{value:"Quality",children:"Quality"}),e.jsx("option",{value:"CustomFormat",children:"Custom Format"}),e.jsx("option",{value:"Upgrade",children:"Upgrade"})]})]})]}),p?e.jsx(ks,{loading:I,rows:$e,total:$e.length,page:U,totalPages:Ve,onPageChange:he,onRefresh:()=>{Fe({showLoading:!0})},lastUpdated:ye,groupSonarr:m,summary:pe,instanceCount:n.length,isAggFiltered:He}):e.jsx(Ls,{loading:g,counts:K?.counts??null,series:m?Qe:We,page:L,pageSize:l,totalPages:D,totalItems:X,onlyMissing:Y,reasonFilter:be,onPageChange:s=>{ge(s),Ne(b,s,J,{preloadAll:!1,showLoading:!0,missingOnly:Y})},onRestart:()=>{Ie()},lastUpdated:q,groupSonarr:m,instances:n,selection:b})]})]})})]})}function ks({loading:r,rows:t,total:u,page:h,totalPages:y,onPageChange:v,onRefresh:F,lastUpdated:N,groupSonarr:m,summary:T,instanceCount:n,isAggFiltered:M=!1}){const b=a.useRef([]),B=a.useRef([]),K=a.useRef(new Map),A=a.useMemo(()=>{if(t===b.current)return B.current;const l=new Map;t.forEach(P=>{const X=P.__instance,ie=P.series,ee=String(P.season);l.has(X)||l.set(X,new Map);const f=l.get(X);f.has(ie)||f.set(ie,new Map);const i=f.get(ie);i.has(ee)||i.set(ee,[]),i.get(ee).push(P)});const S=[],D=new Map;return l.forEach((P,X)=>{P.forEach((ie,ee)=>{const f=`${X}-${ee}`,i=new Set;ie.forEach(($,U)=>{$.forEach(he=>{const re=`${U}-${he.episode}`;i.add(re)})});const x=K.current.get(f);if(x&&x.episodeKeys.size===i.size){let $=!0;for(const U of i)if(!x.episodeKeys.has(U)){$=!1;break}if($){S.push(x),D.set(f,x);return}}const R=Array.from(ie.values())[0]?.[0];console.log(`[Sonarr Grouped] Series: ${ee}, QualityProfile: ${R?.qualityProfileName}, FirstEpisode:`,R);const I={instance:X,series:ee,qualityProfileId:R?.qualityProfileId,qualityProfileName:R?.qualityProfileName,subRows:Array.from(ie.entries()).map(([$,U])=>({seasonNumber:$,isSeason:!0,subRows:U.map(he=>({...he,isEpisode:!0}))})),episodeKeys:i};S.push(I),D.set(f,I)})}),b.current=t,B.current=S,K.current=D,S},[t]),L=a.useMemo(()=>A.slice(h*50,(h+1)*50),[A,h]),ge=a.useMemo(()=>t.slice(h*50,(h+1)*50),[t,h]),J=m?L:ge,C=a.useMemo(()=>[{accessorKey:"title",header:"Title",cell:({row:l})=>{if(l.original.isEpisode)return l.original.title;if(l.original.isSeason)return`Season ${l.original.seasonNumber}`;const S=[l.original.series];return l.original.instance&&S.push(`(${l.original.instance})`),l.original.qualityProfileName&&S.push(`• ${l.original.qualityProfileName}`),S.join(" ")}},{accessorKey:"monitored",header:"Monitored",cell:({row:l})=>{const S=(l.original.isEpisode,l.original.monitored);return e.jsx("span",{className:`track-status ${S?"available":"missing"}`,children:S?"✓":"✗"})}},{accessorKey:"hasFile",header:"Has File",cell:({row:l})=>{if(l.original.isEpisode){const S=l.original.hasFile;return e.jsx("span",{className:`track-status ${S?"available":"missing"}`,children:S?"✓":"✗"})}return null}},{accessorKey:"airDate",header:"Air Date",cell:({row:l})=>l.original.isEpisode?l.original.airDate||"—":null}],[]),g=a.useMemo(()=>[...n>1?[{accessorKey:"__instance",header:"Instance"}]:[],{accessorKey:"series",header:"Series"},{accessorKey:"season",header:"Season"},{accessorKey:"episode",header:"Episode"},{accessorKey:"title",header:"Title"},{accessorKey:"monitored",header:"Monitored",cell:({getValue:l})=>{const S=l();return e.jsx("span",{className:`track-status ${S?"available":"missing"}`,children:S?"✓":"✗"})}},{accessorKey:"hasFile",header:"Has File",cell:({getValue:l})=>{const S=l();return e.jsx("span",{className:`track-status ${S?"available":"missing"}`,children:S?"✓":"✗"})}},{accessorKey:"airDate",header:"Air Date",cell:({getValue:l})=>l()||"—"},{accessorKey:"qualityProfileName",header:"Quality Profile",cell:({getValue:l})=>l()||"—"},{accessorKey:"reason",header:"Reason",cell:({getValue:l})=>{const S=l();return S?e.jsx("span",{className:"table-badge table-badge-reason",children:S}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})}}],[n]),j=m?C:g,q=ze({data:J,columns:j,getCoreRowModel:Te(),getExpandedRowModel:vs()}),G=ze({data:J,columns:j,getCoreRowModel:Te(),getSortedRowModel:gs(),getPaginationRowModel:ys(),state:{pagination:{pageIndex:h,pageSize:50}},manualPagination:!0,pageCount:y}),Q=m?q:G,le=50,te=Math.ceil(m?A.length/le:t.length/le),W=Math.min(h,Math.max(0,te-1)),Z=m?`${A.length} series`:t.length.toLocaleString();return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:["Aggregated episodes across all instances"," ",N?`(updated ${N})`:"",e.jsx("br",{}),e.jsx("strong",{children:"Available:"})," ",T.available.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",T.monitored.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",T.missing.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total Episodes:"})," ",T.total.toLocaleString(void 0,{maximumFractionDigits:0}),M&&t.length<T.total&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",t.length.toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",T.total.toLocaleString(void 0,{maximumFractionDigits:0})]})]}),e.jsxs("button",{className:"btn ghost",onClick:F,disabled:r,children:[e.jsx(qe,{src:Ue}),"Refresh"]})]}),r?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading Sonarr library…"]}):m?e.jsx("div",{className:"sonarr-hierarchical-view",children:L.map(l=>{console.log(`[Sonarr Render] Series: ${l.series}, QualityProfile: ${l.qualityProfileName}`);let S=0;return l.subRows.forEach(D=>{S+=D.subRows.length}),e.jsxs("details",{className:"series-details",children:[e.jsxs("summary",{className:"series-summary",children:[e.jsx("span",{className:"series-title",children:l.series}),e.jsxs("span",{className:"series-instance",children:["(",l.instance,")"]}),e.jsxs("span",{className:"series-count",children:["(",S," episodes)"]}),l.qualityProfileName?e.jsxs("span",{className:"series-quality",children:["• ",l.qualityProfileName]}):null]}),e.jsx("div",{className:"series-content",children:l.subRows.map(D=>e.jsxs("details",{className:"season-details",children:[e.jsxs("summary",{className:"season-summary",children:[e.jsxs("span",{className:"season-title",children:["Season ",D.seasonNumber]}),e.jsxs("span",{className:"season-count",children:["(",D.subRows.length," episodes)"]})]}),e.jsx("div",{className:"season-content",children:e.jsx("div",{className:"episodes-table-wrapper",children:e.jsxs("table",{className:"episodes-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Episode"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Monitored"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Air Date"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:D.subRows.map(P=>e.jsxs("tr",{children:[e.jsx("td",{"data-label":"Episode",children:P.episode}),e.jsx("td",{"data-label":"Title",children:P.title}),e.jsx("td",{"data-label":"Monitored",children:e.jsx("span",{className:`track-status ${P.monitored?"available":"missing"}`,children:P.monitored?"✓":"✗"})}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${P.hasFile?"available":"missing"}`,children:P.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Air Date",children:P.airDate||"—"}),e.jsx("td",{"data-label":"Reason",children:P.reason?e.jsx("span",{className:"table-badge table-badge-reason",children:P.reason}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${P.__instance}-${P.series}-${P.season}-${P.episode}`))})]})})})]},`${l.instance}-${l.series}-${D.seasonNumber}`))})]},`${l.instance}-${l.series}`)})}):!r&&T.total===0&&n>0?e.jsxs("div",{className:"hint",children:[e.jsx("p",{children:"No episodes found in the database."}),e.jsx("p",{children:"The backend may still be initializing and syncing data from your Sonarr instances. Please check the logs or wait a few moments and refresh."})]}):J.length?e.jsx("div",{className:"table-wrapper",children:e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:e.jsx("tr",{children:Q.getFlatHeaders().map(l=>e.jsxs("th",{className:l.column.getCanSort()?"sortable":"",onClick:l.column.getToggleSortingHandler(),children:[l.isPlaceholder?null:Pe(l.column.columnDef.header,l.getContext()),l.column.getCanSort()&&e.jsx("span",{className:"sort-arrow",children:{asc:"▲",desc:"▼"}[l.column.getIsSorted()]??null})]},l.id))})}),e.jsx("tbody",{children:Q.getRowModel().rows.map(l=>{const S=l.original,D=`${S.__instance}-${S.series}-${S.season}-${S.episode}`;return e.jsx("tr",{children:l.getVisibleCells().map(P=>e.jsx("td",{"data-label":P.column.columnDef.header,children:Pe(P.column.columnDef.cell,P.getContext())},P.id))},D)})})]})}):e.jsx("div",{className:"hint",children:"No series found."}),J.length>0&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",W+1," of ",te," (",Z," items · page size ",le,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>v(Math.max(0,W-1)),disabled:W===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>v(Math.min(te-1,W+1)),disabled:W>=te-1||r,children:"Next"})]})]})]})}function Ls({loading:r,counts:t,series:u,page:h,pageSize:y,totalPages:v,totalItems:F,onlyMissing:N,reasonFilter:m,onPageChange:T,onRestart:n,lastUpdated:M,groupSonarr:b,instances:B,selection:K}){const[A,L]=a.useState(0),ge=50,J=a.useRef([]),C=a.useRef([]),g=a.useMemo(()=>{if(u===J.current)return C.current;const i=[];for(const x of u){const R=x.series?.title||"",I=x.series?.qualityProfileId??null,$=x.series?.qualityProfileName??null;Object.entries(x.seasons??{}).forEach(([U,he])=>{(he.episodes??[]).forEach(re=>{i.push({__instance:"Instance",series:R,season:U,episode:re.episodeNumber??"",title:re.title??"",monitored:!!re.monitored,hasFile:!!re.hasFile,airDate:re.airDateUtc??"",reason:re.reason??null,qualityProfileId:I,qualityProfileName:$})})})}return J.current=u,C.current=i,i},[u]),j=a.useMemo(()=>{let i=g;if(N&&(i=i.filter(x=>!x.hasFile)),m!=="all"){console.log(`[Sonarr Instance Filter] Applying reason filter: "${m}"`);const x=i.length;m==="Not being searched"?i=i.filter(R=>R.reason==="Not being searched"||!R.reason):i=i.filter(R=>R.reason===m),console.log(`[Sonarr Instance Filter] Filtered from ${x} to ${i.length} episodes for reason "${m}"`),i.length<10&&console.log("[Sonarr Instance Filter] Sample filtered rows:",i.slice(0,5).map(R=>({series:R.series,episode:R.episode,reason:R.reason})))}return i},[g,N,m]);a.useEffect(()=>{L(0)},[N,m]);const q=a.useRef([]),G=a.useRef([]),Q=a.useMemo(()=>{if(j===q.current)return G.current;const i=new Map;j.forEach(R=>{const I=R.series;i.has(I)||i.set(I,new Map);const $=i.get(I),U=String(R.season);$.has(U)||$.set(U,[]),$.get(U).push(R)});const x=Array.from(i.entries()).map(([R,I])=>{const $=Array.from(I.values())[0]?.[0];return{series:R,qualityProfileId:$?.qualityProfileId,qualityProfileName:$?.qualityProfileName,subRows:Array.from(I.entries()).map(([U,he])=>({seasonNumber:U,isSeason:!0,subRows:he.map(re=>({...re,isEpisode:!0}))}))}});return q.current=j,G.current=x,x},[j]),le=a.useMemo(()=>g.length,[g]),te=m!=="all"||N,W=j.length,Z=Math.max(1,Math.ceil(j.length/ge)),l=Math.min(A,Math.max(0,Z-1)),S=a.useMemo(()=>j.slice(l*ge,(l+1)*ge),[j,l]),D=50,[P,X]=a.useState(0),ie=Math.max(1,Math.ceil(Q.length/D)),ee=Math.min(P,Math.max(0,ie-1)),f=a.useMemo(()=>Q.slice(ee*D,(ee+1)*D),[Q,ee]);return a.useEffect(()=>{X(0)},[N,m]),e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:[t?e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:"Available:"})," ",t.available.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",t.monitored.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",(t.missing??0).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total Episodes:"})," ",le.toLocaleString(void 0,{maximumFractionDigits:0}),te&&W<le&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",W.toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",le.toLocaleString(void 0,{maximumFractionDigits:0})]})]}):"Loading series information...",M?` (updated ${M})`:""]}),e.jsxs("button",{className:"btn ghost",onClick:n,disabled:r,children:[e.jsx(qe,{src:Ue}),"Restart"]})]}),r?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading series…"]}):b?e.jsx("div",{className:"sonarr-hierarchical-view",children:f.map(i=>{let x=0;i.subRows.forEach(I=>{x+=I.subRows.length});const R=B.find(I=>I.category===K)?.name||K;return e.jsxs("details",{className:"series-details",children:[e.jsxs("summary",{className:"series-summary",children:[e.jsx("span",{className:"series-title",children:i.series}),e.jsxs("span",{className:"series-instance",children:["(",R,")"]}),e.jsxs("span",{className:"series-count",children:["(",x," episodes)"]}),i.qualityProfileName?e.jsxs("span",{className:"series-quality",children:["• ",i.qualityProfileName]}):null]}),e.jsx("div",{className:"series-content",children:i.subRows.map(I=>e.jsxs("details",{className:"season-details",children:[e.jsxs("summary",{className:"season-summary",children:[e.jsxs("span",{className:"season-title",children:["Season ",I.seasonNumber]}),e.jsxs("span",{className:"season-count",children:["(",I.subRows.length," episodes)"]})]}),e.jsx("div",{className:"season-content",children:e.jsx("div",{className:"episodes-table-wrapper",children:e.jsxs("table",{className:"episodes-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Episode"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Monitored"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Air Date"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:I.subRows.map($=>e.jsxs("tr",{children:[e.jsx("td",{"data-label":"Episode",children:$.episode}),e.jsx("td",{"data-label":"Title",children:$.title}),e.jsx("td",{"data-label":"Monitored",children:e.jsx("span",{className:`track-status ${$.monitored?"available":"missing"}`,children:$.monitored?"✓":"✗"})}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${$.hasFile?"available":"missing"}`,children:$.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Air Date",children:$.airDate||"—"}),e.jsx("td",{"data-label":"Reason",children:$.reason?e.jsx("span",{className:"table-badge table-badge-reason",children:$.reason}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${$.series}-${$.season}-${$.episode}`))})]})})})]},`${i.series}-${I.seasonNumber}`))})]},`${i.series}`)})}):!r&&u.length>0&&j.length===0&&g.length===0?e.jsxs("div",{className:"hint",children:[e.jsx("p",{children:"No episodes found for these series."}),e.jsx("p",{children:"The backend may still be syncing episode data from Sonarr. Please check the logs or wait a few moments and refresh."})]}):!r&&u.length>0&&j.length===0&&g.length>0?e.jsx("div",{className:"hint",children:"No episodes match the current filter."}):!b&&j.length>0?e.jsxs("div",{className:"table-wrapper",children:[e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Series"}),e.jsx("th",{children:"Season"}),e.jsx("th",{children:"Episode"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Monitored"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Air Date"}),e.jsx("th",{children:"Quality Profile"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:S.map((i,x)=>e.jsxs("tr",{children:[e.jsx("td",{"data-label":"Series",children:i.series}),e.jsx("td",{"data-label":"Season",children:i.season}),e.jsx("td",{"data-label":"Episode",children:i.episode}),e.jsx("td",{"data-label":"Title",children:i.title}),e.jsx("td",{"data-label":"Monitored",children:e.jsx("span",{className:`track-status ${i.monitored?"available":"missing"}`,children:i.monitored?"✓":"✗"})}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${i.hasFile?"available":"missing"}`,children:i.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Air Date",children:i.airDate||"—"}),e.jsx("td",{"data-label":"Quality Profile",children:i.qualityProfileName||"—"}),e.jsx("td",{"data-label":"Reason",children:i.reason?e.jsx("span",{className:"table-badge table-badge-reason",children:i.reason}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${i.series}-${i.season}-${i.episode}-${x}`))})]}),Z>1&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",l+1," of ",Z," (",j.length.toLocaleString()," episodes · page size ",ge,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>L(Math.max(0,l-1)),disabled:l===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>L(Math.min(Z-1,l+1)),disabled:l>=Z-1||r,children:"Next"})]})]})]}):e.jsx("div",{className:"hint",children:"No series found."}),b&&Q.length>0&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",ee+1," of ",ie," (",Q.length.toLocaleString()," series · page size ",D,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>X(Math.max(0,ee-1)),disabled:ee===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>X(Math.min(ie-1,ee+1)),disabled:ee>=ie-1||r,children:"Next"})]})]})]})}const ns=50,xs=500;function Es({loading:r,rows:t,trackRows:u,page:h,onPageChange:y,onRefresh:v,lastUpdated:F,summary:N,instanceCount:m,groupLidarr:T,isAggFiltered:n=!1}){const M=a.useRef([]),b=a.useRef([]),B=a.useRef(new Map),K=a.useMemo(()=>{if(t===M.current)return b.current;const C=new Map;t.forEach(q=>{const G=q.__instance,Q=q.album?.artistName||"Unknown Artist";C.has(G)||C.set(G,new Map);const le=C.get(G);le.has(Q)||le.set(Q,[]),le.get(Q).push(q)});const g=[],j=new Map;return C.forEach((q,G)=>{q.forEach((Q,le)=>{const te=`${G}-${le}`,W=new Set;Q.forEach(P=>{const ie=`${P.album?.title}`;W.add(ie)});const Z=B.current.get(te);if(Z&&Z.albumKeys.size===W.size){let P=!0;for(const X of W)if(!Z.albumKeys.has(X)){P=!1;break}if(P){g.push(Z),j.set(te,Z);return}}const S=Q[0]?.album,D={instance:G,artist:le,qualityProfileId:S?.qualityProfileId??null,qualityProfileName:S?.qualityProfileName??null,albums:Q,albumKeys:W};g.push(D),j.set(te,D)})}),M.current=t,b.current=g,B.current=j,g},[t]),A=a.useMemo(()=>K.slice(h*50,(h+1)*50),[K,h]),L=a.useMemo(()=>{const g=h*50,j=g+50;return u.slice(g,j)},[u,h]),ge=a.useMemo(()=>[...m>1?[{accessorKey:"__instance",header:"Instance",size:120}]:[],{accessorKey:"artistName",header:"Artist",size:150},{accessorKey:"albumTitle",header:"Album",size:150},{accessorKey:"trackNumber",header:"#",size:50},{accessorKey:"title",header:"Track"},{accessorKey:"duration",header:"Duration",cell:C=>{const g=C.getValue();return g?`${Math.floor(g/60)}:${String(g%60).padStart(2,"0")}`:e.jsx("span",{className:"hint",children:"—"})},size:80},{accessorKey:"monitored",header:"Monitored",cell:C=>{const g=C.getValue();return e.jsx("span",{className:`track-status ${g?"available":"missing"}`,children:g?"✓":"✗"})},size:100},{accessorKey:"hasFile",header:"Has File",cell:C=>{const g=C.getValue();return e.jsx("span",{className:`track-status ${g?"available":"missing"}`,children:g?"✓":"✗"})},size:100},{accessorKey:"qualityProfileName",header:"Quality Profile",cell:C=>C.getValue()||"—",size:150},{accessorKey:"reason",header:"Reason",cell:C=>{const g=C.getValue();return g?e.jsx("span",{className:"table-badge table-badge-reason",children:g}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})},size:120}],[m]),J=ze({data:L,columns:ge,getCoreRowModel:Te()});return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:["Aggregated albums across all instances"," ",F?`(updated ${F})`:"",e.jsx("br",{}),e.jsx("strong",{children:"Available:"})," ",N.available.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",N.monitored.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",N.missing.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total:"})," ",N.total.toLocaleString(void 0,{maximumFractionDigits:0}),n&&(T?t.length:u.length)<N.total&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",(T?t.length:u.length).toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",N.total.toLocaleString(void 0,{maximumFractionDigits:0})]})]}),e.jsxs("button",{className:"btn ghost",onClick:v,disabled:r,children:[e.jsx(qe,{src:Ue}),"Refresh"]})]}),r?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading Lidarr library…"]}):T?e.jsx("div",{className:"lidarr-hierarchical-view",children:A.map(C=>e.jsxs("details",{className:"artist-details",children:[e.jsxs("summary",{className:"artist-summary",children:[e.jsx("span",{className:"artist-title",children:C.artist}),e.jsxs("span",{className:"artist-instance",children:["(",C.instance,")"]}),e.jsxs("span",{className:"artist-count",children:["(",C.albums.length," albums)"]}),C.qualityProfileName?e.jsxs("span",{className:"artist-quality",children:["• ",C.qualityProfileName]}):null]}),e.jsx("div",{className:"artist-content",children:C.albums.map(g=>{const j=g.album,q=j?.title||"Unknown Album",G=j?.id||0,Q=j?.artistName||"",le=j?.releaseDate,te=j?.monitored,W=j?.hasFile,Z=j?.reason,l=g.tracks||[],S=g.totals;return e.jsxs("details",{className:"album-details",children:[e.jsxs("summary",{className:"album-summary",children:[e.jsx("span",{className:"album-title",children:q}),le&&e.jsx("span",{className:"album-date",children:new Date(le).toLocaleDateString()}),l&&l.length>0&&e.jsxs("span",{className:"album-track-count",children:["(",S.available||0,"/",S.monitored||l.length," tracks)"]}),e.jsx("span",{className:`album-status ${W?"has-file":"missing"}`,children:W?"✓":"✗"})]}),e.jsx("div",{className:"album-content",children:l&&l.length>0?e.jsx("div",{className:"tracks-table-wrapper",children:e.jsxs("table",{className:"tracks-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"#"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Duration"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:l.map(D=>e.jsxs("tr",{className:D.hasFile?"track-available":"track-missing",children:[e.jsx("td",{"data-label":"#",children:D.trackNumber}),e.jsx("td",{"data-label":"Title",children:D.title}),e.jsx("td",{"data-label":"Duration",children:D.duration?`${Math.floor(D.duration/60)}:${String(D.duration%60).padStart(2,"0")}`:"—"}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${D.hasFile?"available":"missing"}`,children:D.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Reason",children:Z?e.jsx("span",{className:"table-badge table-badge-reason",children:Z}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${G}-${D.id}`))})]})}):e.jsxs("div",{className:"album-info",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Monitored:"})," ",te?"Yes":"No"," | ",e.jsx("strong",{children:"Has File:"})," ",W?"Yes":"No"]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Reason:"})," ",Z?e.jsx("span",{className:"table-badge table-badge-reason",children:Z}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})]})]})})]},`${g.__instance}-${Q}-${q}`)})})]},`${C.instance}-${C.artist}`))}):u.length?e.jsx("div",{className:"table-wrapper",children:e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:J.getHeaderGroups().map(C=>e.jsx("tr",{children:C.headers.map(g=>e.jsx("th",{children:g.isPlaceholder?null:Pe(g.column.columnDef.header,g.getContext())},g.id))},C.id))}),e.jsx("tbody",{children:J.getRowModel().rows.map(C=>{const g=C.original,j=`${g.__instance}-${g.artistName}-${g.albumTitle}-${g.trackNumber}`;return e.jsx("tr",{children:C.getVisibleCells().map(q=>e.jsx("td",{"data-label":String(q.column.columnDef.header),children:Pe(q.column.columnDef.cell,q.getContext())},q.id))},j)})})]})}):e.jsx("div",{className:"hint",children:"No tracks found."}),(T?A.length>0:L.length>0)&&e.jsxs("div",{className:"pagination",children:[e.jsx("div",{children:T?e.jsxs(e.Fragment,{children:["Page ",h+1," of ",Math.ceil(K.length/50)," (",K.length," artists · page size 50)"]}):e.jsxs(e.Fragment,{children:["Page ",h+1," of ",Math.ceil(u.length/50)," (",u.length.toLocaleString()," tracks · page size 50)"]})}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>y(Math.max(0,h-1)),disabled:h===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>y(Math.min(Math.ceil(T?K.length/50:u.length/50)-1,h+1)),disabled:h>=Math.ceil(T?K.length/50:u.length/50)-1||r,children:"Next"})]})]})]})}function Is({loading:r,data:t,page:u,totalPages:h,pageSize:y,allAlbums:v,onlyMissing:F,reasonFilter:N,onPageChange:m,onRestart:T,lastUpdated:n,groupLidarr:M,instances:b,selection:B}){const[K,A]=a.useState(0),L=50,ge=a.useMemo(()=>{let f=v;return F&&(f=f.filter(i=>!i.album?.hasFile)),f},[v,F]),J=a.useMemo(()=>N==="all"?ge:N==="Not being searched"?ge.filter(f=>{const i=f.album;return i?.reason==="Not being searched"||!i?.reason}):ge.filter(f=>f.album?.reason===N),[ge,N]),C=a.useMemo(()=>v.length,[v]),g=N!=="all"||F,j=J.length;a.useMemo(()=>{let f=0;return v.forEach(i=>{const x=i.tracks||[];f+=x.length}),f},[v]),a.useMemo(()=>{let f=0;return J.forEach(i=>{const x=i.tracks||[];f+=x.length}),f},[J]),a.useEffect(()=>{A(0)},[F,N]);const q=a.useRef([]),G=a.useRef([]),Q=a.useMemo(()=>{if(J===q.current)return G.current;const f=new Map;J.forEach(x=>{const I=x.album?.artistName||"Unknown Artist";f.has(I)||f.set(I,[]),f.get(I).push(x)});const i=Array.from(f.entries()).map(([x,R])=>{const $=R[0]?.album?.qualityProfileName??null;return{artist:x,albums:R,qualityProfileName:$}});return q.current=J,G.current=i,i},[J]),le=a.useMemo(()=>[{id:"title",header:"Album",cell:f=>f.row.original.album?.title||"Unknown Album"},{id:"artistName",header:"Artist",cell:f=>f.row.original.album?.artistName||"Unknown Artist",size:150},{id:"releaseDate",header:"Release Date",cell:f=>{const x=f.row.original.album?.releaseDate;return x?new Date(x).toLocaleDateString():e.jsx("span",{className:"hint",children:"—"})},size:120},{id:"monitored",header:"Monitored",cell:f=>{const x=f.row.original.album?.monitored;return e.jsx("span",{className:`track-status ${x?"available":"missing"}`,children:x?"✓":"✗"})},size:100},{id:"hasFile",header:"Has File",cell:f=>{const x=f.row.original.album?.hasFile;return e.jsx("span",{className:`track-status ${x?"available":"missing"}`,children:x?"✓":"✗"})},size:100},{id:"qualityProfileName",header:"Quality Profile",cell:f=>f.row.original.album?.qualityProfileName||"—",size:150},{id:"reason",header:"Reason",cell:f=>{const x=f.row.original.album?.reason;return x?e.jsx("span",{className:"table-badge table-badge-reason",children:x}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})},size:120}],[]),te=Math.max(1,Math.ceil(J.length/L)),W=Math.min(K,Math.max(0,te-1)),Z=a.useMemo(()=>J.slice(W*L,(W+1)*L),[J,W]),l=50,[S,D]=a.useState(0),P=Math.max(1,Math.ceil(Q.length/l)),X=Math.min(S,Math.max(0,P-1)),ie=a.useMemo(()=>Q.slice(X*l,(X+1)*l),[Q,X]);a.useEffect(()=>{D(0)},[F,N]);const ee=ze({data:Z,columns:le,getCoreRowModel:Te(),getSortedRowModel:gs()});return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:[t?.counts?e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:"Available:"})," ",(t.counts.available??0).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",(t.counts.monitored??0).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",((t.counts.monitored??0)-(t.counts.available??0)).toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total:"})," ",C.toLocaleString(void 0,{maximumFractionDigits:0}),g&&j<C&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",j.toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",C.toLocaleString(void 0,{maximumFractionDigits:0})]})]}):"Loading album information...",n?` (updated ${n})`:""]}),e.jsxs("button",{className:"btn ghost",onClick:T,disabled:r,children:[e.jsx(qe,{src:Ue}),"Restart"]})]}),r?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading…"]}):M?e.jsx("div",{className:"lidarr-hierarchical-view",children:ie.map(f=>{const i=b.find(x=>x.category===B)?.name||B;return e.jsxs("details",{className:"artist-details",children:[e.jsxs("summary",{className:"artist-summary",children:[e.jsx("span",{className:"artist-title",children:f.artist}),e.jsxs("span",{className:"artist-instance",children:["(",i,")"]}),e.jsxs("span",{className:"artist-count",children:["(",f.albums.length," albums)"]}),f.qualityProfileName?e.jsxs("span",{className:"artist-quality",children:["• ",f.qualityProfileName]}):null]}),e.jsx("div",{className:"artist-content",children:f.albums.map(x=>{const R=x.album,I=R?.title||"Unknown Album",$=R?.id||0,U=R?.artistName||"",he=R?.releaseDate,re=R?.monitored,we=R?.hasFile,ye=R?.reason,Re=x.tracks||[],me=x.totals;return e.jsxs("details",{className:"album-details",children:[e.jsxs("summary",{className:"album-summary",children:[e.jsx("span",{className:"album-title",children:I}),he&&e.jsx("span",{className:"album-date",children:new Date(he).toLocaleDateString()}),Re&&Re.length>0&&e.jsxs("span",{className:"album-track-count",children:["(",me.available||0,"/",me.monitored||Re.length," tracks)"]}),e.jsx("span",{className:`album-status ${we?"has-file":"missing"}`,children:we?"✓":"✗"})]}),e.jsx("div",{className:"album-content",children:Re&&Re.length>0?e.jsx("div",{className:"tracks-table-wrapper",children:e.jsxs("table",{className:"tracks-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"#"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Duration"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:Re.map(Y=>e.jsxs("tr",{className:Y.hasFile?"track-available":"track-missing",children:[e.jsx("td",{"data-label":"#",children:Y.trackNumber}),e.jsx("td",{"data-label":"Title",children:Y.title}),e.jsx("td",{"data-label":"Duration",children:Y.duration?`${Math.floor(Y.duration/60)}:${String(Y.duration%60).padStart(2,"0")}`:"—"}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${Y.hasFile?"available":"missing"}`,children:Y.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Reason",children:ye?e.jsx("span",{className:"table-badge table-badge-reason",children:ye}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${$}-${Y.id}`))})]})}):e.jsxs("div",{className:"album-info",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Monitored:"})," ",re?"Yes":"No"," | ",e.jsx("strong",{children:"Has File:"})," ",we?"Yes":"No"]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Reason:"})," ",ye?e.jsx("span",{className:"table-badge table-badge-reason",children:ye}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})]})]})})]},`${U}-${I}`)})})]},f.artist)})}):!M&&v.length?e.jsxs("div",{className:"table-wrapper",children:[e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:ee.getHeaderGroups().map(f=>e.jsx("tr",{children:f.headers.map(i=>e.jsx("th",{children:i.isPlaceholder?null:Pe(i.column.columnDef.header,i.getContext())},i.id))},f.id))}),e.jsx("tbody",{children:ee.getRowModel().rows.map(f=>{const x=f.original.album,R=x?.title||"Unknown",I=x?.artistName||"Unknown",$=`${R}-${I}`;return e.jsx("tr",{children:f.getVisibleCells().map(U=>e.jsx("td",{"data-label":String(U.column.columnDef.header),children:Pe(U.column.columnDef.cell,U.getContext())},U.id))},$)})})]}),te>1&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",W+1," of ",te," (",J.length.toLocaleString()," albums · page size ",L,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>A(Math.max(0,W-1)),disabled:W===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>A(Math.min(te-1,W+1)),disabled:W>=te-1||r,children:"Next"})]})]})]}):e.jsx("div",{className:"hint",children:"No albums found."}),M&&Q.length>0&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",X+1," of ",P," (",Q.length.toLocaleString()," artists · page size ",l,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>D(Math.max(0,X-1)),disabled:X===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>D(Math.min(P-1,X+1)),disabled:X>=P-1||r,children:"Next"})]})]})]})}function _s({active:r}){const{push:t}=is(),{value:u,setValue:h,register:y,clearHandler:v}=rs(),{liveArr:F,groupLidarr:N}=os(),[m,T]=a.useState([]),[n,M]=a.useState(""),[b,B]=a.useState(null),[K,A]=a.useState(0),[L,ge]=a.useState(""),[J,C]=a.useState(!1),[g,j]=a.useState(null),[q,G]=a.useState({}),[Q,le]=a.useState(ns),[te,W]=a.useState(1),Z=a.useRef(""),l=a.useRef({}),S=a.useRef(u),D=a.useRef(!1),P=a.useRef(n),X=_e({getKey:d=>{const p=d.album,s=p?.artistName||"",o=p?.title||"";return`${s}-${o}`},hashFields:["album","tracks","totals"]}),[ie,ee]=a.useState([]),[f,i]=a.useState([]),[x,R]=a.useState(!1),[I,$]=a.useState(0),[U,he]=a.useState(""),[re,we]=a.useState(null),ye=_e({getKey:d=>{const p=d.album,s=p?.artistName||"",o=p?.title||"";return`${d.__instance}-${s}-${o}`},hashFields:["__instance","album","tracks","totals"]}),Re=_e({getKey:d=>`${d.__instance}-${d.artistName}-${d.albumTitle}-${d.trackNumber}`,hashFields:["__instance","artistName","albumTitle","trackNumber","title","hasFile","monitored","reason"]}),[me,Y]=a.useState(!1),[fe,Ae]=a.useState("all"),[be,De]=a.useState({available:0,monitored:0,missing:0,total:0}),pe=a.useCallback(async()=>{try{const d=await cs();d.ready===!1&&!D.current?(D.current=!0,t("Lidarr backend is still initialising. Check the logs if this persists.","info")):d.ready&&(D.current=!0);const p=(d.arr||[]).filter(s=>s.type==="lidarr");if(T(p),!p.length){M("aggregate"),B(null),ee([]),De({available:0,monitored:0,missing:0,total:0});return}n===""?M(p.length===1?p[0].category:"aggregate"):n!=="aggregate"&&!p.some(s=>s.category===n)&&M(p[0].category)}catch(d){t(d instanceof Error?d.message:"Unable to load Lidarr instances","error")}},[t,n]),Se=a.useCallback(async(d,p,s,o,c)=>{if(o.length)try{const E=[];for(const _ of o){const O=await es(d,_,s,p),k=O.page??_;if(E.push({page:k,albums:O.albums??[]}),Z.current!==c)return}if(Z.current!==c)return;G(_=>{const O={..._};let k=!1;for(const{page:z,albums:H}of E){const oe=X.syncData(H);oe.hasChanges&&(O[z]=oe.data,k=!0)}return l.current=O,k?O:_})}catch(E){t(E instanceof Error?E.message:`Failed to load additional pages for ${d}`,"error")}},[t]),Ce=a.useCallback(async(d,p,s,o={})=>{const c=o.preloadAll!==!1;(o.showLoading??!0)&&C(!0);try{const _=`${d}::${s}`,O=Z.current!==_;O&&(Z.current=_,G(()=>(l.current={},{})));const k=await es(d,p,ns,s);B(k);const z=k.page??p;A(z),ge(s);const H=k.page_size??ns,oe=k.total??(k.albums??[]).length,w=Math.max(1,Math.ceil((oe||0)/H));le(H),W(w);const se=k.albums??[],ue=O?{}:l.current,xe=X.syncData(se),ae=xe.hasChanges;if(O&&X.reset(),(O||ae)&&(G(V=>{const je={...O?{}:V,[z]:xe.data};return l.current=je,je}),j(new Date().toLocaleTimeString())),c){const V=[];for(let de=0;de<w;de+=1)de!==z&&(ue[de]||V.push(de));Se(d,s,H,V,_)}}catch(_){t(_ instanceof Error?_.message:`Failed to load ${d} albums`,"error")}finally{C(!1)}},[t,Se]),Ne=a.useCallback(async d=>{if(!m.length){ee([]),De({available:0,monitored:0,missing:0,total:0});return}(d?.showLoading??!0)&&R(!0);try{const s=[];let o=0,c=0;for(const w of m){let se=0,ue=!1;const xe=w.name||w.category;for(;se<100;){const ae=await es(w.category,se,xs,"");if(console.log("=== Lidarr API Response ==="),console.log("Instance:",w.category),console.log("Response:",ae),console.log("Albums count:",ae.albums?.length),ae.albums&&ae.albums.length>0&&(console.log("First album entry:",ae.albums[0]),console.log("First album.album:",ae.albums[0].album),console.log("First album.totals:",ae.albums[0].totals),console.log("First album.tracks:",ae.albums[0].tracks)),console.log("========================="),!ue){const de=ae.counts;de&&(o+=de.available??0,c+=de.monitored??0),ue=!0}const V=ae.albums??[];if(V.forEach(de=>{s.push({...de,__instance:xe})}),!V.length||V.length<xs)break;se+=1}}const E=[];s.forEach(w=>{const se=w.album,ue=se?.artistName||"Unknown Artist",xe=se?.title||"Unknown Album",ae=se?.reason,V=se?.qualityProfileId,de=se?.qualityProfileName,je=w.tracks||[];je&&je.length>0&&je.forEach(ce=>{E.push({__instance:w.__instance,artistName:ue,albumTitle:xe,trackNumber:ce.trackNumber||0,title:ce.title||"Unknown Track",duration:ce.duration,hasFile:ce.hasFile||!1,monitored:ce.monitored||!1,reason:ae,qualityProfileId:V,qualityProfileName:de})})});const _=ye.syncData(s),O=_.hasChanges,k=Re.syncData(E),z=k.hasChanges;O&&ee(_.data),z&&i(k.data);const H=N?{available:o,monitored:c,missing:s.length-o,total:s.length}:{available:E.filter(w=>w.hasFile).length,monitored:E.filter(w=>w.monitored).length,missing:E.filter(w=>!w.hasFile).length,total:E.length},oe=be.available!==H.available||be.monitored!==H.monitored||be.missing!==H.missing||be.total!==H.total;oe&&De(H),U!==u&&($(0),he(u)),(O||oe)&&we(new Date().toLocaleTimeString())}catch(s){ee([]),De({available:0,monitored:0,missing:0,total:0}),t(s instanceof Error?s.message:"Failed to load aggregated Lidarr data","error")}finally{R(!1)}},[m,u,t,U,N]);a.useEffect(()=>{r&&pe()},[r,pe]),a.useEffect(()=>{if(!r||!n||n==="aggregate")return;const d=P.current!==n;d&&(l.current={},G({}),W(1),A(0),P.current=n);const p=S.current;Ce(n,d?0:K,p,{preloadAll:!0,showLoading:!0})},[r,n,Ce,K]),a.useEffect(()=>{r&&n==="aggregate"&&Ne()},[r,n,Ne]),Ke(()=>{n==="aggregate"&&F&&Ne({showLoading:!1})},n==="aggregate"&&F?1e3:null),a.useEffect(()=>{if(!r)return;const d=p=>{n==="aggregate"?(he(p),$(0)):n&&(A(0),Ce(n,0,p,{preloadAll:!0,showLoading:!0}))};return y(d),()=>{v(d)}},[r,n,y,v,Ce]),Ke(()=>{if(n&&n!=="aggregate"){if(S.current?.trim?.()||"")return;Ce(n,K,L,{preloadAll:!1,showLoading:!1})}},r&&n&&n!=="aggregate"&&F?1e3:null),a.useEffect(()=>{S.current=u},[u]),a.useEffect(()=>{n==="aggregate"&&he(u)},[n,u]);const Fe=a.useMemo(()=>{let d=ie;if(U){const p=U.toLowerCase();d=d.filter(s=>{const o=s.album,c=(o?.title??"").toString().toLowerCase(),E=(o?.artistName??"").toString().toLowerCase(),_=(s.__instance??"").toLowerCase();return c.includes(p)||E.includes(p)||_.includes(p)})}return me&&(d=d.filter(p=>!p.album?.hasFile)),fe!=="all"&&(fe==="Not being searched"?d=d.filter(p=>{const s=p.album;return s?.reason==="Not being searched"||!s?.reason}):d=d.filter(p=>p.album?.reason===fe)),d},[ie,U,me,fe]),Oe=!!U||fe!=="all",He=a.useMemo(()=>{let d=f;if(U){const p=U.toLowerCase();d=d.filter(s=>s.artistName.toLowerCase().includes(p)||s.albumTitle.toLowerCase().includes(p)||s.title.toLowerCase().includes(p)||s.__instance.toLowerCase().includes(p))}return me&&(d=d.filter(p=>!p.hasFile)),fe!=="all"&&(fe==="Not being searched"?d=d.filter(p=>p.reason==="Not being searched"||!p.reason):d=d.filter(p=>p.reason===fe)),d},[f,U,me,fe]),$e=a.useMemo(()=>{const d=Object.keys(q).map(Number).sort((s,o)=>s-o),p=[];return d.forEach(s=>{q[s]&&p.push(...q[s])}),p},[q]),Ve=a.useMemo(()=>q[K]??[],[q,K]),Qe=a.useCallback(async()=>{if(!(!n||n==="aggregate"))try{await ds(n),t(`Restarted ${n}`,"success")}catch(d){t(d instanceof Error?d.message:`Failed to restart ${n}`,"error")}},[n,t]),We=a.useCallback(d=>{const p=d.target.value||"aggregate";M(p),p!=="aggregate"&&h("")},[M,h]),Ie=n==="aggregate";return e.jsxs("section",{className:"card",children:[e.jsx("div",{className:"card-header",children:"Lidarr"}),e.jsx("div",{className:"card-body",children:e.jsxs("div",{className:"split",children:[e.jsxs("aside",{className:"pane sidebar",children:[m.length>1&&e.jsx("button",{className:`btn ${Ie?"active":""}`,onClick:()=>M("aggregate"),children:"All Lidarr"}),m.map(d=>e.jsx("button",{className:`btn ghost ${n===d.category?"active":""}`,onClick:()=>{M(d.category),h("")},children:d.name||d.category},d.category))]}),e.jsxs("div",{className:"pane",children:[e.jsxs("div",{className:"field mobile-instance-select",children:[e.jsx("label",{children:"Instance"}),e.jsxs("select",{value:n||"aggregate",onChange:We,disabled:!m.length,children:[m.length>1&&e.jsx("option",{value:"aggregate",children:"All Lidarr"}),m.map(d=>e.jsx("option",{value:d.category,children:d.name||d.category},d.category))]})]}),e.jsxs("div",{className:"row",style:{alignItems:"flex-end",gap:"12px",flexWrap:"wrap"},children:[e.jsxs("div",{className:"col field",style:{flex:"1 1 200px"},children:[e.jsx("label",{children:"Search"}),e.jsx("input",{placeholder:"Filter albums",value:u,onChange:d=>h(d.target.value)})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Status"}),e.jsxs("select",{onChange:d=>{const p=d.target.value;Y(p==="missing")},value:me?"missing":"all",children:[e.jsx("option",{value:"all",children:"All Albums"}),e.jsx("option",{value:"missing",children:"Missing Only"})]})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Search Reason"}),e.jsxs("select",{onChange:d=>Ae(d.target.value),value:fe,children:[e.jsx("option",{value:"all",children:"All Reasons"}),e.jsx("option",{value:"Not being searched",children:"Not Being Searched"}),e.jsx("option",{value:"Missing",children:"Missing"}),e.jsx("option",{value:"Quality",children:"Quality"}),e.jsx("option",{value:"CustomFormat",children:"Custom Format"}),e.jsx("option",{value:"Upgrade",children:"Upgrade"})]})]})]}),Ie?e.jsx(Es,{loading:x,rows:Fe,trackRows:He,page:I,onPageChange:$,onRefresh:()=>{Ne({showLoading:!0})},lastUpdated:re,summary:be,instanceCount:m.length,groupLidarr:N,isAggFiltered:Oe}):e.jsx(Is,{loading:J,data:b,page:K,totalPages:te,pageSize:Q,allAlbums:N?Ve:$e,onlyMissing:me,reasonFilter:fe,onPageChange:d=>{A(d),Ce(n,d,L,{preloadAll:!0})},onRestart:()=>{Qe()},lastUpdated:g,groupLidarr:N,instances:m,selection:n})]})]})})]})}function Us({type:r,active:t}){return r==="radarr"?e.jsx(As,{active:t}):r==="lidarr"?e.jsx(_s,{active:t}):e.jsx($s,{active:t})}export{Us as ArrView};
|
|
2
2
|
//# sourceMappingURL=ArrView.js.map
|