1import{r as e,j as t}from"./vendor-react-C9yDzYQD.js";import{supabase as a}from"./supabase-client-_h80EYw_.js";import{B as i}from"./button-CcIRk75H.js";import{u as r}from"./useAuth-Dz3EPsxs.js";import{a as l}from"./runtime-utils-GN4cODRt.js";import{I as s}from"./image-Bt9rnFUc.js";import{c as d}from"./createLucideIcon-DNcTU-zM.js";import{S as n}from"./sparkles-COPkKMBj.js";import{a as o}from"./vendor-date-D4HAbvGT.js";import{L as m}from"./loader-circle-CWK_zhHB.js";import{C as u}from"./circle-x-tTPWE6xb.js";const c=d("Film",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M7 3v18",key:"bbkbws"}],["path",{d:"M3 7.5h4",key:"zfgn84"}],["path",{d:"M3 12h18",key:"1i2n21"}],["path",{d:"M3 16.5h4",key:"1230mu"}],["path",{d:"M17 3v18",key:"in4fa5"}],["path",{d:"M17 7.5h4",key:"myr1c1"}],["path",{d:"M17 16.5h4",key:"go4c1d"}]]),p=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,x=(e,t)=>{if(!p.test(e)||!p.test(t))throw new Error("Video poster keys require valid user and memory IDs");return`${e}/backfills/video-posters/${t}.jpg`};function h(){const{toast:d}=r(),[p,h]=e.useState(null),[f,g]=e.useState(null),[_,b]=e.useState({image:0,video:0}),[v,j]=e.useState({image:0,video:0}),[y,N]=e.useState(null),[w,k]=e.useState(0),[q,S]=e.useState(0),[M,I]=e.useState(!1),[L,$]=e.useState(!1),[U,P]=e.useState(null),[C,D]=e.useState(null),[R,V]=e.useState([]),B=e.useRef(!1),O="video_poster_backfill_status",E=e.useCallback(async e=>{const t=JSON.parse(JSON.stringify(e)),{error:i}=await a.from("system_settings").upsert({key:O,value:t,description:"Persistent status for video poster backfill jobs"},{onConflict:"key"});if(i)throw i;D(e)},[]),F=e.useCallback(async()=>{var e;const[t,i,r,l]=await Promise.all([a.from("memories").select("id",{count:"exact",head:!0}).not("image_url","is",null).neq("image_url","").filter("metadata->>thumbnail_url","is",null),a.from("memories").select("id",{count:"exact",head:!0}).eq("type","video").not("video_url","is",null).neq("video_url","").filter("metadata->>thumbnail_url","is",null),a.from("memories").select("id",{count:"exact",head:!0}).or(["and(image_url.not.is.null,image_url.neq.,metadata->>thumbnail_url.not.is.null,metadata->>thumbnail_url.neq.,metadata->>dominant_color.is.null)","and(image_url.not.is.null,image_url.neq.,metadata->>width.is.null)","and(image_url.not.is.null,image_url.neq.,metadata->>height.is.null)","and(image_url.not.is.null,image_url.neq.,metadata->>aspect_ratio.is.null)","and(image_url.not.is.null,image_url.neq.,metadata->>orientation.is.null)","and(type.eq.video,video_url.not.is.null,video_url.neq.,metadata->>thumbnail_url.not.is.null,metadata->>thumbnail_url.neq.,metadata->>dominant_color.is.null)","and(type.eq.video,video_url.not.is.null,video_url.neq.,metadata->>thumbnail_url.not.is.null,metadata->>thumbnail_url.neq.,metadata->>width.is.null)","and(type.eq.video,video_url.not.is.null,video_url.neq.,metadata->>thumbnail_url.not.is.null,metadata->>thumbnail_url.neq.,metadata->>height.is.null)","and(type.eq.video,video_url.not.is.null,video_url.neq.,metadata->>thumbnail_url.not.is.null,metadata->>thumbnail_url.neq.,metadata->>aspect_ratio.is.null)","and(type.eq.video,video_url.not.is.null,video_url.neq.,metadata->>thumbnail_url.not.is.null,metadata->>thumbnail_url.neq.,metadata->>orientation.is.null)"].join(",")),a.from("system_settings").select("value").eq("key",O).maybeSingle()]);if(t.error||h(t.count??0),i.error||g(i.count??0),r.error||N(r.count??0),!l.error){const t=null==(e=l.data)?void 0:e.value;D(t&&"object"==typeof t?t:null)}},[]);e.useEffect(()=>{F()},[F]);const K=e.useCallback(async(e,t=!1)=>{var i;const{data:{session:r}}=await a.auth.getSession();if(!r)return void d({title:"Not authenticated",variant:"error"});if((e=>"image"===e||"metadata"===e)(e))return void d({title:"Browser backfill disabled",description:"Remote image and metadata repair must run through hardened maintenance tooling; the admin browser will not fetch stored remote URLs."});B.current=!1,I(!0),$(!1),P(e),"metadata"===e?(k(0),S(0)):(b(t=>({...t,[e]:0})),j(t=>({...t,[e]:0})));const l=50;let s=0,n=0;const o=(new Date).toISOString(),m=Number((null==C?void 0:C.lifetime_processed)??(null==C?void 0:C.processed)??0),u=Number((null==C?void 0:C.lifetime_failed)??(null==C?void 0:C.failed)??0),c=new Set;let p=0,h="video"===e&&"string"==typeof(null==C?void 0:C.resume_after_id)?C.resume_after_id:null,g=!1;const _=[],v=t?R.filter(e=>"dry-run"===e.mode&&"planned"===e.outcome&&e.after.thumbnailUrl).map(e=>e.memoryId).slice(0,l):[];"video"===e&&V([]);const y=async()=>{const{count:e}=await a.from("memories").select("id",{count:"exact",head:!0}).eq("type","video").not("video_url","is",null).neq("video_url","").filter("metadata->>thumbnail_url","is",null);return e??0};let N="video"===e?f??await y():null;for("video"===e&&t&&await E({status:"running",started_at:o,updated_at:o,pending_at_start:f??0,processed:0,failed:0,lifetime_processed:m,lifetime_failed:u,remaining:f??0,limit:l,resume_after_id:h});!B.current&&("video"!==e||c.size<l);){let r=a.from("memories").select("id, user_id, type, image_url, video_url, metadata");if("video"===e)if(r=r.order("id",{ascending:!0}).limit(50),t){if(0===v.length)break;r=r.in("id",v)}else h&&(r=r.gt("id",h));else r=r.order("created_at",{ascending:!1}).range(p,p+50-1);"image"===e?r.not("image_url","is",null).neq("image_url","").filter("metadata->>thumbnail_url","is",null):"video"===e?r.eq("type","video").not("video_url","is",null).neq("video_url","").filter("metadata->>thumbnail_url","is",null).not("image_url","is",null).neq("image_url",""):r.or(["and(image_url.
1not.is.null,image_url.neq.,metadata->>thumbnail_url.not.is.null,metadata->>thumbnail_url.neq.,metadata->>dominant_color.is.null)","and(image_url.not.is.null,image_url.neq.,metadata->>width.is.null)","and(image_url.not.is.null,image_url.neq.,metadata->>height.is.null)","and(image_url.not.is.null,image_url.neq.,metadata->>aspect_ratio.is.null)","and(image_url.not.is.null,image_url.neq.,metadata->>orientation.is.null)","and(type.eq.video,video_url.not.is.null,video_url.neq.,metadata->>thumbnail_url.not.is.null,metadata->>thumbnail_url.neq.,metadata->>dominant_color.is.null)","and(type.eq.video,video_url.not.is.null,video_url.neq.,metadata->>thumbnail_url.not.is.null,metadata->>thumbnail_url.neq.,metadata->>width.is.null)","and(type.eq.video,video_url.not.is.null,video_url.neq.,metadata->>thumbnail_url.not.is.null,metadata->>thumbnail_url.neq.,metadata->>height.is.null)","and(type.eq.video,video_url.not.is.null,video_url.neq.,metadata->>thumbnail_url.not.is.null,metadata->>thumbnail_url.neq.,metadata->>aspect_ratio.is.null)","and(type.eq.video,video_url.not.is.null,video_url.neq.,metadata->>thumbnail_url.not.is.null,metadata->>thumbnail_url.neq.,metadata->>orientation.is.null)"].join(","));const{data:w,error:q}=await r;if(q)throw q;if(!w||0===w.length){if("video"===e&&h&&!g){h=null,g=!0;continue}break}if("video"===e&&!t){const e=w.slice(0,l).map(e=>({memoryId:e.id,mode:"dry-run",outcome:"planned",sourceUrl:e.image_url||e.video_url||"",objectKey:e.image_url?null:x(e.user_id,e.id),before:{thumbnailUrl:null},after:{thumbnailUrl:e.image_url||null}}));return V(e),I(!1),$(!0),P(null),void d({title:"Video poster dry-run complete",description:`${e.length} records are ready for review. No media or database records were changed.`})}const M="video"===e?Math.max(0,l-c.size):w.length,L=w.filter(e=>!c.has(e.id)).slice(0,M);if(0===L.length){p+=50;continue}const U="video"===e?4:3;for(let i=0;i<L.length&&!B.current;i+=U){const r=L.slice(i,i+U);await Promise.all(r.map(async i=>{c.add(i.id);const r=i.image_url||i.video_url||"",l="video"!==e||i.image_url?null:x(i.user_id,i.id);try{const d=i.metadata&&"object"==typeof i.metadata?i.metadata:{},c=i.image_url||"";if(!c)throw new Error("Remote video poster generation is disabled in the browser; run the DNS-hardened CLI backfill.");const p="string"==typeof d.dominant_color?d.dominant_color:"#171717",x=c,{data:h,error:g}=await a.rpc("admin_patch_video_poster_backfill_metadata",{p_memory_id:i.id,p_user_id:i.user_id,p_outcome:"success",p_thumbnail_url:x,p_poster_source:"image_url",p_enrichment:{dominant_color:p},p_error:null});if(g)throw g;if(!0!==h)throw new Error("Memory changed concurrently; poster was not overwritten");if("video"===e){const e={memoryId:i.id,mode:"apply",outcome:"updated",sourceUrl:r,objectKey:l,before:{thumbnailUrl:null},after:{thumbnailUrl:x||null}};_.push(e),V([..._])}s++,"metadata"===e?k(s):b(t=>({...t,[e]:s})),"video"===e&&t&&await E({status:"running",started_at:o,updated_at:(new Date).toISOString(),pending_at_start:f??0,processed:s,failed:n,lifetime_processed:m+s,lifetime_failed:u+n,remaining:Math.max((f??0)-s,0),last_processed_memory_id:i.id,resume_after_id:i.id,last_manifest:_.slice(-20)})}catch(d){if("video"===e){const e=d instanceof Error?d.message.slice(0,500):String(d).slice(0,500),{error:t}=await a.rpc("admin_patch_video_poster_backfill_metadata",{p_memory_id:i.id,p_user_id:i.user_id,p_outcome:"failure",p_thumbnail_url:null,p_poster_source:null,p_enrichment:{},p_error:e}),s={memoryId:i.id,mode:"apply",outcome:"failed",sourceUrl:r,objectKey:l,before:{thumbnailUrl:null},after:{thumbnailUrl:null},error:e};_.push(s),V([..._])}n++,"metadata"===e?S(n):j(t=>({...t,[e]:n})),"video"===e&&t&&await E({status:"running",started_at:o,updated_at:(new Date).toISOString(),pending_at_start:f??0,processed:s,failed:n,lifetime_processed:m+s,lifetime_failed:u+n,remaining:Math.max((f??0)-s,0),last_failed_memory_id:i.id,last_error:d instanceof Error?d.message:String(d),resume_after_id:i.id,last_manifest:_.slice(-20)})}}))}if("video"===e){h=(null==(i=L.at(-1))?void 0:i.id)||h;const e=await y();N=e,t&&await E({status:"running",started_at:o,updated_at:(new Date).toISOString(),pe
1nding_at_start:f??0,processed:s,failed:n,lifetime_processed:m+s,lifetime_failed:u+n,remaining:e,limit:l,resume_after_id:h,last_manifest:_.slice(-20)})}else p=0;if(w.length<50||"video"===e&&c.size>=l)break}if("video"===e&&!t)return I(!1),$(!0),P(null),void d({title:"Video poster dry-run complete",description:"No pending records were found after applying the saved resume cursor. No changes were made."});if(I(!1),$(!0),P(null),F(),"video"===e&&t){const e=await y();await E({status:B.current?"stopped":e>0?"incomplete":"completed",started_at:o,updated_at:(new Date).toISOString(),completed_at:(new Date).toISOString(),pending_at_start:f??0,processed:s,failed:n,lifetime_processed:m+s,lifetime_failed:u+n,remaining:e,limit:l,resume_after_id:h,last_manifest:_.slice(-20)})}d({title:B.current?"Backfill stopped":"video"===e&&N&&N>0?"Video backfill needs another pass":"Backfill complete!",description:`Processed ${s} ${"image"===e?"images":"video"===e?"video posters":"media metadata records"}${n>0?`, ${n} failed`:""}.`})},[F,E,d,R,C,f]),T="image"===U?p:"video"===U?f:"metadata"===U?y:null,z="metadata"===U?w:U?_[U]:0,A=T&&T>0?Math.min(100,Math.round(z/T*100)):0,H=Number((null==C?void 0:C.lifetime_processed)??(null==C?void 0:C.processed)??0),J=Number((null==C?void 0:C.lifetime_failed)??(null==C?void 0:C.failed)??0),G=Number((null==C?void 0:C.processed)||0),Z=Number((null==C?void 0:C.failed)||0),Q="string"==typeof(null==C?void 0:C.status)?C.status:null;return t.jsxs("div",{className:"space-y-6",children:[t.jsx("p",{className:"text-sm text-muted-foreground",children:"Keep upload catch-up work split by purpose. Thumbnails and posters stay in their own lane, while metadata catch-up handles dominant colors, size fields, aspect ratios, and orientation for already-uploaded media."}),t.jsxs("div",{className:"space-y-4",children:[t.jsxs("div",{className:"rounded-3xl border border-foreground
1/10 bg-background/40 p-5 space-y-4",children:[t.jsxs("div",{children:[t.jsx("p",{className:"text-sm font-black uppercase tracking-[0.18em] text-foreground/80",children:"Thumbnail And Poster Backfill"}),t.jsxs("p",{className:"mt-1 text-xs text-muted-foreground",children:["Generates missing image thumbnails and video posters. Video repair previews are read-only by default; each explicit apply is capped at ",50," records."]})]}),t.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[t.jsxs("div",{className:"p-4 rounded-2xl bg-amber-500/10 border border-amber-500/20 text-center",children:[t.jsxs("div",{className:"flex items-center justify-center gap-2 text-amber-500",children:[t.jsx(s,{className:"w-4 h-4"}),t.jsx("div",{className:"text-2xl font-black",children:null===p?"â":p.toLocaleString()})]}),t.jsx("div",{className:"text-[10px] font-bold uppercase tracking-widest text-amber-500/70 mt-1",children:"Images Need Thumbnails"})]}),t.jsxs("div",{className:"p-4 rounded-2xl bg-sky-500/10 border border-sky-500/20 text-center",children:[t.jsxs("div",{className:"flex items-center justify-center gap-2 text-sky-500",children:[t.jsx(c,{className:"w-4 h-4"}),t.jsx("div",{className:"text-2xl font-black",children:null===f?"â":f.toLocaleString()})]}),t.jsx("div",{className:"text-[10px] font-bold uppercase tracking-widest text-sky-500/70 mt-1",children:"Videos Need Posters"})]})]}),t.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[t.jsxs("div",{className:"p-4 rounded-2xl bg-green-500/10 border border-green-500/20 text-center",children:[t.jsx("div",{className:"text-2xl font-black text-green-500",children:_.image.toLocaleString()}),t.jsx("div",{className:"text-[10px] font-bold uppercase tracking-widest text-green-500/70 mt-1",children:"Images Processed"})]}),t.jsxs("div",{className:"p-4 rounded-2xl bg-violet-500/10 border border-violet-500/20 text-center",children:[t.jsx("div",{className:"text-2xl font-black text-violet-500",children:Math.max(_.video,H).toLocaleString()}),t.jsx("div",{className:"text-[10px] font-bold uppercase tracking-widest text-violet-500/70 mt-1",children:"Video Posters Processed"})]})]}),t.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[t.jsxs("div",{className:"p-4 rounded-2xl bg-muted/20 border border-foreground
1/5 text-center",children:[t.jsx("div",{className:"text-2xl font-black text-destructive",children:v.image}),t.jsx("div",{className:"text-[10px] font-bold uppercase tracking-widest text-muted-foreground mt-1",children:"Image Failures"})]}),t.jsxs("div",{className:"p-4 rounded-2xl bg-muted/20 border border-foreground/5 text-center",children:[t.jsx("div",{className:"text-2xl font-black text-destructive",children:Math.max(v.video,J)}),t.jsx("div",{className:"text-[10px] font-bold uppercase tracking-widest text-muted-foreground mt-1",children:"Video Failures"})]})]}),t.jsxs("div",{className:"flex gap-3 flex-wrap",children:[t.jsxs(i,{onClick:()=>K("image"),disabled:!0,className:"flex-1 h-12 rounded-2xl bg-primary hover:bg-primary/90 text-white font-bold gap-2",children:[t.jsx(s,{className:"w-4 h-4"}),"Image Repair Requires Server Tooling"]}),t.jsxs(i,{onClick:()=>K("video"),disabled:M||0===f,variant:"secondary",className:"flex-1 h-12 rounded-2xl font-bold gap-2",children:[t.jsx(c,{className:"w-4 h-4"}),0===f?"Videos Up to Date":`Preview Next ${Math.min(f??50,50)} Posters`]}),t.jsxs(i,{onClick:()=>K("video",!0),disabled:M||0===f||!R.some(e=>"planned"===e.outcome&&e.after.thumbnailUrl),variant:"outline",className:"flex-1 h-12 rounded-2xl font-bold gap-2",children:[t.jsx(c,{className:"w-4 h-4"}),"Apply Reviewed Batch (max ",50,")"]})]})]}
1),t.jsxs("div",{className:"rounded-3xl border border-foreground/10 bg-background/40 p-5 space-y-4",children:[t.jsxs("div",{children:[t.jsx("p",{className:"text-sm font-black uppercase tracking-[0.18em] text-foreground/80",children:"Media Metadata Backfill"}),t.jsx("p",{className:"mt-1 text-xs text-muted-foreground",children:"Fills in dominant colors, width, height, aspect ratio, and orientation after fast uploads."})]}),t.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[t.jsxs("div",{className:"p-4 rounded-2xl bg-fuchsia-500/10 border border-fuchsia-500/20 text-center",children:[t.jsx("div",{className:"text-2xl font-black text-fuchsia-500",children:null===y?"â":y.toLocaleString()}),t.jsx("div",{className:"text-[10px] font-bold uppercase tracking-widest text-fuchsia-500/70 mt-1",children:"Need Metadata"})]}),t.jsxs("div",{className:"p-4 rounded-2xl bg-emerald-500/10 border border-emerald-500/20 text-center",children:[t.jsx("div",{className:"text-2xl font-black text-emerald-500",children:w.toLocaleString()}),t.jsx("div",{className:"text-[10px] font-bold uppercase tracking-widest text-emerald-500/70 mt-1",children:"Processed"})]}),t.jsxs("div",{className:"p-4 rounded-2xl bg-muted/20 border border-foreground
1/5 text-center",children:[t.jsx("div",{className:"text-2xl font-black text-destructive",children:q.toLocaleString()}),t.jsx("div",{className:"text-[10px] font-bold uppercase tracking-widest text-muted-foreground mt-1",children:"Failures"})]})]}),t.jsxs(i,{onClick:()=>K("metadata"),disabled:!0,variant:"outline",className:"w-full h-12 rounded-2xl font-bold gap-2",children:[t.jsx(n,{className:"w-4 h-4"}),"Metadata Repair Requires Server Tooling"]})]})]}),C&&t.jsxs("div",{className:"p-4 rounded-2xl bg-background/60 border border-border/50",children:[t.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground",children:"Video Backfill Status"}),t.jsxs("p",{className:"mt-2 text-sm text-foreground",children:["running"===Q?"Running":"completed"===Q?"Last run completed":"stopped"===Q?"Last run stopped":"incomplete"===Q?"Last run incomplete":"Last run recorded",(null==C?void 0:C.updated_at)?` · Updated ${o(new Date(C.updated_at),"MMM d, HH:mm")}`:""]}),t.jsxs("p",{className:"mt-1 text-xs text-muted-foreground",children:["This run: ",G.toLocaleString()," processed, ",Z.toLocaleString()," failed."]})]}),R.length>0&&t.jsxs("div",{className:"rounded-2xl border border-border/50 bg-background/60 p-4",children:[t.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground",children:"Latest Video Poster Manifest"}),t.jsxs("p",{className:"mt-2 text-xs text-muted-foreground",children:[R.filter(e=>"planned"===e.outcome).length," planned ·"," ",R.filter(e=>"updated"===e.outcome).length," updated ·"," ",R.filter(e=>"failed"===e.outcome).length," retryable failures"]}),t.jsx("div",{className:"mt-3 max-h-48 space-y-2 overflow-auto font-mono text-[10px] text-muted-foreground",children:R.slice(-20).map(e=>t.jsxs("div",{className:"rounded-lg bg-muted/20 px-3 py-2",children:[t.jsx("span",{className:"font-bold text-foreground/80",children:e.outcome})," ",e.memoryId," · ",e.before.thumbnailUrl||"no poster"," â"," ",e.after.thumbnailUrl||e.objectKey||"retry pending",e.error?` · ${e.error}`:""]},`${e.mode}:${e.memoryId}`))})]}),M&&t.jsxs("div",{className:"p-4 rounded-2xl bg-primary/10 border border-primary/20",children:[t.jsxs("div",{className:"flex items-center justify-between mb-2",children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(m,{className:"w-4 h-4 animate-spin text-primary"}),t.jsxs("span",{className:"text-sm font-bold text-primary",children:["Processing ","video"===U?"video posters":"metadata"===U?"media metadata":"image thumbnails","..."]})]}),t.jsxs("span",{className:"text-sm font-bold text-primary",children:[z," / ",T??"?"]})]}),t.jsx("div",{className:"h-2 bg-primary/20 rounded-full overflow-hidden",children:t.jsx("div",{className:"h-full bg-primary transition-all duration-300 rounded-full",style:{width:`${A}%`}})})]}),L&&!M&&t.jsx("div",{className:l("p-4 rounded-2xl border text-center","incomplete"===Q?"bg-amber-500/10 border-amber-500/20":"bg-green-500/10 border-green-500/20"),children:t.jsxs("p",{className:l("text-sm font-bold","incomplete"===Q?"text-amber-600":"text-green-500"),children:[B.current?"Stopped.":"incomplete"===Q?"Incomplete pass.":"Done!"," Images: ",_.image," processed, videos: ",_.video," processed, metadata: ",w," processed.",(v.image>0||v.video>0||q>0)&&` Failures: ${v.image} image, ${v.video} video, ${q} metadata.`]})}),t.jsxs("div",{className:"flex gap-3 flex-wrap",children:[t.jsx(i,{variant:"outline",onClick:F,disabled:M,className:"rounded-2xl h-12 px-6 font-bold",children:"Refresh Stats"}),M?t.jsxs(i,{onClick:()=>{B.current=!0},variant:"outline",className:"flex-1 h-12 rounded-2xl border-destructive/50 text-destructive hover:bg-destructive/10 font-bold gap-2",children:[t.jsx(u,{className:"w-4 h-4"})," Stop"]}):null]})]})}export{h as AdminMediaBackfillPanel};
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.