1var Ws=Object.defineProperty;var Xs=(s,a,o)=>a in s?Ws(s,a,{enumerable:!0,configurable:!0,writable:!0,value:o}):s[a]=o;var Je=(s,a,o)=>Xs(s,typeof a!="symbol"?a+"":a,o);import{d as M,t as U,j as e,B as k,r as ys,v as ls,P as Fe,w as ss,x as Zs,af as Qs,ai as bs,ah as et,E as st,aj as tt,ak as at,n as Re,b3 as ke,o as it,L as nt}from"./index-DGkCV18M.js";import{r as n,Y as Ns,v as ie,R as Ee,bd as rt,ba as lt,aA as us,U as ot,ac as Ve,ce as ws,cf as ct,e as ye,y as Ye,bS as ts,g as dt,H as ms,X as Ge,ao as as,ay as ut,d as mt,bf as is,i as ns,cg as ht,ah as rs,aI as pt,E as xt,ch as hs,p as ps,bw as gt,aa as ft,C as jt,aB as vt,s as yt,K as bt,z as Nt,a6 as _s,a7 as Ss,bb as We,O as wt,ap as _t,ci as St,cj as kt,w as Ct}from"./icons-B5hbgZbc.js";import{C as me,a as he,b as pe,d as xe}from"./card-CccqfwSN.js";import{B as se}from"./badge-DqPzbhq4.js";import{S as Se}from"./skeleton-BG_Ldh4B.js";import{I as de}from"./input-Djs9V4hI.js";import{D as ks,b as Cs,c as Ts,d as Is}from"./dialog-DK2wDU8s.js";import{T as Es}from"./textarea-D_PtYdnP.js";import{L as le}from"./label-Dnz4VgCM.js";import{S as ge,a as fe,b as je,c as ve,d as Z}from"./select-xLVyleAn.js";import{u as Tt}from"./index-CmvZa3SB.js";import{P as Le}from"./progress-tUl4MqjX.js";import{S as It}from"./switch-NalEOrEe.js";import{C as As}from"./checkbox-CKIrtKi8.js";import"./index-pMG5Nshn.js";const Et="https://www.googleapis.com/auth/youtube.upload",At="https://www.googleapis.com/auth/youtube.force-ssl",$t=s=>{const a=(s??"").split(/\s+/);return a.includes(Et)&&a.includes(At)},Rt=new Intl.NumberFormat("en-US"),Lt=s=>s==null||s===""?"â":Rt.format(Number(s)),Pt=s=>s?new Date(s).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"}):"â",zt=()=>{const[s,a]=n.useState(null),[o,x]=n.useState(!0),[r,v]=n.useState(null),[f,T]=n.useState(!1),[m,h]=n.useState(!1),[g,C]=n.useState(!1),y=n.useCallback(async()=>{x(!0);const{data:w,error:O}=await M.from("my_youtube_connection").select("channel_id, channel_title, scope, created_at, updated_at").maybeSingle();return O&&console.error("youtube connection lookup failed",O.message),a(w??null),x(!1),w??null},[]),_=n.useCallback(async()=>{T(!0);try{const w=await M.functions.invoke("youtube-api?action=channel",{method:"GET"});if(w.error)throw new Error("Could not load channel data");v(w.data)}catch(w){U({title:"YouTube data unavailable",description:w instanceof Error?w.message:"Unknown error",variant:"destructive"})}finally{T(!1)}},[]);n.useEffect(()=>{(async()=>{const w=await y();w!=null&&w.channel_id&&await _()})()},[y,_]);const N=async()=>{h(!0);try{const{data:w,error:O}=await M.functions.invoke("youtube-oauth/start",{body:{return_to:`${window.location.origin}/admin/youtube`}});if(O||!(w!=null&&w.authorization_url))throw new Error("Could not start the YouTube connection");window.location.href=w.authorization_url}catch(w){U({title:"Connection failed",description:w instanceof Error?w.message:"Unknown error",variant:"destructive"}),h(!1)}},S=async()=>{C(!0);try{const{error:w}=await M.functions.invoke("youtube-oauth/disconnect",{body:{}});if(w)throw new Error("Could not disconnect the channel");a(null),v(null),U({title:"YouTube disconnected"})}catch(w){U({title:"Disconnect failed",description:w instanceof Error?w.message:"Unknown error",variant:"destructive"})}finally{C(!1)}},L=!!(s!=null&&s.channel_id),V=$t(s==null?void 0:s.scope);return e.jsxs(me,{className:"border-border/60",children:[e.jsxs(he,{className:"flex flex-row items-center justify-between gap-4 space-y-0",children:[e.jsxs(pe,{className:"text-lg font-display flex items-center gap-2",children:[e.jsx(Ns,{className:"w-5 h-5 text-primary"})," YouTube Channel"]}),e.jsx("div",{className:"flex items-center gap-2",children:L?e.jsxs(e.Fragment,{children:[e.jsxs(se,{variant:"secondary",className:"gap-1",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-accent"})," Connected"]}),e.jsxs(k,{variant:"outline",size:"sm",className:"gap-2",onClick:_,disabled:f,children:[f?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(Ee,{className:"w-4 h-4"}),"Refresh"]}),e.jsxs(k,{variant:"ghost",size:"sm",className:"gap-2 text-muted-foreground",onClick:S,disabled:g,children:[g?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(rt,{className:"w-4 h-4"}),"Disconnect"]})]}):e.jsxs(k,{size:"sm",className:"gap-2",onClick:N,disabled:m||o,children:[m?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(lt,{className:"w-4 h-4"}),"Connect YouTube"]})})]}),e.jsx(xe,{className:"space-y-6",children:o?e.jsxs("div",{className:"space-y-3",children:[e.jsx(Se,{className:"h-6 w-48"}),e.jsx(Se,{className:"h-20 w-full"})]}
1):L?e.jsxs(e.Fragment,{children:[!V&&e.jsxs("div",{className:"rounded-xl border border-primary/30 bg-primary/5 p-4 flex flex-col sm:flex-row sm:items-center gap-3",children:[e.jsx(us,{className:"w-5 h-5 text-primary shrink-0"}),e.jsx("p",{className:"text-sm flex-1",children:"Management access required â reconnect YouTube to enable uploading and editing videos."}),e.jsxs(k,{size:"sm",className:"gap-2 shrink-0",onClick:N,disabled:m,children:[m?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(us,{className:"w-4 h-4"}),"Grant management access"]})]}),e.jsxs("div",{className:"flex items-start gap-4",children:[(r==null?void 0:r.channel.thumbnail)&&e.jsx("img",{src:r.channel.thumbnail,alt:`${r.channel.title??"Channel"} avatar`,className:"w-14 h-14 rounded-full border border-border/60",loading:"lazy"}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"font-semibold truncate",children:(r==null?void 0:r.channel.title)??(s==null?void 0:s.channel_title)??"â"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:(r==null?void 0:r.channel.custom_url)??"â"}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["Linked ",Pt(s==null?void 0:s.created_at)]})]})]}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[{label:"Subscribers",value:r==null?void 0:r.statistics.subscriber_count,icon:ot},{label:"Total views",value:r==null?void 0:r.statistics.view_count,icon:Ve},{label:"Videos",value:r==null?void 0:r.statistics.video_count,icon:ws}].map(w=>{const O=w.icon;return e.jsxs("div",{className:"rounded-xl border border-border/60 bg-card/60 p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-xs uppercase tracking-wide text-muted-foreground",children:[e.jsx(O,{className:"w-3.5 h-3.5"})," ",w.label]}),e.jsx("p",{className:"text-2xl font-bold mt-1",children:f&&!r?e.jsx(Se,{className:"h-7 w-20"}):Lt(w.value)})]},w.label)})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:r?`Last synced ${new Date().toLocaleTimeString("en-GB")}`:"Not synced yet"})]}):e.jsx("p",{className:"text-sm text-muted-foreground",children:"No YouTube channel is connected yet. Connect a channel to see subscribers, views and recent video performance here."})})]})};var os="Radio",[Dt,$s]=ys(os),[Gt,Ut]=Dt(os),Rs=n.forwardRef((s,a)=>{const{__scopeRadio:o,name:x,checked:r=!1,required:v,disabled:f,value:T="on",onCheck:m,form:h,...g}=s,[C,y]=n.useState(null),_=ls(a,L=>y(L)),N=n.useRef(!1),S=C?h||!!C.closest("form"):!0;return e.jsxs(Gt,{scope:o,checked:r,disabled:f,children:[e.jsx(Fe.button,{type:"button",role:"radio","aria-checked":r,"data-state":Ds(r),"data-disabled":f?"":void 0,disabled:f,value:T,...g,ref:_,onClick:ss(s.onClick,L=>{r||m==null||m(),S&&(N.current=L.isPropagationStopped(),N.current||L.stopPropagation())})}),S&&e.jsx(zs,{control:C,bubbles:!N.current,name:x,value:T,checked:r,required:v,disabled:f,form:h,style:{transform:"translateX(-100%)"}})]})});Rs.displayName=os;var Ls="RadioIndicator",Ps=n.forwardRef((s,a)=>{const{__scopeRadio:o,forceMount:x,...r}=s,v=Ut(Ls,o);return e.jsx(Zs,{present:x||v.checked,children:e.jsx(Fe.span,{"data-state":Ds(v.checked),"data-disabled":v.disabled?"":void 0,...r,ref:a})})});Ps.displayName=Ls;var Mt="RadioBubbleInput",zs=n.forwardRef(({__scopeRadio:s,control:a,checked:o,bubbles:x=!0,...r},v)=>{const f=n.useRef(null),T=ls(f,v),m=Tt(o),h=Qs(a);return n.useEffect(()=>{const g=f.current;if(!g)return;const C=window.HTMLInputElement.prototype,_=Object.getOwnPropertyDescriptor(C,"checked").set;if(m!==o&&_){const N=new Event("click",{bubbles:x});_.call(g,o),g.dispatchEvent(N)}},[m,o,x]),e.jsx(Fe.input,{type:"radio","aria-hidden":!0,defaultChecked:o,...r,tabIndex:-1,ref:T,style:{...r.style,...h,position:"absolute",pointerEvents:"none",opacity:0,margin:0}})});zs.displayName=Mt;function Ds(s){return s?"checked":"unchecked"}var Ot=["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"],Be="RadioGroup",[Vt,Pa]=ys(Be,[bs,$s]),Gs=bs(),Us=$s(),[Yt,Ft]=Vt(Be),Ms=n.forwardRef((s,a)=>{const{__scopeRadioGroup:o,name:x,defaultValue:r,value:v,required:f=!1,disabled:T=!1,orientation:m,dir:h,loop:g=!0,onValueChange:C,...y}=s,_=Gs(o),N=et(h),[S,L]=st({prop:v,defaultProp:r??null,onChange:C,caller:Be});return e.jsx(Yt,{scope:o,name:x,required:f,disabled:T,value:S,onValueChange:L,children:e.jsx(tt,{asChild:!0,..._,orientation:m,dir:N,loop:g,children:e.jsx(Fe.div,{role:"radiogroup","aria-required":f,"aria-orientation":m,"data-disabled":T?"":void 0,dir:N,...y,ref:a})})})});Ms.displayName=Be;var Os="RadioGroupItem",Vs=n.forwardRef((s,a)=>{const{__scopeRadioGroup:o,disabled:x,...r}=s,v=Ft(Os,o),f=v.disabled||x,T=Gs(o),m=Us(o),h=n.useRef(null),g=ls(a,h),C=v.value===r.value,y=n.useRef(!1);return n.useEffect(()=>{const _=S=>{Ot.includes(S.key)&&(y.current=!0)},N=()=>y.current=!1;return document.addEventListener("keydown",_),document.addEventListener("keyup",N),(
1)=>{document.removeEventListener("keydown",_),document.removeEventListener("keyup",N)}},[]),e.jsx(at,{asChild:!0,...T,focusable:!f,active:C,children:e.jsx(Rs,{disabled:f,required:v.required,checked:C,...m,...r,name:v.name,ref:g,onCheck:()=>v.onValueChange(r.value),onKeyDown:ss(_=>{_.key==="Enter"&&_.preventDefault()}),onFocus:ss(r.onFocus,()=>{var _;y.current&&((_=h.current)==null||_.click())})})})});Vs.displayName=Os;var Bt="RadioGroupIndicator",Ys=n.forwardRef((s,a)=>{const{__scopeRadioGroup:o,...x}=s,r=Us(o);return e.jsx(Ps,{...r,...x,ref:a})});Ys.displayName=Bt;var Fs=Ms,Bs=Vs,qt=Ys;const cs=n.forwardRef(({className:s,...a},o)=>e.jsx(Fs,{className:Re("grid gap-2",s),...a,ref:o}));cs.displayName=Fs.displayName;const ds=n.forwardRef(({className:s,...a},o)=>e.jsx(Bs,{ref:o,className:Re("aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",s),...a,children:e.jsx(qt,{className:"flex items-center justify-center",children:e.jsx(ct,{className:"h-2.5 w-2.5 fill-current text-current"})})}));ds.displayName=Bs.displayName;const xs=s=>["Chapters",...s.map(a=>`${a.timestamp} ${a.label}`)].join(` 2`),Kt=ke.map(s=>({slug:s.slug,title:s.title})),Ht=s=>{if(!s)return null;const a=s.match(/PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/);return a?Number(a[1]??0)*3600+Number(a[2]??0)*60+Number(a[3]??0):null},_e=({title:s,items:a})=>a&&a.length>0?e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:s}),e.jsx("ul",{className:"text-sm space-y-1 list-disc pl-4",children:a.map((o,x)=>e.jsx("li",{children:o},`${s}-${x}`))})]}):null,Pe=({title:s,items:a})=>a&&a.length>0?e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:s}),e.jsx("div",{className:"flex flex-wrap gap-1.5",children:a.map((o,x)=>e.jsx(se,{variant:"secondary",className:"font-normal",children:o},`${s}-${x}`))})]}):null,Jt=({video:s,currentTitle:a,currentDescription:o,currentTags:x,onApplyTitle:r,onApplyDescription:v,onApplyTags:f,onApplyChapters:T})=>{var X,ne,Ne,be,Ce,we,t,l,R,ce,q,ae;const m=s.id,[h,g]=n.useState(!1),[C,y]=n.useState(0),[_,N]=n.useState(""),[S,L]=n.useState(null),[V,w]=n.useState(null),[O,b]=n.useState([]),[F,W]=n.useState(null),[J,te]=n.useState([]),[u,i]=n.useState(!1),[d,j]=n.useState(null),[$,I]=n.useState(!1),[z,A]=n.useState(null),Y=P=>te(K=>K.includes(P)?K:[...K,P]),B=n.useCallback(async P=>{const{data:K,error:H}=await M.functions.invoke("youtube-analyze",{body:{id:m,refresh:P.refresh===!0,cache_only:P.cacheOnly===!0,guides:Kt}});if(H){let oe="The analysis request failed.";const Te=H==null?void 0:H.context;try{const Q=Te&&typeof Te.json=="function"?await Te.json():null;Q!=null&&Q.message?oe=Q.message:Q!=null&&Q.error&&(oe=String(Q.error))}catch{}throw new Error(oe)}return K},[m]);n.useEffect(()=>{let P=!0;return(async()=>{var K;try{const H=await B({cacheOnly:!0});if(!P||!(H!=null&&H.analysis))return;L(H.analysis),w(H.provenance??null),b(Array.isArray(H.warnings)?H.warnings:[]),i(!!H.cached),j(H.analyzed_at??((K=H.provenance)==null?void 0:K.analyzed_at)??null),y(100)}catch{}})(),()=>{P=!1}},[B]);const ee=async P=>{var Te;g(!0),W(null),te([]),y(8),N("Reading video metadataâ¦");const K=[[25,"Downloading the timestamped transcriptâ¦"],[45,"Extracting 10 timestamped framesâ¦"],[70,"Analysing content with AIâ¦"],[88,"Building SEO recommendationsâ¦"]];let H=0;const oe=window.setInterval(()=>{H<K.length&&(y(K[H][0]),N(K[H][1]),H++)},4e3);try{const Q=await B({refresh:P});if(!(Q!=null&&Q.analysis))throw new Error("The analysis response was empty.");L(Q.analysis),w(Q.provenance??null),b(Array.isArray(Q.warnings)?Q.warnings:[]),i(!!Q.cached),j(Q.analyzed_at??((Te=Q.provenance)==null?void 0:Te.analyzed_at)??null),y(100),N("Analysis complete")}catch(Q){W(Q instanceof Error?Q.message:"Unknown error"),y(0),N("")}finally{window.clearInterval(oe),g(!1)}},p=S==null?void 0:S.seo,c=S==null?void 0:S.guide,E=(p==null?void 0:p.recommended_chapters)??[],D=async()=>
2{if(c!=null&&c.slug){I(!0);try{const{data:P}=await M.from("guide_videos").select("id").eq("guide_slug",c.slug).eq("youtube_video_id",m).maybeSingle();if(P){A(c.slug),U({title:"Already attached",description:`This video is already on /${c.slug}.`});return}const{count:K}=await M.from("guide_videos").select("id",{count:"exact",head:!0}).eq("guide_slug",c.slug).not("youtube_video_id","is",null),{error:H}=await M.from("guide_videos").insert({guide_slug:c.slug,youtube_video_id:m,title:a||s.title||"Tabir lecture",poster_url:s.thumbnail_large??s.thumbnail??null,duration_seconds:Ht(s.duration),published_at:s.published_at??null,channel_title:"Tabir Academy",source:"youtube",sort_order:K??0,is_hero:(K??0)===0,is_published:!1});if(H)throw new Error(H.message);A(c.slug),Y("Guide"),U({title:`Attached to /${c.slug}`,description:"Saved as a draft â publish it from Admin â Guides when you're ready."})}catch(P){U({title:"Could not attach the guide",description:P instanceof Error?P.message:"Unknown error",variant:"destructive"})}finally{I(!1)}}},G=()=>{p!=null&&p.recommended_title&&(r(p.recommended_title),Y("Title"));let P=(p==null?void 0:p.optimized_description)??o;E.length>0&&(P=`${P} 3 4${xs(E)}`),c!=null&&c.description_section&&(P=`${P} 5 6${c.description_section}`),(p!=null&&p.optimized_description||E.length>0||c!=null&&c.description_section)&&(v(P),Y("Description"),E.length>0&&Y("Chapters")),p!=null&&p.recommended_tags&&p.recommended_tags.length>0&&(f(p.recommended_tags),Y("Tags")),U({title:"Suggestions applied to the editor",description:"Review the changes, then press Save changes to publish them to YouTube."})};return e.jsxs("div",{className:"rounded-xl border border-primary/25 bg-primary/5 p-4 space-y-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"text-sm font-semibold flex items-center gap-1.5",children:[e.jsx(ye,{className:"w-4 h-4 text-primary"})," AI video analysis & SEO assistant"]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Transcript-first analysis with 10 timestamped frames. Nothing is sent to YouTube until you apply and save."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[S&&e.jsxs(k,{size:"sm",variant:"outline",className:"gap-2",onClick:()=>ee(!0),disabled:h,children:[h?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(Ee,{className:"w-4 h-4"}),"Re-analyse"]}),!S&&e.jsxs(k,{size:"sm",className:"gap-2",onClick:()=>ee(!1),disabled:h,children:[h?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(ye,{className:"w-4 h-4"}),"AI Optimize Video"]})]})]}),u&&d&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Saved analysis from ",new Date(d).toLocaleString("en-GB")," â no new AI cost. Use Re-analyse to refresh it."]}),(h||C>0&&C<100)&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(Le,{value:C}),e.jsx("p",{className:"text-xs text-muted-foreground",children:_})]}),F&&e.jsxs("p",{className:"text-sm text-destructive flex items-start gap-1.5",children:[e.jsx(Ye,{className:"w-4 h-4 mt-0.5 shrink-0"})," ",F]}),O.length>0&&e.jsx("ul",{className:"text-xs text-muted-foreground space-y-1",children:O.map((P,K)=>e.jsxs("li",{className:"flex items-start gap-1.5",children:[e.jsx(ts,{className:"w-3.5 h-3.5 mt-0.5 shrink-0"}),P]},K))}),S&&e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs("div",{className:"rounded-lg bg-background/70 border px-3 py-2",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"SEO score"}),e.jsxs("p",{className:"text-2xl font-bold",children:[(p==null?void 0:p.score)??"â",e.jsx("span",{className:"text-sm text-muted-foreground",children:"/100"})]})]}),e.jsx(k,{size:"sm",variant:"secondary",onClick:G,children:"Apply all"}),J.length>0&&e.jsxs("span",{className:"text-xs text-muted-foreground flex items-center gap-1",children:[e.jsx(dt,{className:"w-3.5 h-3.5"})," Applied: ",J.join(", ")," â press Save changes to publish"]})]}),(p==null?void 0:p.current_assessment)&&e.jsxs("div",{className:"rounded-lg border bg-background/70 p-3 text-sm",children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-1",children:"Current SEO assessment"}),p.current_assessment]}),e.jsx("div",{className:"grid gap-2 sm:grid-cols-2 text-sm",children:[["Primary topic",(X=S.content)==null?void 0:X.primary_topic],["Subject",(ne=S.content)==null?void 0:ne.subject],["Level",(Ne=S.content)==null?void 0:Ne.educational_level],["Audience",(be=S.content)==null?void 0:be.target_audience],["Search intent",p==null?void 0:p.search_intent]].filter(([,P])=>P).map(([P,K])=>e.jsxs("p",{children:[e.jsxs("span",{className:"text-muted-foreground",children:[P,": "]}
6),e.jsx("span",{className:"font-medium",children:K})]},String(P)))}),(p==null?void 0:p.recommended_title)&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"Title"}),e.jsxs("div",{className:"rounded-lg border bg-background/70 p-3 space-y-2 text-sm",children:[e.jsxs("p",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Current: "}),a||"â"]}),e.jsxs("p",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Recommended: "}),e.jsx("span",{className:"font-medium",children:p.recommended_title})]}),e.jsx(k,{size:"sm",variant:"outline",onClick:()=>{r(p.recommended_title),Y("Title")},children:"Apply title"})]}),p.title_suggestions&&p.title_suggestions.length>0&&e.jsx("ul",{className:"space-y-1.5",children:p.title_suggestions.filter(Boolean).map((P,K)=>e.jsxs("li",{className:"flex items-start justify-between gap-2 text-sm",children:[e.jsx("span",{children:P}),e.jsx(k,{size:"sm",variant:"ghost",className:"shrink-0",onClick:()=>{r(P),Y("Title")},children:"Use"})]},K))})]}),(p==null?void 0:p.optimized_description)&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"Description â current vs recommended"}),e.jsxs("div",{className:"grid gap-2 lg:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[11px] text-muted-foreground mb-1",children:"Current"}),e.jsx("pre",{className:"rounded-lg border bg-background/50 p-3 text-xs whitespace-pre-wrap font-mono max-h-64 overflow-auto",children:(o==null?void 0:o.trim())||"(empty)"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[11px] text-muted-foreground mb-1",children:"Recommended"}),e.jsx("pre",{className:"rounded-lg border bg-background/70 p-3 text-xs whitespace-pre-wrap font-mono max-h-64 overflow-auto",children:p.optimized_description})]})]}),e.jsx(k,{size:"sm",variant:"outline",onClick:()=>{v(p.optimized_description),Y("Description")},children:"Apply description"})]}),e.jsx(Pe,{title:"Primary keywords",items:p==null?void 0:p.primary_keywords}),e.jsx(Pe,{title:"Secondary keywords",items:p==null?void 0:p.secondary_keywords}),(p==null?void 0:p.recommended_tags)&&p.recommended_tags.length>0&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("p",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:["Tags â current: ",x.length>0?x.join(", "):"none"]}),e.jsx(Pe,{title:"Recommended tags",items:p.recommended_tags}),e.jsx(k,{size:"sm",variant:"outline",onClick:()=>{f(p.recommended_tags),Y("Tags")},children:"Apply tags"})]}),e.jsx(Pe,{title:"Hashtags",items:p==null?void 0:p.recommended_hashtags}),E.length>0&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"Chapters (from transcript timing)"}),e.jsx("ul",{className:"text-sm font-mono space-y-0.5",children:E.map((P,K)=>e.jsxs("li",{children:[P.timestamp," â ",P.label]},K))}),e.jsx(k,{size:"sm",variant:"outline",onClick:()=>{T(xs(E)),Y("Chapters")},children:"Apply chapters"})]}),(c==null?void 0:c.slug)&&e.jsxs("div",{className:"space-y-2 rounded-lg border bg-background/70 p-3",children:[e.jsxs("p",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground flex items-center gap-1.5",children:[e.jsx(ms,{className:"w-3.5 h-3.5"})," Recommended Tabir study guide"]}),e.jsxs("p",{className:"text-sm",children:[e.jsx("span",{className:"font-medium",children:c.title||c.slug})," ",e.jsxs("a",{href:`/${c.slug}`,target:"_blank",rel:"noopener noreferrer",className:"text-primary underline",children:["/",c.slug]}),typeof c.confidence=="number"&&e.jsxs(se,{variant:"outline",className:"ml-2 font-normal",children:[Math.round((c.confidence>1?c.confidence/100:c.confidence)*100),"% confidence"]})]}),c.reasoning&&e.jsx("p",{className:"text-sm text-muted-foreground",children:c.reasoning}),c.description_section&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-muted-foreground",children:"Suggested guide CTA for the YouTube description"}),e.jsx("pre",{className:"rounded-lg border bg-background/50 p-3 text-xs whitespace-pre-wrap font-mono",children:c.description_section}),e.jsx(k,{size:"sm",variant:"outline",onClick:()=>{T(c.description_section),Y("Guide CTA")},children:"Append guide CTA to description"})]}),c.guide_side_recommendation&&e.jsxs("p",{className:"text-sm text-muted-foreground",children:[e.jsx("span",{className:"font-medium text-foreground",children:"On the guide page: "}),c.guide_side_recommendation]}),e.jsxs(k,{size:"sm",className:"gap-2",onClick:D,disabled:$||z===c.slug,children:[$?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(ms,{className:"w-4 h-4"}),z===c.slug?"Attached (draft)":"Attach to guide"]})]}),e.jsx(_e,{title:"Key concepts",items:(Ce=S.content)==null?void 0:Ce.key_concepts}),e.jsx(_e,{title:"Terminology",items:(we=S.content)==null?void 0:we.terminology}
6),e.jsx(_e,{title:"Title weaknesses",items:(t=S.recommendations)==null?void 0:t.title_weaknesses}),e.jsx(_e,{title:"Description weaknesses",items:(l=S.recommendations)==null?void 0:l.description_weaknesses}),e.jsx(_e,{title:"Keyword opportunities",items:(R=S.recommendations)==null?void 0:R.keyword_opportunities}),e.jsx(_e,{title:"Content / SEO gaps",items:(ce=S.recommendations)==null?void 0:ce.gaps}),e.jsx(_e,{title:"Actionable recommendations",items:(q=S.recommendations)==null?void 0:q.actions}),e.jsx(_e,{title:"Limitations",items:S.limitations}),V&&e.jsxs("p",{className:"text-[11px] text-muted-foreground border-t pt-3",children:[V.model," via ",V.provider," · transcript:"," ",V.transcript_source??"unavailable",V.transcript_segments?` (${V.transcript_segments} segments)`:""," · frames:"," ",(ae=V.frame_timestamps)==null?void 0:ae.map(P=>P.label).join(", ")," · ",V.frame_method,". The AI read the transcript and these 10 sampled frames â it did not watch the whole video.",S.transcript_quality?` Transcript quality: ${S.transcript_quality}`:""]})]})]})},Xe=s=>{if(!s)return"";const a=new Date(s);if(Number.isNaN(a.getTime()))return"";const o=x=>String(x).padStart(2,"0");return`${a.getFullYear()}-${o(a.getMonth()+1)}-${o(a.getDate())}T${o(a.getHours())}:${o(a.getMinutes())}`},Wt=({video:s,categories:a,onSaved:o,onCancel:x})=>{const[r,v]=n.useState(s.title??""),[f,T]=n.useState(s.description??""),[m,h]=n.useState(s.tags??[]),[g,C]=n.useState(""),[y,_]=n.useState(s.category_id??""),[N,S]=n.useState(s.privacy_status??"private"),[L,V]=n.useState(Xe(s.publish_at)),[w,O]=n.useState(!!(s.self_declared_made_for_kids??s.made_for_kids)),[b,F]=n.useState(!1),W=n.useMemo(()=>{const i=[],d={title:s.title??"",description:s.description??"",tags:(s.tags??[]).join(", "),categoryId:s.category_id??"",privacy:s.privacy_status??"",publishAt:Xe(s.publish_at),kids:!!(s.self_declared_made_for_kids??s.made_for_kids)},j=$=>{var I;return((I=a.find(z=>z.id===$))==null?void 0:I.title)??$??"â"};
6return r!==d.title&&i.push({field:"Title",from:d.title,to:r}),f!==d.description&&i.push({field:"Description",from:`${d.description.length} chars`,to:`${f.length} chars`}),m.join(", ")!==d.tags&&i.push({field:"Tags",from:d.tags||"none",to:m.join(", ")||"none"}),y!==d.categoryId&&i.push({field:"Category",from:j(d.categoryId),to:j(y)}),N!==d.privacy&&i.push({field:"Visibility",from:d.privacy||"â",to:N}),L!==d.publishAt&&i.push({field:"Scheduled publish",from:d.publishAt||"none",to:L||"none"}),w!==d.kids&&i.push({field:"Made for kids",from:d.kids?"Yes":"No",to:w?"Yes":"No"}),i},[r,f,m,y,N,L,w,s,a]),J=W.length>0;n.useEffect(()=>{if(!J)return;const i=d=>{d.preventDefault(),d.returnValue=""};return window.addEventListener("beforeunload",i),()=>window.removeEventListener("beforeunload",i)},[J]);const te=()=>{const i=g.trim();i&&(m.includes(i)||h([...m,i]),C(""))},u=async()=>{if(!J){U({title:"Nothing to save",description:"No fields were changed."});return}if(L){if(new Date(L).getTime()<=Date.now()){U({title:"Invalid schedule",description:"The scheduled publish time must be in the future.",variant:"destructive"});return}if(N!=="private"){U({title:"Invalid schedule",description:"Scheduled publishing requires visibility to be Private.",variant:"destructive"});return}}F(!0);try{const i={action:"updateVideo",id:s.id};r!==(s.title??"")&&(i.title=r),f!==(s.description??"")&&(i.description=f),m.join("\0")!==(s.tags??[]).join("\0")&&(i.tags=m),y&&y!==(s.category_id??"")&&(i.categoryId=y),N!==(s.privacy_status??"")&&(i.privacyStatus=N),w!==!!(s.self_declared_made_for_kids??s.made_for_kids)&&(i.selfDeclaredMadeForKids=w),L!==Xe(s.publish_at)&&(i.publishAt=L?new Date(L).toISOString():null);const{data:d,error:j}=await M.functions.invoke("youtube-api",{body:i});if(j){let I="YouTube rejected the update.";const z=j==null?void 0:j.context;try{const A=z&&typeof z.json=="function"?await z.json():null;A!=null&&A.message?I=A.message:A!=null&&A.error&&(I=String(A.error))}catch{}throw new Error(I)}const $=d==null?void 0:d.video;if(!$)throw new Error("Update response was empty.");U({title:"Video updated",description:W.map(I=>I.field).join(", ")+" saved to YouTube."}),o($)}catch(i){U({title:"Update failed",description:i instanceof Error?i.message:"Unknown error",variant:"destructive"})}finally{F(!1)}};return e.jsxs("div",{className:"space-y-5",children:[e.jsx(Jt,{video:s,currentTitle:r,currentDescription:f,currentTags:m,onApplyTitle:i=>v(i.slice(0,100)),onApplyDescription:i=>T(i.slice(0,5e3)),onApplyTags:i=>h(i),onApplyChapters:i=>T(d=>(d.includes(i)?d:`${d.trimEnd()} 7 8${i}`.trimStart()).slice(0,5e3))}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(le,{htmlFor:"yt-title",children:"Title"}),e.jsxs("span",{className:`text-xs ${r.length>100?"text-destructive":"text-muted-foreground"}`,children:[r.length,"/100"]})]}),e.jsx(de,{id:"yt-title",value:r,maxLength:100,onChange:i=>v(i.target.value)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(le,{htmlFor:"yt-desc",children:"Description"}),e.jsxs("span",{className:`text-xs ${f.length>5e3?"text-destructive":"text-muted-foreground"}`,children:[f.length,"/5000"]})]}),e.jsx(Es,{id:"yt-desc",value:f,maxLength:5e3,rows:10,onChange:i=>T(i.target.value),className:"font-mono text-xs whitespace-pre-wrap"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(le,{children:"Tags"}),e.jsx("div",{className:"flex flex-wrap gap-1.5",children:m.map(i=>e.jsxs(se,{variant:"secondary",className:"font-normal gap-1",children:[i,e.jsx("button",{type:"button","aria-label":`Remove tag ${i}`,onClick:()=>h(m.filter(d=>d!==i)),children:e.jsx(Ge,{className:"w-3 h-3"})})]},i))}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(de,{value:g,placeholder:"Add a tag and press Enter",onChange:i=>C(i.target.value),onKeyDown:i=>{(i.key==="Enter"||i.key===",")&&(i.preventDefault(),te())}}),e.jsx(k,{type:"button",variant:"outline",size:"icon",onClick:te,"aria-label":"Add tag",children:e.jsx(as,{className:"w-4 h-4"})})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[m.join(",").length,"/500 characters used by tags"]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(le,{children:"Category"}),e.jsxs(ge,{value:y,onValueChange:_,children:[e.jsx(fe,{children:e.jsx(je,{placeholder:"Select category"})}),e.jsx(ve,{children:a.map(i=>e.jsx(Z,{value:i.id,children:i.title},i.id))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(le,{children:"Audience"}),e.jsxs(ge,{value:w?"yes":"no",onValueChange:i=>O(i==="yes"),children:[e.jsx(fe,{children:e.jsx(je,{})}),e.jsxs(ve,{children:[e.jsx(Z,{value:"no",children:"Not made for kids"}),e.jsx(Z,{value:"yes",children:"Made for kids"})]})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(le,{children:"Visibility"}),e.jsx(cs,{value:N,onValueChange:i=>S(i),className:"flex flex-wrap gap-4",children:["public","unlisted","private"].map(i=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ds,{value:i,id:`yt-privacy-${i}`}),e.jsx(le,{htmlFor:`yt-privacy-${i}`,className:"capitalize font-normal",children:i})]},i))})]}),N==="private"&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(le,{htmlFor:"yt-publish-at",children:"Schedule publish (optional)"}),e.jsx(de,{id:"yt-publish-at",type:"datetime-local",value:L,onChange:i=>V(i.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Leave empty to keep the video private. Scheduling requires a future time."})]}),J&&e.jsxs("div",{className:"rounded-xl border border-primary/30 bg-primary/5 p-3 space-y-1.5",children:[e.jsxs("p",{className:"text-xs font-semibold uppercase tracking-wide flex items-center gap-1.5",children:[e.jsx(Ye,{className:"w-3.5 h-3.5"})," Unsaved changes"]}),e.jsx("ul",{className:"text-sm space-y-0.5",children:W.map(i=>e.jsxs("li",{className:"text-muted-foreground",children:[e.jsxs("span",{className:"font-medium text-foreground",children:[i.field,":"]})," ",i.from," â ",i.to]},i.field))})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(k,{className:"gap-2",onClick:u,disabled:b||!J,children:[b?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(ut,{className:"w-4 h-4"}),"Save changes"]}),e.jsx(k,{variant:"ghost",onClick:x,disabled:b,children:"Cancel"})]})]})},Xt=it("relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",{variants:{variant:{default:"bg-background text-foreground",destructive:"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive"}},defaultVariants:{variant:"default"}}),Ue=n.forwardRef(({className:s,variant:a,...o},x)=>e.jsx("div",{ref:x,role:"alert",className:Re(Xt({variant:a}),s),...o}));Ue.displayName="Alert";const Me=n.forwardRef(({className:s,...a},o)=>e.jsx("h5",{ref:o,className:Re("mb-1 font-medium leading-none tracking-tight",s),...a}
8));Me.displayName="AlertTitle";const Oe=n.forwardRef(({className:s,...a},o)=>e.jsx("div",{ref:o,className:Re("text-sm [&_p]:leading-relaxed",s),...a}));Oe.displayName="AlertDescription";const Zt="https://sphsrlvxegrsaasnspcr.supabase.co",qe=`${Zt}/functions/v1/youtube-upload`,Qt=2*1024*1024*1024,qs=["video/mp4","video/quicktime","video/webm","video/x-matroska","video/x-msvideo","video/avi"];class Ie extends Error{constructor(o,x,r=!1){super(o);Je(this,"code");Je(this,"resumable");this.code=x,this.resumable=r}}async function Ke(){var o;const{data:s}=await M.auth.getSession(),a=(o=s.session)==null?void 0:o.access_token;if(!a)throw new Ie("Your session expired â sign in again.","no_session");return{Authorization:`Bearer ${a}`,apikey:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InNwaHNybHZ4ZWdyc2Fhc25zcGNyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzA0NzMwMDQsImV4cCI6MjA4NjA0OTAwNH0.tope3k0_5Rn6jtOF9He9Khrggvt47It7h0m6Hvp4g5c"}}async function He(s){const a=await s.json().catch(()=>({}));if(!s.ok)throw new Ie((a==null?void 0:a.message)??(a==null?void 0:a.error)??"The upload request failed.",(a==null?void 0:a.error)??"request_failed",(a==null?void 0:a.resumable)===!0);return a}function ea(s){const a=(s.type||"").toLowerCase();return a&&!qs.includes(a)||!a&&!/\.(mp4|mov|webm|mkv|avi)$/i.test(s.name)?"Upload an MP4, MOV, WebM, MKV or AVI video file.":s.size<=0?"The selected file is empty.":s.size>Qt?"Maximum upload size is 2 GB.":null}function sa(s){var x;const a=(s.type||"").toLowerCase();if(qs.includes(a))return a;const o=(x=s.name.split(".").pop())==null?void 0:x.toLowerCase();return o==="mov"?"video/quicktime":o==="webm"?"video/webm":o==="mkv"?"video/x-matroska":o==="avi"?"video/x-msvideo":"video/mp4"}async function gs(s,a,o){const x=await fetch(`${qe}?action=initiateUpload`,{method:"POST",headers:{...await Ke(),"Content-Type":"application/json"},body:JSON.stringify({action:"initiateUpload",client_upload_id:o,file_size:s.size,mime_type:sa(s),title:a.title,description:a.description,tags:a.tags,categoryId:a.categoryId,privacyStatus:a.privacyStatus,publishAt:a.publishAt,selfDeclaredMadeForKids:a.selfDeclaredMadeForKids})});return await He(x)}async function ta(s){const a=await fetch(`${qe}?action=status&upload_id=${encodeURIComponent(s)}`,{method:"POST",headers:{...await Ke(),"Content-Type":"application/json"},body:JSON.stringify({action:"status",upload_id:s})});return await He(a)}async function aa(s){const a=await fetch(`${qe}?action=cancel&upload_id=${encodeURIComponent(s)}`,{method:"POST",headers:{...await Ke(),"Content-Type":"application/json"},body:JSON.stringify({action:"cancel",upload_id:s})});await He(a)}async function ia(s,a,o,x){const r=await fetch(`${qe}?action=chunk&upload_id=${encodeURIComponent(s)}&offset=${o}`,{method:"POST",headers:{...await Ke(),"Content-Type":"application/octet-stream"},body:a,signal:x});return await He(r)}async function na(s,a,o){var m;const x=s.size,r=Math.min(a.chunk_size??8*1024*1024,8*1024*1024);let v=a.bytes_received??0,f=a;const T=Math.max(1,Math.ceil(x/r));for(;v<x;){if((m=o.signal)!=null&&m.aborted)throw new Ie("Upload cancelled.","aborted",!0);const h=Math.min(v+r,x),g=s.slice(v,h);if(f=await ia(a.upload_id,g,v,o.signal),f.status==="completed")return o.onProgress({bytes:x,total:x,chunkIndex:T,chunkCount:T}),f;v=f.bytes_received??h,o.onProgress({bytes:v,total:x,chunkIndex:Math.min(T,Math.ceil(v/r)),chunkCount:T})}return f}const Ze=s=>s<1024?`${s} B`:s<1024*1024?`${(s/1024).toFixed(0)} KB`:s<1024*1024*1024?`${(s/1024/1024).toFixed(1)} MB`:`${(s/1024/1024/1024).toFixed(2)} GB`,ra=({open:s,onOpenChange:a,categories:o,onUploaded:x})=>{const[r,v]=n.useState(null),[f,T]=n.useState(!1),m=n.useRef(null),[h,g]=n.useState(""),[C,y]=n.useState(""),[_,N]=n.useState([]),[S,L]=n.useState(""),[V,w]=n.useState("27"),[O,b]=n.useState("private"),[F,W]=n.useState(""),[J,te]=n.useState(!1),[u,i]=n.useState("form"),[d,j]=n.useState({bytes:0,total:0,chunkIndex:0,chunkCount:0}),[$,I]=n.useState(null),[z,A]=n.useState(null),[Y,B]=n.useState(null),ee=n.useRef(crypto.randomUUID()),p=n.useRef(null),c=n.useCallback(()=>{v(null),g(""),y(""),N([]),L(""),w("27"),b("private"),W(""),te(!1),i("form"),j({bytes:0,total:0,chunkIndex:0,chunkCount:0}),I(null),A(null),B(null),ee.current=crypto.randomUUID()},[]);n.useEffect(()=>{var l;s||((l=p.current)==null||l.abort(),c())},[s,c]),n.useEffect(()=>{if(u!=="uploading")return;const l=R=>{R.preventDefault(),R.returnValue=""};return window.addEventListener("beforeunload",l),()=>window.removeEventListener("beforeunload",l)},[u]);const E=l=>{if(!l)return;const R=ea(l);if(R){U({title:"File not supported",description:R,variant:"destructive"});return}
8v(l),h.trim()||g(l.name.replace(/\.[^.]+$/,"").slice(0,100))},D=()=>{const l=S.trim();l&&(_.includes(l)||N([..._,l]),L(""))},G=n.useMemo(()=>{if(!r)return"Choose a video file to upload.";if(!h.trim())return"A title is required.";if(h.length>100)return"The title must be 100 characters or fewer.";if(C.length>5e3)return"The description must be 5000 characters or fewer.";if(_.length>100)return"A video can have at most 100 tags.";if(_.join(",").length>500)return"Tags must total 500 characters or fewer.";if(F){if(new Date(F).getTime()<=Date.now())return"The scheduled publish time must be in the future.";if(O!=="private")return"Scheduled publishing requires visibility to be Private."}return null},[r,h,C,_,F,O]),X={title:h.trim(),description:C,tags:_,categoryId:V,privacyStatus:O,publishAt:F?new Date(F).toISOString():null,selfDeclaredMadeForKids:J},ne=async(l,R)=>{const ce=new AbortController;p.current=ce,i("uploading"),B(null);try{const q=await na(R,l,{signal:ce.signal,onProgress:j});q.status==="completed"?(A(q),i("completed"),x(),U({title:"Upload complete",description:"The video is now on your YouTube channel."})):(I(q),i("paused"),B({message:"The upload stopped before finishing.",resumable:!0}))}catch(q){const ae=q instanceof Ie?q:null;if((ae==null?void 0:ae.code)==="aborted")return;i("paused"),B({message:(ae==null?void 0:ae.message)??(q instanceof Error?q.message:"Unknown error"),resumable:(ae==null?void 0:ae.resumable)??!0})}},Ne=async()=>{if(!r||G){G&&U({title:"Check the details",description:G,variant:"destructive"});return}i("uploading"),B(null),j({bytes:0,total:r.size,chunkIndex:0,chunkCount:0});try{const l=await gs(r,X,ee.current);if(I(l),l.status==="completed"){A(l),i("completed"),x();return}await ne(l,r)}catch(l){const R=l instanceof Ie?l:null;i("form"),B({message:(R==null?void 0:R.message)??"Could not start the upload.",resumable:!1})}},be=async()=>{if(r)try{const l=$?await ta($.upload_id):await gs(r,X,ee.current);if(I(l),l.status==="completed"){A(l),i("completed"),x();return}if(l.status!=="uploading"){B({message:`This upload is ${l.status} and cannot be resumed. Start a new upload.`,resumable:!1});return}j(R=>({...R,bytes:l.bytes_received??0,total:l.file_size})),await ne(l,r)}catch(l){B({message:l instanceof Error?l.message:"Could not resume the upload.",resumable:l instanceof Ie?l.resumable:!0})}},Ce=async()=>{var l;if((l=p.current)==null||l.abort(),$)try{await aa($.upload_id),U({title:"Upload cancelled"})}catch{U({title:"Upload stopped",description:"The session could not be cancelled on YouTube."})}c(),a(!1)},we=d.total>0?Math.round(d.bytes/d.total*100):0,t=u==="uploading";return e.jsx(ks,{open:s,onOpenChange:l=>{if(!l&&t){U({title:"Upload in progress",description:"Cancel the upload before closing."});return}a(l)},children:e.jsxs(Cs,{className:"max-w-3xl max-h-[90vh] overflow-y-auto",children:[e.jsx(Ts,{children:e.jsx(Is,{className:"text-left pr-8",children:u==="completed"?"Upload complete":"Upload video to YouTube"})}),u==="completed"&&z?e.jsxs("div",{className:"space-y-4",children:[e.jsxs(Ue,{children:[e.jsx(mt,{className:"w-4 h-4"}),e.jsx(Me,{children:"Video published to your channel"}),e.jsx(Oe,{children:z.ownership_verified?"Ownership verified on the connected Tabir Academy channel.":"Ownership could not be verified â check the video in YouTube Studio."})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3 text-sm",children:[e.jsxs("div",{className:"rounded-xl border border-border/60 p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Requested visibility"}),e.jsx("p",{className:"font-medium capitalize",children:z.requested_privacy_status??"â"})]}),e.jsxs("div",{className:"rounded-xl border border-border/60 p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Actual YouTube visibility"}),e.jsx("p",{className:"font-medium capitalize",children:z.actual_privacy_status??"â"})]})]}),z.privacy_notice&&e.jsxs(Ue,{variant:"destructive",children:[e.jsx(Ye,{className:"w-4 h-4"}),e.jsx(Me,{children:"Visibility changed by YouTube"}),e.jsx(Oe,{children:z.privacy_notice})]}),z.video_id&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(k,{size:"sm",className:"gap-2",asChild:!0,children:e.jsxs("a",{href:`https://www.youtube.com/watch?v=${z.video_id}`,target:"_blank",rel:"noopener noreferrer",children:[e.jsx(is,{className:"w-4 h-4"})," Open on YouTube"]})}),e.jsxs(k,{variant:"outline",size:"sm",className:"gap-2",onClick:async()=>{await navigator.clipboard.writeText(`https://www.youtube.com/watch?v=${z.video_id}`),U({title:"Link copied"})},children:[e.jsx(ns,{className:"w-4 h-4"})," Copy URL"]}),e.jsx(k,{variant:"ghost",size:"sm",onClick:c,children:"Upload another"}),e.jsx(k,{variant:"ghost",size:"sm",onClick:()=>a(!1),children:"Done"})]})]}):e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{onDragOver:l=>{l.preventDefault(),t||T(!0)},onDragLeave:()=>T(!1),onDrop:l=>{var R;l.preventDefault(),T(!1),!t&&E(((R=l.dataTransfer.files)==null?void 0:R[0])??null)},className:`rounded-xl border-2 border-dashed p-6 text-center transition-colors ${f?"border-primary bg-primary/5":"border-border/60 bg-card/40"}`,children:[e.jsx("input",{ref:m,type:"file",accept:"video/mp4,video/quicktime,video/webm,video/x-matroska,video/x-msvideo,.mp4,.mov,.webm,.mkv,.avi",className:"hidden",onChange:l=>{var R;return E(((R=l.target.files)==null?void 0:R[0])??null)}}),r?e.jsxs("div",{className:"flex items-center justify-center gap-3 text-sm",children:[e.jsx(ht,{className:"w-5 h-5 text-primary"}),e.jsx("span",{className:"font-medium truncate max-w-[16rem]",children:r.name}),e.jsx(se,{variant:"outline",children:Ze(r.size)}),!t&&e.jsxs(k,{variant:"ghost",size:"sm",onClick:()=>v(null),className:"gap-1",children:[e.jsx(Ge,{className:"w-3.5 h-3.5"})," Remove"]})]}):e.jsxs(e.Fragment,{children:[e.jsx(rs,{className:"w-6 h-6 mx-auto text-muted-foreground"}),e.jsx("p",{className:"text-sm mt-2",children:"Drag and drop a video here"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"MP4, MOV, WebM, MKV or AVI â up to 2 GB"}),e.jsx(k,{variant:"outline",size:"sm",className:"mt-3",onClick:()=>{var l;return(l=m.current)==null?void 0:l.click()},children:"Choose file"})]})]}),(u==="uploading"||u==="paused")&&e.jsxs("div",{className:"space-y-2 rounded-xl border border-border/60 p-4",children:[e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsxs("span",{className:"flex items-center gap-2 font-medium",children:[t&&e.jsx(ie,{className:"w-4 h-4 animate-spin text-primary"}),t?"Uploading to YouTubeâ¦":"Upload paused"]}),e.jsxs("span",{className:"text-muted-foreground",children:[we,"%"]})]}),e.jsx(Le,{value:we}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[Ze(d.bytes)," of ",Ze(d.total),d.chunkCount>0&&` · chunk ${d.chunkIndex}/${d.chunkCount}`]}),e.jsxs("div",{className:"flex items-center gap-2 pt-1",children:[u==="paused"&&e.jsxs(k,{size:"sm",className:"gap-2",onClick:be,children:[e.jsx(pt,{className:"w-4 h-4"})," Retry / resume"]}),e.jsxs(k,{variant:"outline",size:"sm",className:"gap-2",onClick:Ce,children:[e.jsx(Ge,{className:"w-4 h-4"})," Cancel upload"]})]})]}),Y&&e.jsxs(Ue,{variant:"destructive",children:[e.jsx(Ye,{className:"w-4 h-4"}),e.jsx(Me,{children:Y.resumable?"Upload interrupted":"Upload failed"}),e.jsx(Oe,{children:Y.message})]}),e.jsxs("fieldset",{disabled:t,className:"space-y-5 disabled:opacity-60",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(le,{htmlFor:"yt-up-title",children:"Title"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[h.length,"/100"]})]}),e.jsx(de,{id:"yt-up-title",value:h,maxLength:100,onChange:l=>g(l.target.value),placeholder:"Video title"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(le,{htmlFor:"yt-up-desc",children:"Description"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[C.length,"/5000"]})]}),e.jsx(Es,{id:"yt-up-desc",value:C,maxLength:5e3,rows:6,onChange:l=>y(l.target.value),placeholder:"What students will learn in this videoâ¦"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(le,{children:"Tags"}),e.jsx("div",{className:"flex flex-wrap gap-1.5",children:_.map(l=>e.jsxs(se,{variant:"secondary",className:"font-normal gap-1",children:[l,e.jsx("button",{type:"button","aria-label":`Remove tag ${l}`,onClick:()=>N(_.filter(R=>R!==l)),children:e.jsx(Ge,{className:"w-3 h-3"})})]},l))}),e.jsx(de,{value:S,placeholder:"Add a tag and press Enter",onChange:l=>L(l.target.value),onKeyDown:l=>{(l.key==="Enter"||l.key===",")&&(l.preventDefault(),D())}}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[_.join(",").length,"/500 characters used by tags"]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(le,{children:"Category"}),e.jsxs(ge,{value:V,onValueChange:w,children:[e.jsx(fe,{children:e.jsx(je,{placeholder:"Select category"})}),e.jsx(ve,{children:(o.length?o:[{id:"27",title:"Education"}]).map(l=>e.jsx(Z,{value:l.id,children:l.title},l.id))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(le,{htmlFor:"yt-up-schedule",children:"Scheduled publish (optional)"}),e.jsx(de,{id:"yt-up-schedule",type:"datetime-local",value:F,onChange:l=>W(l.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Requires Private visibility."})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(le,{children:"Visibility"}),e.jsx(cs,{value:O,onValueChange:l=>b(l),className:"grid gap-2",children:[["private","Private â only you and invited accounts"],["unlisted","Unlisted â anyone with the link"],["public","Public â visible to everyone"]].map(([l,R])=>e.jsxs("label",{className:"flex items-center gap-3 rounded-lg border border-border/60 px-3 py-2 text-sm cursor-pointer",children:[e.jsx(ds,{value:l,id:`yt-up-${l}`}),R]},l))})]}),e.jsxs("div",{className:"flex items-center justify-between rounded-xl border border-border/60 p-3",children:[e.jsxs("div",{children:[e.jsx(le,{htmlFor:"yt-up-kids",children:"Made for kids"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Required audience declaration."})]}),e.jsx(It,{id:"yt-up-kids",checked:J,onCheckedChange:te})]})]}),u==="form"&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(k,{className:"gap-2",onClick:Ne,disabled:!!G,children:[e.jsx(rs,{className:"w-4 h-4"})," Start upload"]}),e.jsx(k,{variant:"ghost",onClick:()=>a(!1),children:"Cancel"}),G&&e.jsx("span",{className:"text-xs text-muted-foreground",children:G})]})]})]})})},la=12,oa=ke.map(s=>({slug:s.slug,title:s.title})),Ks=new Intl.NumberFormat("en-US"),ze=s=>s==null||s===""?"â":Ks.format(Number(s)),Qe=s=>s?new Date(s).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"}):"â",fs=s=>{if(!s)return"â";const a=s.match(/PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/);if(!a)return"â";const[o,x,r]=[Number(a[1]??0),Number(a[2]??0),Number(a[3]??0)],v=f=>String(f).padStart(2,"0");return o>0?`${o}:${v(x)}:${v(r)}`:`${x}:${v(r)}`},js=s=>s==="public"?"secondary":s==="unlisted"?"outline":"destructive",ca=()=>{var p;const[s,a]=n.useState([]),[o,x]=n.useState(!0),[r,v]=n.useState(""),[f,T]=n.useState(0),[m,h]=n.useState([null]),[g,C]=n.useState(null),[y,_]=n.useState(null),[N,S]=n.useState({}),[L,V]=n.useState([]),[w,O]=n.useState(!1),[b,F]=n.useState(null),[W,J]=n.useState(!1),[te,u]=n.useState(!1),[i,d]=n.useState({total:0,done:0,failures:[],running:!1,
8current:null}),j=n.useCallback(async c=>{x(!0);try{const E=new URLSearchParams({action:"videos",limit:String(la)});c&&E.set("page_token",c);const{data:D,error:G}=await M.functions.invoke(`youtube-api?${E.toString()}`,{method:"GET"});if(G)throw new Error("Could not load videos");const X=D;return a(X.videos??[]),C(X.next_page_token??null),_(X.total_results??null),X.next_page_token??null}catch(E){return U({title:"Video library unavailable",description:E instanceof Error?E.message:"Unknown error",variant:"destructive"}),null}finally{x(!1)}},[]);n.useEffect(()=>{j(null),(async()=>{const{data:c,error:E}=await M.functions.invoke("youtube-api?action=categories",{method:"GET"});if(!E){const D=(c==null?void 0:c.categories)??[];V(D),S(Object.fromEntries(D.map(G=>[G.id,G.title])))}})()},[j]);const $=async()=>{if(!g)return;const c=g,E=await j(c);h(D=>{const G=[...D];return G[f+1]=c,G}),T(D=>D+1),C(E)},I=async()=>{if(f===0)return;const c=m[f-1]??null;await j(c),T(E=>E-1)},z=async()=>{h([null]),T(0),await j(null)},A=async(c,E=!1)=>{F(c),O(E),J(!0);try{const{data:D,error:G}=await M.functions.invoke(`youtube-api?action=video&id=${encodeURIComponent(c.id)}`,{method:"GET"});if(G)throw new Error("Could not load video details");const X=D==null?void 0:D.video;X&&F(X)}catch(D){U({title:"Details unavailable",description:D instanceof Error?D.message:"Unknown error",variant:"destructive"})}finally{J(!1)}};n.useEffect(()=>{const c=async E=>{const D=E.detail,G=D==null?void 0:D.videoId;if(!G)return;const X=s.find(ne=>ne.id===G);if(X){await A(X,!0);return}F({id:G,title:null,url:`https://www.youtube.com/watch?v=${G}`}),O(!0),J(!0);try{const{data:ne,error:Ne}=await M.functions.invoke(`youtube-api?action=video&id=${encodeURIComponent(G)}`,{method:"GET"});if(Ne)throw new Error("Could not load video details");const be=ne==null?void 0:ne.video;be&&F(be)}catch(ne){U({title:"Details unavailable",description:ne instanceof Error?ne.message:"Unknown error",variant:"destructive"})}finally{J(!1)}};return window.addEventListener("yt-open-video",c),()=>window.removeEventListener("yt-open-video",c)},[s]);const Y=async()=>{const c=ee;if(c.length!==0){d({total:c.length,done:0,failures:[],running:!0,current:null});for(let E=0;E<c.length;E++){const D=c[E];d(G=>({...G,current:D.title??D.id}));try{const{data:G,error:X}=await M.functions.invoke("youtube-analyze",{body:{id:D.id,refresh:!1,guides:oa}});if(X)throw new Error("Analysis failed");if(G!=null&&G.error)throw new Error(String(G.error))}catch(G){d(X=>({...X,failures:[...X.failures,`${D.title??D.id}: ${G instanceof Error?G.message:"failed"}`]}))}d(G=>({...G,done:E+1}))}d(E=>
8({...E,running:!1,current:null})),U({title:"Bulk analysis finished",description:"Open any video's SEO panel to review the saved recommendations. Nothing was published to YouTube."})}},B=async c=>{await navigator.clipboard.writeText(c),U({title:"Link copied"})},ee=n.useMemo(()=>{const c=r.trim().toLowerCase();return c?s.filter(E=>(E.title??"").toLowerCase().includes(c)||(E.description??"").toLowerCase().includes(c)||E.tags.some(D=>D.toLowerCase().includes(c))):s},[s,r]);return e.jsxs(e.Fragment,{children:[e.jsxs(me,{className:"border-border/60",children:[e.jsxs(he,{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-3 space-y-0",children:[e.jsxs(pe,{className:"text-lg font-display flex items-center gap-2",children:[e.jsx(ws,{className:"w-5 h-5 text-primary"})," Video library",y!=null&&e.jsxs(se,{variant:"outline",className:"ml-1 font-normal",children:[Ks.format(y)," videos"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{className:"relative",children:[e.jsx(xt,{className:"w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground"}),e.jsx(de,{value:r,onChange:c=>v(c.target.value),placeholder:"Search this pageâ¦",className:"pl-9 w-full sm:w-56"})]}),e.jsxs(k,{variant:"outline",size:"sm",className:"gap-2",onClick:z,disabled:o,children:[o?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(Ee,{className:"w-4 h-4"}),"Refresh"]}),e.jsxs(k,{variant:"outline",size:"sm",className:"gap-2",onClick:Y,disabled:i.running||o||s.length===0,children:[i.running?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(ye,{className:"w-4 h-4"}),"Analyze existing videos"]}),e.jsxs(k,{size:"sm",className:"gap-2",onClick:()=>u(!0),children:[e.jsx(rs,{className:"w-4 h-4"})," Upload"]})]})]}),e.jsxs(xe,{className:"space-y-4",children:[(i.running||i.done>0)&&e.jsxs("div",{className:"rounded-xl border border-primary/25 bg-primary/5 p-3 space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 text-xs",children:[e.jsxs("span",{className:"font-medium",children:["AI SEO analysis ",i.done,"/",i.total,i.current?` â ${i.current}`:i.running?"":" â finished"]}),e.jsx("span",{className:"text-muted-foreground",children:"Results are saved; no YouTube metadata is changed."})]}),e.jsx(Le,{value:i.total?i.done/i.total*100:0}),i.failures.length>0&&e.jsx("ul",{className:"text-xs text-destructive space-y-0.5",children:i.failures.map((c,E)=>e.jsx("li",{children:c},E))})]}),o&&s.length===0?e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4",children:[0,1,2,3,4,5].map(c=>e.jsx(Se,{className:"h-52 w-full rounded-xl"},c))}):ee.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No videos match this view."}):e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4",children:ee.map(c=>e.jsxs("div",{className:"group rounded-xl border border-border/60 bg-card/60 overflow-hidden hover:border-primary/50 transition-colors flex flex-col",children:[e.jsxs("button",{type:"button",onClick:()=>A(c),className:"text-left relative","aria-label":`Open details for ${c.title??"video"}`,children:[c.thumbnail&&e.jsx("img",{src:c.thumbnail,alt:c.title??"Video thumbnail",className:"w-full aspect-video object-cover",loading:"lazy"}),e.jsx("span",{className:"absolute bottom-2 right-2 rounded bg-background/90 px-1.5 py-0.5 text-[11px] font-medium",children:fs(c.duration)})]}),e.jsxs("div",{className:"p-3 space-y-2 flex-1 flex flex-col",children:[e.jsx("button",{type:"button",onClick:()=>A(c),className:"text-sm font-medium line-clamp-2 text-left group-hover:text-primary transition-colors",children:c.title??"Untitled"}),e.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[e.jsx("span",{children:Qe(c.published_at)}),e.jsx(se,{variant:js(c.privacy_status),className:"capitalize",children:c.privacy_status??"unknown"})]}),e.jsxs("div",{className:"flex items-center gap-3 text-xs text-muted-foreground",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Ve,{className:"w-3.5 h-3.5"})," ",ze(c.view_count)]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(hs,{className:"w-3.5 h-3.5"})," ",ze(c.like_count)]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(ps,{className:"w-3.5 h-3.5"})," ",ze(c.comment_count)]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1 mt-auto pt-1",children:[e.jsxs(k,{variant:"ghost",size:"sm",className:"gap-1.5 px-2 text-primary",onClick:()=>A(c,!0),children:[e.jsx(ye,{className:"w-3.5 h-3.5"})," AI SEO"]}),e.jsx(k,{variant:"ghost",size:"sm",className:"gap-1.5 px-2",asChild:!0,children:e.jsxs("a",{href:c.url,target:"_blank",rel:"noopener noreferrer",children:[e.jsx(is,{className:"w-3.5 h-3.5"})," YouTube"]})}),e.jsxs(k,{variant:"ghost",size:"sm",className:"gap-1.5 px-2",onClick:()=>B(c.url),children:[e.jsx(ns,{className:"w-3.5 h-3.5"})," Copy URL"]})]})]})]},c.id))}),e.jsxs("div",{className:"flex items-center justify-between pt-2",children:[e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Page ",f+1]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(k,{variant:"outline",size:"sm",className:"gap-1",onClick:I,disabled:f===0||o,children:[e.jsx(gt,{className:"w-4 h-4"})," Previous"]}),e.jsxs(k,{variant:"outline",size:"sm",className:"gap-1",onClick:$,disabled:!g||o,children:["Next ",e.jsx(ft,{className:"w-4 h-4"})]})]})]})]})]}),e.jsx(ks,{open:!!b,onOpenChange:c=>{c||(F(null),O(!1))},children:e.jsxs(Cs,{className:"max-w-3xl max-h-[90vh] overflow-y-auto",children:[e.jsx(Ts,{children:e.jsx(Is,{className:"pr-8 text-left",children:w?"Edit video":(b==null?void 0:b.title)??"Video details"})}),b&&w&&e.jsx(Wt,{video:b,categories:L,onSaved:c=>{F(c),a(E=>E.map(D=>D.id===c.id?{...D,...c}:D)),O(!1)},onCancel:()=>O(!1)}),b&&!w&&e.jsxs("div",{className:"space-y-5",children:[(b.thumbnail_large??b.thumbnail)&&e.jsx("img",{src:b.thumbnail_large??b.thumbnail,alt:b.title??"Video thumbnail",className:"w-full rounded-xl border border-border/60"}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[e.jsx(se,{variant:js(b.privacy_status),className:"capitalize",children:b.privacy_status??"unknown"}),b.publish_at&&e.jsxs(se,{variant:"outline",children:["Scheduled ",Qe(b.publish_at)]}),e.jsxs(se,{variant:"outline",className:"gap-1",children:[e.jsx(jt,{className:"w-3 h-3"})," ",fs(b.duration)]}),e.jsxs("span",{className:"text-muted-foreground",children:["Published ",Qe(b.published_at)]}),W&&e.jsx(ie,{className:"w-4 h-4 animate-spin text-muted-foreground"})]}),e.jsx("div",{className:"grid grid-cols-3 gap-3",children:[{label:"Views",value:b.view_count,icon:Ve},{label:"Likes",value:b.like_count,icon:hs},{label:"Comments",value:b.comment_count,icon:ps}].map(c=>{const E=c.icon;return e.jsxs("div",{className:"rounded-xl border border-border/60 bg-card/60 p-3",children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-[11px] uppercase tracking-wide text-muted-foreground",children:[e.jsx(E,{className:"w-3.5 h-3.5"})," ",c.label]}),e.jsx("p",{className:"text-xl font-bold mt-1",children:ze(c.value)})]},c.label)})}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3 text-sm",children:[e.jsxs("div",{className:"rounded-xl border border-border/60 p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Category"}),e.jsx("p",{className:"font-medium",children:b.category_id?N[b.category_id]??b.category_id:"â"})]}),e.jsxs("div",{className:"rounded-xl border border-border/60 p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Made for kids"}),e.jsx("p",{className:"font-medium",children:b.made_for_kids==null?"â":b.made_for_kids?"Yes":b.self_declared_made_for_kids?"Self-declared yes":"No"})]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs uppercase tracking-wide text-muted-foreground mb-1",children:"Description"}),e.jsx("p",{className:"text-sm whitespace-pre-wrap text-muted-foreground",children:((p=b.description)==null?void 0:p.trim())||"No description."})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs uppercase tracking-wide text-muted-foreground mb-2",children:"Tags"}),b.tags.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No tags."}):e.jsx("div",{className:"flex flex-wrap gap-1.5",children:b.tags.map(c=>e.jsx(se,{variant:"secondary",className:"font-normal",children:c},c))})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(k,{size:"sm",className:"gap-2",onClick:()=>O(!0),children:[e.jsx(vt,{className:"w-4 h-4"})," Edit video"]}),e.jsx(k,{variant:"outline",size:"sm",className:"gap-2",asChild:!0,children:e.jsxs("a",{href:b.url,target:"_blank",rel:"noopener noreferrer",children:[e.jsx(is,{className:"w-4 h-4"})," Open on YouTube"]})}),e.jsxs(k,{variant:"ghost",size:"sm",className:"gap-2",onClick:()=>B(b.url),children:[e.jsx(ns,{className:"w-4 h-4"})," Copy URL"]})]})]})]})}),e.jsx(ra,{open:te,onOpenChange:u,categories:L,onUploaded:z})]})},Ae=s=>{const a=Number(s);return Number.isFinite(a)?a:0},Hs=s=>s>=75?"Critical":s>=55?"High":s>=35?"Medium":"Low";function Js(s){const a=`${s.title??""} ${(s.tags??[]).join(" ")}`.toLowerCase();return ke.filter(o=>{const x=o.title.toLowerCase().split(/[^a-z0-9]+/).filter(r=>r.length>=4);return x.length>0&&x.every(r=>a.includes(r))}).map(o=>o.slug)}function da(s,a,o){const x=new Map(a.map(m=>[m.video_id,m])),r=new Map;for(const m of o)r.set(m.youtube_video_id,[...r.get(m.youtube_video_id)??[],m.guide_slug]);const v=s.map(m=>{var S,L;const h=Ae(m.view_count),g=m.published_at?new Date(m.published_at).getTime():Date.now(),C=Math.max((Date.now()-g)/864e5,0),y=h/Math.max(C,1),_=x.get(m.id)??null,N=(m.description??"").toLowerCase();return{video:m,views:h,likes:Ae(m.like_count),comments:Ae(m.comment_count),daysSincePublish:Math.floor(C),viewsPerDay:y,paceIndex:0,engagementRate:h>0?(Ae(m.like_count)+Ae(m.comment_count))/h:null,analysis:_,seoScore:(_==null?void 0:_.seo_score)??null,subject:((L=(S=_==null?void 0:_.analysis)==null?void 0:S.content)==null?void 0:L.subject)??null,recommendedGuide:(_==null?void 0:_.recommended_guide_slug)??null,attachedGuides:r.get(m.id)??[],hasGuideCta:N.includes("tabiracademy.com"),isPublic:m.privacy_status==="public"}}),f=m=>m<=30?"new":m<=180?"recent":"old",T=new Map;for(const m of["new","recent","old"]){const h=v.filter(g=>f(g.daysSincePublish)===m).map(g=>g.viewsPerDay);T.set(m,h.length?h.reduce((g,C)=>g+C,0)/h.length:0)}for(const m of v){const h=T.get(f(m.daysSincePublish))??0;m.paceIndex=h>0?Math.min(Math.round(m.viewsPerDay/h*100),999):0}return v}const es=s=>{var a;return((a=ke.find(o=>o.slug===s))==null?void 0:a.title)??s},ua=s=>{var a;return((a=ke.find(o=>o.slug===s))==null?void 0:a.tier)??4};function ma(s){var o,x,r,v,f,T,m;const a=[];for(const h of s){const g=[],C=[];if(!h.analysis)g.push({label:"Never analysed with AI",points:20}),C.push("No saved AI SEO analysis yet â its metadata has never been assessed.");else{const N=h.seoScore??100;N<45?(g.push({label:`SEO score ${N}/100 (low)`,points:30}),C.push(`AI SEO score is ${N}/100 â title, description or tags are holding it back.`)):N<70&&(g.push({label:`SEO score ${N}/100 (medium)`,points:15}),C.push(`AI SEO score is ${N}/100 â there is measurable room to improve.`));const S=!h.video.description||(h.video.tags??[]).length===0,L=!!((r=(x=(o=h.analysis.analysis)==null?void 0:o.content)==null?void 0:x.key_concepts)!=null&&r.length);S&&L&&(g.push({label:"Strong teaching content, thin metadata",points:20}),C.push("The transcript shows solid teaching, but the description/tags give search engines little to index."));const V=h.recommendedGuide,w=Number(((f=(v=h.analysis.analysis)==null?void 0:v.guide)==null?void 0:f.confidence)??0),O=Math.round(w<=1?w*100:w);if(V&&!h.attachedGuides.includes(V)){const F=O>=70?20:12;g.push({label:`Strong guide match not attached (${es(V)})`,points:F}),C.push(`AI matched this video to the ${es(V)} guide (${O}% confidence) but it is not attached.`)}!h.hasGuideCta&&h.isPublic&&(g.push({label:"Description has no Tabir guide link",points:10}
8),C.push("The YouTube description contains no link back to a Tabir guide, so the video sends no traffic to the site."));const b=(m=(T=h.analysis.analysis)==null?void 0:T.seo)==null?void 0:m.recommended_title;b&&h.video.title&&b.trim()!==h.video.title.trim()&&(h.video.title.trim().length<35||/lec\s*\d+|^\W|part\s*\d+$/i.test(h.video.title))&&(g.push({label:"Title much weaker than AI recommendation",points:15}),C.push("The current title is shorthand/generic compared with the AI recommendation students would actually search for."))}h.paceIndex>=150?(g.push({label:`Above-average reach for its age (pace ${h.paceIndex}%)`,points:10}),C.push(`It is running at ${h.paceIndex}% of the average daily views for videos of its age, so improvements compound.`)):h.views>=100&&g.push({label:`${h.views.toLocaleString()} lifetime views`,points:5});const y=h.recommendedGuide??h.attachedGuides[0]??Js(h.video)[0]??null;if(y){const N=ua(y),S=N===1?10:N===2?6:3;g.push({label:`${es(y)} guide (tier ${N})`,points:S})}const _=Math.min(g.reduce((N,S)=>N+S.points,0),100);_<15||C.length===0||a.push({videoId:h.video.id,title:h.video.title??h.video.id,priority:Hs(_),score:_,reasons:C,factors:g,needsAnalysis:!h.analysis,attachSlug:h.recommendedGuide&&!h.attachedGuides.includes(h.recommendedGuide)?h.recommendedGuide:null})}return a.sort((h,g)=>g.score-h.score)}function ha(s,a){const o=new Map;for(const r of a)o.set(r.guide_slug,(o.get(r.guide_slug)??0)+1);const x=new Map;for(const r of s)for(const v of new Set([...Js(r.video),...r.recommendedGuide?[r.recommendedGuide]:[]]))x.set(v,[...x.get(v)??[],r.video.title??r.video.id]);return ke.map(r=>{const v=o.get(r.slug)??0,f=x.get(r.slug)??[],T=v>0,m=(T?0:40)+(f.length===0?20:0)+(r.tier===1?30:r.tier===2?18:r.tier===3?8:4);return{slug:r.slug,title:r.title,tier:r.tier,videoCount:v,hasVideo:T,matchedVideos:f.slice(0,4),priority:Hs(m),suggestedTopics:T?[`Additional chapter/topic coverage for ${r.title}`]:f.length>0?[`Attach the existing ${r.title}-related video(s) to this guide`]:[`Full ${r.title} walkthrough`,`${r.title} test pattern & scoring explainer`]}}).sort((r,v)=>v.priority.localeCompare(r.priority)||r.tier-v.tier||Number(r.hasVideo)-Number(v.hasVideo))}const De=s=>s==="Critical"?"destructive":s==="High"?"default":s==="Medium"?"secondary":"outline",re=new Intl.NumberFormat("en-US"),vs=ke.map(s=>({slug:s.slug,title:s.title,tier:s.tier})),$e=(s,a)=>window.dispatchEvent(new CustomEvent("yt-open-video",{detail:{videoId:s,mode:a}})),ue=({label:s,value:a,hint:o})=>e.jsxs("div",{className:"rounded-lg border bg-background/70 px-3 py-2",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-muted-foreground",children:s}),e.jsx("p",{className:"text-xl font-bold",children:a}),o&&e.jsx("p",{className:"text-[11px] text-muted-foreground",children:o})]}),pa=()=>{const[s,a]=n.useState(!0),[o,x]=n.useState([]),[r,v]=n.useState([]),[f,T]=n.useState([]),[m,h]=n.useState({views:null,subs:null,count:null}),[g,C]=n.useState(null),[y,_]=n.useState(null),[N,S]=n.useState(null),[L,V]=n.useState(!1),[w,O]=n.useState(""),[b,F]=n.useState("all"),[W,J]=n.useState("all"),[te,u]=n.useState("all"),[i,d]=n.useState("all"),[j,$]=n.useState("all"),[I,z]=n.useState("all"),[A,Y]=n.useState(new Set),B=t=>{Y(l=>{const R=new Set(l);return R.has(t)?R.delete(t):R.add(t),R})},ee=n.useCallback(async()=>{var t,l,R;a(!0);try{const[ce,q,ae,P,K]=await Promise.all([M.functions.invoke("youtube-api?action=channel",{method:"GET"}),M.functions.invoke("youtube-api?action=allVideos&max=250",{method:"GET"}),M.from("youtube_video_analyses").select("video_id, video_title, seo_score, recommended_guide_slug, analysis, analyzed_at"),M.from("guide_videos").select("guide_slug, youtube_video_id, is_published"),M.rpc("get_youtube_traffic",{_days:90})]);if(!ce.error){const oe=((t=ce.data)==null?void 0:t.statistics)??{};h({views:oe.view_count!=null?Number(oe.view_count):null,subs:oe.subscriber_count!=null?Number(oe.subscriber_count):null,count:oe.video_count!=null?Number(oe.video_count):null})}if(q.error)throw new Error("Could not load the video library");x(((l=q.data)==null?void 0:l.videos)??[]),v((ae==null?void 0:ae.data)??[]),T(((P==null?void 0:P.data)??[]).filter(oe=>!!oe.youtube_video_id)),C(K!=null&&K.error?null:(K==null?void 0:K.data)??null);const H=await M.functions.invoke("youtube-analyze",{body:{mode:"content_plan",cache_only:!0}});!H.error&&((R=H.data)!=null&&R.plan)&&(_(H.data.plan),S({generated_at:H.data.generated_at,cached:!0}))}catch(ce){U({title:"Growth intelligence unavailable",description:ce instanceof Error?ce.message:"Unknown error",variant:"destructive"})}finally{a(!1)}},[]);n.useEffect(()=>{ee()},[ee]);const p=n.useMemo(()=>da(o,r,f),[o,r,f]),c=n.useMemo(()=>ma(p),[p]),E=n.useMemo(()=>ha(p,f),[p,f]),D=n.useMemo(()=>Array.from(new Set(p.map(t=>
8t.subject).filter(Boolean))),[p]),G=n.useMemo(()=>p.filter(t=>{const l=w.trim().toLowerCase();return!(l&&!(t.video.title??"").toLowerCase().includes(l)||b!=="all"&&t.subject!==b||W!=="all"&&!t.attachedGuides.includes(W)&&t.recommendedGuide!==W||te==="over"&&t.paceIndex<120||te==="under"&&t.paceIndex>=80||i==="low"&&!(t.seoScore!=null&&t.seoScore<45)||i==="medium"&&!(t.seoScore!=null&&t.seoScore>=45&&t.seoScore<70)||i==="high"&&!(t.seoScore!=null&&t.seoScore>=70)||i==="none"&&t.seoScore!=null||j==="public"&&!t.isPublic||j==="private"&&t.isPublic||I==="linked"&&t.attachedGuides.length===0||I==="unlinked"&&t.attachedGuides.length>0)}).sort((t,l)=>l.paceIndex-t.paceIndex),[p,w,b,W,te,i,j,I]),X=p.filter(t=>t.analysis).reduce((t,l)=>t+l.views,0),ne=p.reduce((t,l)=>t+l.views,0),Ne=new Set(f.map(t=>t.youtube_video_id)).size,be=p.filter(t=>t.seoScore!=null&&t.seoScore<70).length,Ce=async()=>{var t;V(!0);try{const l=new Map;for(const q of f)l.set(q.guide_slug,(l.get(q.guide_slug)??0)+1);const{data:R,error:ce}=await M.functions.invoke("youtube-analyze",{body:{mode:"content_plan",refresh:!0,guides:vs.map(q=>({...q,videos:l.get(q.slug)??0})),library:p.map(q=>({title:q.video.title,views:q.views,published_at:q.video.published_at,guide:q.attachedGuides[0]??null})),analyses:r.map(q=>{var ae,P;return{title:q.video_title,subject:((P=(ae=q.analysis)==null?void 0:ae.content)==null?void 0:P.subject)??null,score:q.seo_score,guide:q.recommended_guide_slug}})}});if(ce)throw new Error("The AI content plan request failed");_(R.plan),S({generated_at:(t=R==null?void 0:R.provenance)==null?void 0:t.generated_at,cached:!1}),U({title:"Content opportunities generated"})}catch(l){U({title:"Could not generate content opportunities",description:l instanceof Error?l.message:"Unknown error",variant:"destructive"})}finally{V(!1)}},we=n.useMemo(()=>{const t=[];for(const l of c.slice(0,6))t.push({text:l.needsAnalysis?`Analyse "${l.title}" with AI`:`Optimize "${l.title}"`,reason:l.reasons.join(" "),videoId:l.videoId,priority:l.priority});for(const l of E.filter(R=>!R.hasVideo&&R.tier===1).slice(0,4))t.push({text:`Create a video for the ${l.title} guide`,reason:`Tier-1 guide with no YouTube video attached${l.matchedVideos.length?` (existing related uploads: ${l.matchedVideos.join(", ")})`:""}.`,slug:l.slug,priority:l.priority});return t.slice(0,10)},[c,E]);return s?e.jsxs(me,{children:[e.jsx(he,{children:e.jsx(pe,{children:"YouTube Growth Intelligence"})}),e.jsx(xe,{className:"space-y-3",children:[0,1,2].map(t=>e.jsx(Se,{className:"h-16 w-full"},t))})]}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs(me,{children:[e.jsxs(he,{className:"flex flex-row items-center justify-between gap-3",children:[e.jsxs(pe,{className:"flex items-center gap-2 text-base",children:[e.jsx(yt,{className:"w-4 h-4 text-primary"})," YouTube Growth Intelligence"]}),e.jsxs(k,{size:"sm",variant:"outline",className:"gap-2",onClick:ee,children:[e.jsx(Ee,{className:"w-4 h-4"})," Reload data"]})]}),e.jsxs(xe,{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-2 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(ue,{label:"Subscribers",value:m.subs!=null?re.format(m.subs):"â",hint:"YouTube"}),e.jsx(ue,{label:"Channel views",value:m.views!=null?re.format(m.views):"â",hint:"YouTube"}),e.jsx(ue,{label:"Videos on channel",value:m.count!=null?re.format(m.count):"â",hint:"YouTube"}),e.jsx(ue,{label:"Views across library",value:re.format(ne),hint:`${p.length} videos read`}),e.jsx(ue,{label:"Average views / video",value:p.length?re.format(Math.round(ne/p.length)):"â",hint:"Derived metric"}),e.jsx(ue,{label:"Videos analysed with AI",value:re.format(r.length),hint:`${re.format(X)} views covered`}),e.jsx(ue,{label:"Needing SEO improvement",value:re.format(be),hint:"Derived: saved SEO score < 70"}),e.jsx(ue,{label:"Videos linked to guides",value:re.format(Ne),hint:"guide_videos"})]}),e.jsxs("p",{className:"text-[11px] text-muted-foreground flex items-start gap-1.5",children:[e.jsx(ts,{className:"w-3.5 h-3.5 mt-0.5 shrink-0"}),"Subscribers, views, video counts, likes and comments are real YouTube API values. Views/day, pace index, engagement rate, priority scores and gap priorities are ",e.jsx("strong",{children:"derived metrics"})," calculated from that data plus saved AI analyses. No search-volume or impression figures are shown â no such data source is connected."]})]})]}),e.jsxs(me,{className:"border-primary/30 bg-primary/5",children:[e.jsx(he,{children:e.jsxs(pe,{className:"flex items-center gap-2 text-base",children:[e.jsx(bt,{className:"w-4 h-4 text-primary"})," Recommended next actions"]})}),e.jsxs(xe,{className:"space-y-3",children:[we.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"Nothing pressing â every anal
8ysed video looks healthy."}),we.map((t,l)=>e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3 rounded-lg border bg-background/70 p-3",children:[e.jsxs("div",{className:"min-w-[240px] flex-1",children:[e.jsxs("p",{className:"text-sm font-medium",children:[l+1,". ",t.text]}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-0.5",children:["Reason: ",t.reason]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(se,{variant:De(t.priority),children:t.priority}),t.videoId&&e.jsx(k,{size:"sm",variant:"outline",onClick:()=>$e(t.videoId,"seo"),children:"Open SEO assistant"}),t.slug&&e.jsx(k,{size:"sm",variant:"outline",asChild:!0,children:e.jsx("a",{href:`/${t.slug}`,target:"_blank",rel:"noreferrer",children:"View guide"})})]})]},l))]})]}),e.jsxs(me,{children:[e.jsx(he,{children:e.jsxs(pe,{className:"flex items-center gap-2 text-base",children:[e.jsx(Nt,{className:"w-4 h-4 text-primary"})," Video performance intelligence"]})}),e.jsxs(xe,{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-2 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(de,{placeholder:"Search titleâ¦",value:w,onChange:t=>O(t.target.value)}),e.jsxs(ge,{value:b,onValueChange:F,children:[e.jsx(fe,{children:e.jsx(je,{placeholder:"Subject"})}),e.jsxs(ve,{children:[e.jsx(Z,{value:"all",children:"All subjects"}),D.map(t=>e.jsx(Z,{value:t,children:t},t))]})]}),e.jsxs(ge,{value:W,onValueChange:J,children:[e.jsx(fe,{children:e.jsx(je,{placeholder:"Guide"})}),e.jsxs(ve,{className:"max-h-72",children:[e.jsx(Z,{value:"all",children:"All guides"}),vs.map(t=>e.jsx(Z,{value:t.slug,children:t.title},t.slug))]})]}),e.jsxs(ge,{value:te,onValueChange:u,children:[e.jsx(fe,{children:e.jsx(je,{placeholder:"Performance"})}),e.jsxs(ve,{children:[e.jsx(Z,{value:"all",children:"Any performance"}),e.jsx(Z,{value:"over",children:"Above average pace for its age"}),e.jsx(Z,{value:"under",children:"Below average pace for its age"})]})]}),e.jsxs(ge,{value:i,onValueChange:d,children:[e.jsx(fe,{children:e.jsx(je,{placeholder:"SEO score"})}),e.jsxs(ve,{children:[e.jsx(Z,{value:"all",children:"Any SEO score"}),e.jsx(Z,{value:"low",children:"Low (< 45)"}),e.jsx(Z,{value:"medium",children:"Medium (45â69)"}),e.jsx(Z,{value:"high",children:"Good (70+)"}),e.jsx(Z,{value:"none",children:"Not analysed"})]})]}),e.jsxs(ge,{value:j,onValueChange:$,children:[e.jsx(fe,{children:e.jsx(je,{placeholder:"Visibility"})}),e.jsxs(ve,{children:[e.jsx(Z,{value:"all",children:"Published & unpublished"}),e.jsx(Z,{value:"public",children:"Public only"}),e.jsx(Z,{value:"private",children:"Private / unlisted"})]})]}),e.jsxs(ge,{value:I,onValueChange:z,children:[e.jsx(fe,{children:e.jsx(je,{placeholder:"Guide link"})}),e.jsxs(ve,{children:[e.jsx(Z,{value:"all",children:"Any guide status"}),e.jsx(Z,{value:"linked",children:"Has guide"}),e.jsx(Z,{value:"unlinked",children:"No guide"})]})]})]}),e.jsxs("div",{className:"overflow-x-auto",children:[e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-left text-xs uppercase tracking-wide text-muted-foreground",children:[e.jsx("th",{className:"py-2 pr-3",children:"Video"}),e.jsx("th",{className:"py-2 pr-3",children:"Views"}),e.jsx("th",{className:"py-2 pr-3",children:"Views/day*"}),e.jsx("th",{className:"py-2 pr-3",children:"Pace*"}),e.jsx("th",{className:"py-2 pr-3",children:"Engagement*"}),e.jsx("th",{className:"py-2 pr-3",children:"SEO"}),e.jsx("th",{className:"py-2 pr-3",children:"Guide"}),e.jsx("th",{className:"py-2"})]})}),e.jsx("tbody",{children:G.map(t=>{const l=A.has(t.video.id);return e.jsxs(e.Fragment,{children:[e.jsxs("tr",{className:"border-t align-top cursor-pointer hover:bg-muted/40 transition-colors",onClick:()=>B(t.video.id),children:[e.jsx("td",{className:"py-2 pr-3 max-w-[280px]",children:e.jsxs("div",{className:"flex items-start gap-2",children:[l?e.jsx(_s,{className:"w-4 h-4 text-muted-foreground mt-0.5 shrink-0"}):e.jsx(Ss,{className:"w-4 h-4 text-muted-foreground mt-0.5 shrink-0"}),e.jsxs("div",{children:[e.jsx("p",{className:"font-medium line-clamp-2",children:t.video.title??t.video.id}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[t.daysSincePublish,"d old · ",t.video.privacy_status??"â",t.subject?` · ${t.subject}`:""]})]})]})}),e.jsx("td",{className:"py-2 pr-3",children:re.format(t.views)}),e.jsx("td",{className:"py-2 pr-3 text-muted-foreground",children:t.viewsPerDay.toFixed(2)}),e.jsx("td",{className:"py-2 pr-3 text-muted-foreground",children:t.paceIndex?`${t.paceIndex}%`:"â"}),e.jsx("td",{className:"py-2 pr-3 text-muted-foreground",children:t.engagementRate!=null?`${(t.engagementRate*100).toFixed(1)}%`:"â"}),e.jsx("td",{className:"py-2 pr-3",children:t.seoScore??"â"}),e.jsx("td",{className:"py-2 pr-3 text-xs text-muted-foreground",children:t.attachedGuides.length>0?t.attachedGuides.join(", "):t.recommendedGuide?e.jsxs("span",{children:["match: ",t.recommendedGuide]}):"â"}),e.jsx("td",{className:"py-2 text-right",children:e.jsx(k,{size:"sm",variant:"ghost",onClick:R=>{R.stopPropagation(),$e(t.video.id,"seo")},children:"AI SEO"})})]},`${t.video.id}-summary`),l&&e.jsx("tr",{className:"border-b align-top",children:e.jsxs("td",{colSpan:8,className:"py-3 pr-3",children:[e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-4 mb-3",children:[e.jsxs("div",{className:"rounded-lg border bg-background/70 px-3 py-2",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-muted-foreground",children:"Views/day"}),e.jsx("p",{className:"font-semibold",children:t.viewsPerDay.toFixed(4)})]}),e.jsxs("div",{className:"rounded-lg border bg-background/70 px-3 py-2",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-muted-foreground",children:"Pace index"}),e.jsx("p",{className:"font-semibold",children:t.paceIndex?`${t.paceIndex}%`:"â"})]}),e.jsxs("div",{className:"rounded-lg border bg-background/70 px-3 py-2",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-muted-foreground",children:"Engagement"}),e.jsx("p",{className:"font-semibold",children:t.engagementRate!=null?`${(t.engagementRate*100).toFixed(2)}%`:"â"})]}),e.jsxs("div",{className:"rounded-lg border bg-background/70 px-3 py-2",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-muted-foreground",children:"SEO score"}),e.jsx("p",{className:"font-semibold",children:t.seoScore??"Not analysed"})]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs(k,{size:"sm",variant:"outline",onClick:()=>$e(t.video.id,"seo"),children:[e.jsx(ye,{className:"w-3.5 h-3.5 mr-1.5"}),"Open SEO assistant"]}),t.recommendedGuide&&e.jsx(k,{size:"sm",variant:"ghost",asChild:!0,children:e.jsxs("a",{href:`/${t.recommendedGuide}`,target:"_blank",rel:"noreferrer",children:[e.jsx(We,{className:"w-3.5 h-3.5 mr-1.5"}),"View recommended guide"]})}),t.attachedGuides.length>0&&e.jsxs("span",{className:"text-xs text-muted-foreground",children:["Linked to: ",t.attachedGuides.join(", ")
8]})]})]})},`${t.video.id}-detail`)]})})})]}),G.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"No videos match these filters."})]}),e.jsx("p",{className:"text-[11px] text-muted-foreground",children:"* Derived metrics. Views/day = views ÷ max(days since publish, 1). Pace = this video's views/day as a percentage of the average views/day for videos in the same age cohort (0â30d, 31â180d, 180d+), capped at 999%."})]})]}),e.jsxs(me,{children:[e.jsx(he,{children:e.jsxs(pe,{className:"flex items-center gap-2 text-base",children:[e.jsx(wt,{className:"w-4 h-4 text-primary"})," Optimization opportunities (",c.length,")"]})}),e.jsxs(xe,{className:"space-y-3",children:[c.slice(0,25).map(t=>e.jsxs("div",{className:"rounded-lg border p-3 space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsx("p",{className:"text-sm font-medium",children:t.title}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(se,{variant:De(t.priority),children:t.priority}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:["score ",t.score,"/100"]})]})]}),e.jsx("ul",{className:"text-xs text-muted-foreground list-disc pl-4 space-y-0.5",children:t.reasons.map((l,R)=>e.jsx("li",{children:l},R))}),e.jsxs("p",{className:"text-[11px] text-muted-foreground",children:["Score factors: ",t.factors.map(l=>`${l.label} (+${l.points})`).join(" · ")]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(k,{size:"sm",variant:"outline",onClick:()=>$e(t.videoId,"seo"),children:[e.jsx(ye,{className:"w-3.5 h-3.5 mr-1.5"}),t.needsAnalysis?"Analyze with AI":"Open SEO assistant"]}),t.attachSlug&&e.jsxs(k,{size:"sm",variant:"ghost",onClick:()=>$e(t.videoId,"seo"),children:[e.jsx(We,{className:"w-3.5 h-3.5 mr-1.5"})," Attach to ",t.attachSlug]})]})]},t.videoId)),c.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"No opportunities detected."}),e.jsx("p",{className:"text-[11px] text-muted-foreground",children:"Applying anything still happens inside the SEO assistant and the video editor â nothing here changes YouTube metadata or attaches a guide video automatically."})]})]}),e.jsxs(me,{children:[e.jsx(he,{children:e.jsxs(pe,{className:"flex items-center gap-2 text-base",children:[e.jsx(_t,{className:"w-4 h-4 text-primary"})," Content gaps by guide"]})}),e.jsxs(xe,{children:[e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-left text-xs uppercase tracking-wide text-muted-foreground",children:[e.jsx("th",{className:"py-2 pr-3",children:"Guide"}),e.jsx("th",{className:"py-2 pr-3",children:"Tier"}),e.jsx("th",{className:"py-2 pr-3",children:"Videos"}),e.jsx("th",{className:"py-2 pr-3",children:"Relevant uploads"}),e.jsx("th",{className:"py-2 pr-3",children:"Recommended topics"}),e.jsx("th",{className:"py-2",children:"Priority"})]})}),e.jsx("tbody",{children:E.filter(t=>!t.hasVideo||t.tier<=2).slice(0,30).map(t=>e.jsxs("tr",{className:"border-t align-top",children:[e.jsx("td",{className:"py-2 pr-3 font-medium",children:t.title}),e.jsx("td",{className:"py-2 pr-3",children:t.tier}),e.jsx("td",{className:"py-2 pr-3",children:t.videoCount}),e.jsx("td",{className:"py-2 pr-3 text-xs text-muted-foreground",children:t.matchedVideos.length?t.matchedVideos.join(", "):"none found"}),e.jsx("td",{className:"py-2 pr-3 text-xs",children:t.suggestedTopics.join("; ")}),e.jsx("td",{className:"py-2",children:e.jsx(se,{variant:De(t.priority),children:t.priority})})]},t.slug))})]})}),e.jsx("p",{className:"text-[11px] text-muted-foreground mt-2",children:"Priority uses guide tier (the existing SEO build batches) and current YouTube coverage. No search-volume data is used because no search-volume source is connected to this dashboard."})]})]}),e.jsxs(me,{children:[e.jsxs(he,{className:"flex flex-row flex-wrap items-center justify-between gap-3",children:[e.jsxs(pe,{className:"flex items-center gap-2 text-base",children:[e.jsx(ye,{className:"w-4 h-4 text-primary"})," AI content opportunities"]}),e.jsxs(k,{size:"sm",className:"gap-2",onClick:Ce,disabled:L,children:[L?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(ye,{className:"w-4 h-4"}),y?"Regenerate":"Generate recommendations"]})]}),e.jsxs(xe,{className:"space-y-3",children:[!y&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"Nothing generated yet. Recommendations are grounded in the guide catalogue, this library's real performance and the saved AI SEO analyses â and are cached so re-opening this page costs nothing."}),(N==null?void 0:N.generated_at)&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Saved plan from ",new Date(N.generated_at).toLocaleStr
8ing("en-GB")," â no new AI cost."]}),((y==null?void 0:y.recommendations)??[]).map((t,l)=>e.jsxs("div",{className:"rounded-lg border p-3 space-y-1.5",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsx("p",{className:"text-sm font-semibold",children:t.topic}),t.priority&&e.jsx(se,{variant:De(t.priority),children:t.priority})]}),t.suggested_title&&e.jsxs("p",{className:"text-sm",children:["Suggested title: ",e.jsx("span",{className:"font-medium",children:t.suggested_title})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[t.target_guide?`Guide: ${t.target_guide_title||t.target_guide} · `:"",t.suggested_format?`Format: ${t.suggested_format} · `:"",t.target_audience?`Audience: ${t.target_audience}`:""]}),t.search_intent&&e.jsxs("p",{className:"text-xs",children:[e.jsx("span",{className:"text-muted-foreground",children:"Search intent: "}),t.search_intent]}),t.why&&e.jsxs("p",{className:"text-xs",children:[e.jsx("span",{className:"text-muted-foreground",children:"Why: "}),t.why]}),t.target_guide&&e.jsx(k,{size:"sm",variant:"outline",asChild:!0,children:e.jsx("a",{href:`/${t.target_guide}`,target:"_blank",rel:"noreferrer",children:"Open guide"})})]},l)),((y==null?void 0:y.notes)??[]).length>0&&e.jsx("ul",{className:"text-xs text-muted-foreground list-disc pl-4",children:y.notes.map((t,l)=>e.jsx("li",{children:t},l))})]})]}),e.jsxs(me,{children:[e.jsx(he,{children:e.jsxs(pe,{className:"flex items-center gap-2 text-base",children:[e.jsx(We,{className:"w-4 h-4 text-primary"})," YouTube â website traffic (last 90 days)"]})}),e.jsxs(xe,{className:"space-y-3",children:[!g&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"Traffic report unavailable for this account."}),g&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid gap-2 sm:grid-cols-4",children:[e.jsx(ue,{label:"Sessions from YouTube",value:re.format(g.sessions??0),hint:"First-party page_views"}),e.jsx(ue,{label:"Visitors",value:re.format(g.visitors??0)}),e.jsx(ue,{label:"Page views",value:re.format(g.page_views??0)}),e.jsx(ue,{label:"Guide page views",value:re.format(g.guide_views??0)})]}),(g.landing_pages??[]).length>0&&e.jsxs("div",{children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-1",children:"Landing pages"}),e.jsx("ul",{className:"text-sm space-y-0.5",children:g.landing_pages.map(t=>e.jsxs("li",{className:"flex justify-between gap-3",children:[e.jsx("span",{className:"truncate",children:t.path}),e.jsxs("span",{className:"text-muted-foreground shrink-0",children:[re.format(t.views)," views · ",re.format(t.sessions)," sessions"]})]},t.path))})]}),(g.guide_actions??[]).length>0&&e.jsxs("div",{children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-1",children:"Guide actions in YouTube-referred sessions"}),e.jsx("ul",{className:"text-sm space-y-0.5",children:g.guide_actions.map(t=>e.jsxs("li",{className:"flex justify-between gap-3",children:[e.jsx("span",{children:t.event_type}),e.jsx("span",{className:"text-muted-foreground",children:re.format(t.events)})]},t.event_type))})]}),e.jsxs("p",{className:"text-[11px] text-muted-foreground flex items-start gap-1.5",children:[e.jsx(ts,{className:"w-3.5 h-3.5 mt-0.5 shrink-0"}),"Measured from the site's own first-party tracking (referrer host youtube.com / youtu.be, or utm_source=youtube). Coverage gap: YouTube strips referrers on some apps and in-app browsers, so this undercounts. To measure YouTube â Guide â student action reliably, add",e.jsx("code",{className:"mx-1",children:"?utm_source=youtube&utm_medium=video&utm_campaign=<video-id>"}),"to every guide link placed in a YouTube description or pinned comment â the existing UTM capture and guide_events pipeline then attributes the whole journey with no other analytics changes."]})]})]})]})]})},xa=new Intl.NumberFormat("en-US"),ga=(s,a)=>
8{if(!a.length)return s;const o=a.map(x=>`${x.timestamp} ${x.label}`).join(` 9`);return s.includes(o)?s:`${s} 10 11Chapters: 12${o}`},fa=()=>{const[s,a]=n.useState(!1),[o,x]=n.useState(!1),[r,v]=n.useState([]),[f,T]=n.useState(new Set),[m,h]=n.useState(null),[g,C]=n.useState(""),[y,_]=n.useState({total:0,done:0,failures:[],running:!1}),[N,S]=n.useState([]),[L,V]=n.useState(!1),w=async()=>{var u;a(!0);try{const[{data:i,error:d},{data:j,error:$}]=await Promise.all([M.functions.invoke("youtube-api?action=allVideos&max=400",{method:"GET"}),M.from("youtube_video_analyses").select("*")]);if(d)throw new Error("Could not load the video library");if($)throw new Error("Could not load saved AI analyses");const I=new Map((j??[]).map(A=>[A.video_id,A])),z=[];for(const A of(i==null?void 0:i.videos)??[]){if(A.privacy_status!=="public")continue;const Y=I.get(A.id);if(!((u=Y==null?void 0:Y.analysis)!=null&&u.seo))continue;const B=Y.analysis.seo,ee=String(B.recommended_title??"").trim(),p=ga(String(B.optimized_description??"").trim(),Array.isArray(B.recommended_chapters)?B.recommended_chapters:[]),c=Array.isArray(B.recommended_tags)?B.recommended_tags.filter(D=>
12typeof D=="string"):[];(ee&&ee!==(A.title??"").trim()||p&&p!==(A.description??"").trim()||c.length>0&&(A.tags??[]).length===0)&&z.push({video:A,seoScore:Y.seo_score??null,title:ee||(A.title??""),description:p||(A.description??""),tags:c,chapters:Array.isArray(B.recommended_chapters)?B.recommended_chapters:[]})}z.sort((A,Y)=>(A.seoScore??999)-(Y.seoScore??999)),v(z),T(new Set(z.map(A=>A.video.id))),x(!0)}catch(i){U({title:"Could not build proposals",description:i instanceof Error?i.message:"Unknown error",variant:"destructive"})}finally{a(!1)}},O=async()=>{const{data:u}=await M.from("youtube_metadata_changes").select("id, video_id, video_title_before, field, before_value, after_value, created_at").order("created_at",{ascending:!1}).limit(100);S(u??[]),V(!0)},b=(u,i)=>v(d=>d.map(j=>j.video.id===u?{...j,...i}:j)),F=async u=>{const i={};if(u.title.trim()&&u.title.trim()!==(u.video.title??"").trim()&&(i.title=u.title.trim()),u.description!==(u.video.description??"")&&(i.description=u.description),u.tags.length>0&&(i.tags=u.tags),Object.keys(i).length===0)return;const{data:d,error:j}=await M.functions.invoke("youtube-api?action=updateVideo",{method:"POST",body:{id:u.video.id,...i}});if(j)throw new Error("Update failed");if(d!=null&&d.error)throw new Error(String(d.error));const{data:$}=await M.auth.getUser(),I=Object.keys(i).map(z=>{var A;return{video_id:u.video.id,video_title_before:u.video.title,field:z,before_value:z==="title"?u.video.title:z==="description"?(u.video.description??"").slice(0,2e3):(u.video.tags??[]).join(", "),after_value:z==="title"?u.title.trim():z==="description"?u.description.slice(0,2e3):u.tags.join(", "),source:"batch-seo",changed_by:((A=$.user)==null?void 0:A.id)??null}});await M.from("youtube_metadata_changes").insert(I)},W=async()=>{const u=r.filter(i=>f.has(i.video.id));if(u.length!==0){_({total:u.length,done:0,failures:[],running:!0});for(let i=0;i<u.length;i++){const d=u[i];try{await F(d),v(j=>j.filter($=>$.video.id!==d.video.id)),T(j=>{const $=new Set(j);return $.delete(d.video.id),$})}catch(j){_($=>({...$,failures:[...$.failures,`${d.video.title??d.video.id}: ${j instanceof Error?j.message:"failed"}`]}))}_(j=>({...j,done:i+1}))}_(i=>({...i,running:!1})),U({title:"Batch apply finished",description:"Successful updates are live on YouTube and logged."})}},J=n.useMemo(()=>{const u=g.trim().toLowerCase();return u?r.filter(i=>(i.video.title??"").toLowerCase().includes(u)||i.title.toLowerCase().includes(u)):r},[r,g]),te=(u,i)=>T(d=>{const j=new Set(d);return i?j.add(u):j.delete(u),j});return e.jsxs(me,{className:"border-border/60",children:[e.jsxs(he,{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-3 space-y-0",children:[e.jsxs(pe,{className:"text-lg font-display flex items-center gap-2",children:[e.jsx(ye,{className:"w-5 h-5 text-primary"})," Batch SEO packaging",o&&e.jsxs(se,{variant:"outline",className:"ml-1 font-normal",children:[r.length," to improve"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[o&&e.jsx("div",{className:"relative",children:e.jsx(de,{value:g,onChange:u=>C(u.target.value),placeholder:"Filter proposalsâ¦",className:"w-full sm:w-52"})}),e.jsxs(k,{variant:"outline",size:"sm",className:"gap-2",onClick:w,disabled:s||y.running,children:[s?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(Ee,{className:"w-4 h-4"}),o?"Reload":"Load proposals"]}),e.jsxs(k,{size:"sm",className:"gap-2",onClick:W,disabled:!o||y.running||f.size===0,children:[y.running?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(ye,{className:"w-4 h-4"}),"Apply selected (",f.size,")"]})]})]}),e.jsxs(xe,{className:"space-y-4",children:[!o&&!s&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loads the whole channel library and every saved AI SEO analysis, then lists public videos whose recommended title, description or tags differ from what is live. Review each proposal inline â nothing is written to YouTube until you press Apply."}),s&&e.jsx("div",{className:"space-y-2",children:[0,1,2].map(u=>e.jsx(Se,{className:"h-16 w-full rounded-xl"},u))}),(y.running||y.done>0)&&e.jsxs("div",{className:"rounded-xl border border-primary/25 bg-primary/5 p-3 space-y-2",children:[e.jsxs("p",{className:"text-xs font-medium",children:["Applying ",y.done,"/",y.total,!y.running&&" â finished"]}),e.jsx(Le,{value:y.total?y.done/y.total*100:0}),y.failures.length>0&&e.jsx("ul",{className:"text-xs text-destructive space-y-0.5",children:y.failures.map((u,i)=>e.jsx("li",{children:u},i))})]}),o&&J.length===0&&!y.running&&e.jsx("p",{className:"text-sm text-muted-foreground",children:r.length===0?"Every anal
12ysed public video already matches its AI recommendation â nothing to apply.":"No proposals match the filter."}),e.jsx("div",{className:"space-y-2",children:J.map(u=>{const i=m===u.video.id;return e.jsxs("div",{className:"rounded-xl border border-border/60 bg-card/60 p-3 space-y-2",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(As,{checked:f.has(u.video.id),onCheckedChange:d=>te(u.video.id,d===!0),className:"mt-1","aria-label":`Select ${u.video.title??u.video.id}`}),u.video.thumbnail&&e.jsx("img",{src:u.video.thumbnail,alt:"",className:"w-24 aspect-video object-cover rounded-md hidden sm:block",loading:"lazy"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("p",{className:"text-xs text-muted-foreground line-clamp-1",children:["Now: ",u.video.title??"Untitled"]}),e.jsxs("p",{className:"text-sm font-medium line-clamp-2",children:["â ",u.title]}),e.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground mt-1",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Ve,{className:"w-3.5 h-3.5"})," ",xa.format(Number(u.video.view_count??0))]}),u.seoScore!=null&&e.jsxs(se,{variant:u.seoScore<45?"destructive":"secondary",children:["SEO ",u.seoScore,"/100"]}),u.tags.length>0&&e.jsxs(se,{variant:"outline",children:[u.tags.length," tags"]})]})]}),e.jsx(k,{variant:"ghost",size:"sm",onClick:()=>h(i?null:u.video.id),"aria-label":"Review proposal",children:i?e.jsx(_s,{className:"w-4 h-4"}):e.jsx(Ss,{className:"w-4 h-4"})})]}),i&&e.jsxs("div",{className:"space-y-3 border-t border-border/40 pt-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-semibold text-muted-foreground",children:"Title"}),e.jsx(de,{value:u.title,onChange:d=>b(u.video.id,{title:d.target.value}),maxLength:100}),e.jsxs("p",{className:"text-[11px] text-muted-foreground mt-0.5",children:[u.title.length,"/100"]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-semibold text-muted-foreground",children:"Description"}),e.jsx("textarea",{value:u.description,onChange:d=>b(u.video.id,{description:d.target.value}),maxLength:5e3,rows:8,className:"w-full rounded-md border border-input bg-background px-3 py-2 text-sm"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-semibold text-muted-foreground",children:"Tags (comma-separated)"}),e.jsx(de,{value:u.tags.join(", "),onChange:d=>b(u.video.id,{tags:d.target.value.split(",").map(j=>j.trim()).filter(Boolean)})})]})]})]},u.video.id)})}),e.jsxs("div",{className:"border-t border-border/40 pt-3",children:[e.jsxs(k,{variant:"ghost",size:"sm",className:"gap-2",onClick:L?()=>V(!1):O,children:[e.jsx(St,{className:"w-4 h-4"})," ",L?"Hide change log":"Show change log"]}),L&&e.jsx("div",{className:"mt-2 space-y-1",children:N.length===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:"No metadata changes applied yet."}):N.map(u=>e.jsxs("p",{className:"text-xs text-muted-foreground",children:[e.jsx("span",{className:"font-medium text-foreground",children:u.field})," on"," ",u.video_title_before??u.video_id," â ",new Date(u.created_at).toLocaleString("en-GB")]},u.id))})]})]})]})},ja=()=>{const[s,a]=n.useState(!1),[o,x]=n.useState(!1),[r,v]=n.useState([]),[f,T]=n.useState(new Set),[m,h]=n.useState([]),[g,C]=n.useState(new Set),[y,_]=n.useState(""),[N,S]=n.useState(""),[L,V]=n.useState(!1),[w,O]=n.useState(""),[b,F]=n.useState({total:0,done:0,running:!1}),W=async()=>{a(!0);try{const[{data:d,error:j},{data:$,error:I}]=await Promise.all([M.functions.invoke("youtube-api?action=playlists",{method:"GET"}),M.functions.invoke("youtube-api?action=allVideos&max=400",{method:"GET"})]);if(j||I)throw new Error("Could not load playlists or the video library");const z=(d==null?void 0:d.playlists)??[];v(z),h((($==null?void 0:$.videos)??[]).filter(Y=>Y.privacy_status==="public"));const A=new Set;for(const Y of z.slice(0,40)){const{data:B}=await M.functions.invoke(`youtube-api?action=playlistItems&playlist_id=${encodeURIComponent(Y.id)}`,{method:"GET"});for(const ee of(B==null?void 0:B.video_ids)??[])A.add(ee)}T(A),x(!0)}catch(d){U({title:"Playlists unavailable",description:d instanceof Error?d.message:"Unknown error",variant:"destructive"})}finally{a(!1)}},J=n.useMemo(()=>{const d=m.filter($=>!f.has($.id)),j=w.trim().toLowerCase();return j?d.filter($=>($.title??"").toLowerCase().includes(j)):d},[m,f,w]),te=async()=>{const d=N.trim();if(d){V(!0);try{const{data:j,error:$}=await M.functions.invoke("youtube-api?action=createPlaylist",{method:"POST",body:{title:d,privacyStatus:"public"}});if($||j!=null&&j.error)throw new Error(String((j==null?void 0:j.error)??"Create failed"));U({title:"Playlist created",description:d}),S(""),await W()}catch(j){U({title:"Could not create playlist",description:j instanceof Error?j.message:"Unknown error",variant:"destructive"})}finally{V(!1)}}},u=async()=>
12{if(!y||g.size===0)return;const d=J.filter($=>g.has($.id));F({total:d.length,done:0,running:!0});let j=0;for(const $ of d){try{const{data:I,error:z}=await M.functions.invoke("youtube-api?action=addToPlaylist",{method:"POST",body:{playlistId:y,videoId:$.id}});if(z||I!=null&&I.error&&!(I!=null&&I.duplicate))throw new Error("failed");(I!=null&&I.added||I!=null&&I.duplicate)&&(j++,T(A=>new Set(A).add($.id)))}catch{}F(I=>({...I,done:I.done+1}))}F({total:0,done:0,running:!1}),C(new Set),U({title:"Playlist updated",description:`${j} video(s) added.`})},i=(d,j)=>C($=>{const I=new Set($);return j?I.add(d):I.delete(d),I});return e.jsxs(me,{className:"border-border/60",children:[e.jsxs(he,{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-3 space-y-0",children:[e.jsxs(pe,{className:"text-lg font-display flex items-center gap-2",children:[e.jsx(kt,{className:"w-5 h-5 text-primary"})," Playlists",o&&e.jsxs(se,{variant:"outline",className:"ml-1 font-normal",children:[r.length," playlists · ",J.length," uncovered"]})]}),e.jsxs(k,{variant:"outline",size:"sm",className:"gap-2",onClick:W,disabled:s||b.running,children:[s?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(Ee,{className:"w-4 h-4"}),o?"Reload":"Load playlists"]})]}),e.jsxs(xe,{className:"space-y-4",children:[!o&&!s&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loads the channel's playlists and finds public videos that are not in any playlist â those miss the playlist discovery surface entirely. Create exam/subject playlists and add videos in batches."}),s&&e.jsx("div",{className:"space-y-2",children:[0,1,2].map(d=>e.jsx(Se,{className:"h-12 w-full rounded-xl"},d))}),o&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3",children:[r.map(d=>e.jsxs("div",{className:"rounded-xl border border-border/60 bg-card/60 p-3 flex items-center gap-3",children:[d.thumbnail&&e.jsx("img",{src:d.thumbnail,alt:"",className:"w-16 aspect-video object-cover rounded-md",loading:"lazy"}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"text-sm font-medium line-clamp-1",children:d.title??"Untitled"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[d.item_count," videos · ",d.privacy_status??"?"]})]})]},d.id)),r.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"No playlists on the channel yet."})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[e.jsx(de,{value:N,onChange:d=>S(d.target.value),placeholder:"New playlist title (e.g. Class 11 Physics â Full Course)",maxLength:150}),e.jsxs(k,{onClick:te,disabled:L||!N.trim(),className:"gap-2 shrink-0",children:[L?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(as,{className:"w-4 h-4"}),"Create playlist"]})]}),e.jsxs("div",{className:"border-t border-border/40 pt-4 space-y-3",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center gap-2",children:[e.jsxs("p",{className:"text-sm font-semibold flex-1",children:["Public videos not in any playlist (",J.length,")"]}),e.jsx(de,{value:w,onChange:d=>O(d.target.value),placeholder:"Filterâ¦",className:"sm:w-52"})]}),b.running&&e.jsxs("div",{className:"rounded-xl border border-primary/25 bg-primary/5 p-3 space-y-2",children:[e.jsxs("p",{className:"text-xs font-medium",children:["Adding ",b.done,"/",b.total]}),e.jsx(Le,{value:b.total?b.done/b.total*100:0})]}),e.jsxs("div",{className:"max-h-96 overflow-y-auto space-y-1 pr-1",children:[J.map(d=>e.jsxs("label",{className:"flex items-center gap-3 rounded-lg border border-border/40 px-3 py-2 cursor-pointer hover:bg-muted/40",children:[e.jsx(As,{checked:g.has(d.id),onCheckedChange:j=>i(d.id,j===!0),"aria-label":`Select ${d.title??d.id}`}),e.jsx("span",{className:"text-sm line-clamp-1 flex-1",children:d.title??"Untitled"}),e.jsxs("span",{className:"text-xs text-muted-foreground shrink-0",children:[Number(d.view_count??0).toLocaleString()," views"]})]},d.id)),J.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"Every public video is in at least one playlist."})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[e.jsxs(ge,{value:y,onValueChange:_,children:[e.jsx(fe,{className:"sm:w-80",children:e.jsx(je,{placeholder:"Choose target playlistâ¦"})}),e.jsx(ve,{children:r.map(d=>e.jsx(Z,{value:d.id,children:d.title??d.id},d.id))})]}),e.jsxs(k,{onClick:u,disabled:!y||g.size===0||b.running,className:"gap-2",children:[b.running?e.jsx(ie,{className:"w-4 h-4 animate-spin"}):e.jsx(as,{className:"w-4 h-4"}),"Add ",g.size," video(s)"]})]})]})]})]})]})},za=()=>e.jsxs("div",{className:"min-h-screen bg-background",children:[e.jsx("header",{className:"border-b border-border/40 bg-card/50 backdrop-blur-sm sticky top-0 z-50",children:e.jsxs("div",{className:"max-w-7xl mx-auto px-4 py-4 flex items-center gap-4",children:[e.jsx(nt,{to:"/admin",children:e.jsxs(k,{variant:"ghost",size:"sm",className:"gap-2",children:[e.jsx(Ct,{className:"w-4 h-4"})," Admin"]})}),e.jsxs("h1",{className:"text-2xl font-bold text-primary font-display flex items-center gap-2",children:[e.jsx(Ns,{className:"w-6 h-6"})," YouTube"]})]})}),e.jsxs("main",{className:"max-w-7xl mx-auto px-4 py-8 space-y-6",children:[e.jsx(zt,{}),e.jsx(pa,{}),e.jsx(fa,{}),e.jsx(ja,{}),e.jsx(ca,{})]})]});
12export{za as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.