PageSourceSearch

https://bright-reimagine-spot.lovable.app/assets/ProgramSwapHub-DQ1_vWUc.js

js bright-reimagine-spot.lovable.app collected 2026-10-03 03:26:13 UTC 171,021 bytes, 7 lines download raw bytes

1import{aA as da,r as a,j as e,D as Ie,aO as ca,B as S,bu as la,b as Fe,d as Le,e as Me,g as Ve,y as Se,n as ma,E as ua,G as pa,H as xa,w as je,J as De,K as Ee,bk as ha,x as be,cl as Zs,aD as Ae,L as M,I as ee,au as fs,O as Y,f as Ps,s as j,a8 as d,aV as fa,aM as qe,V as Qs,a6 as ht,be as et,a4 as Dt,a5 as Et,a7 as qt,S as us,o as ps,q as xs,t as hs,v as ve,b4 as Ds,T as Ze,Y as rs,Z as ns,_ as is,$ as os,a0 as ds,a1 as cs,a2 as ls,a3 as ms,aI as _a,W as ga,aa as ja,ab as ba,ac as va,ad as Na,ae as ya,R as $s,cb as Ot,cx as wa,ay as ka,i as It,aB as Sa,bf as Ca,cV as Ra,cW as Aa,ah as ft,ai as _t,cE as Ta,ak as gt,al as jt,aL as $a}from"./index-ClJJfLql.js";import{e as Xe}from"./edgeFunctionError-BEihx-nH.js";import{f as bt}from"./customerNameFallback-DSAMZIS_.js";import{D as Pa,a as Da,b as Ea,d as Fs}from"./dropdown-menu-BGacRKeP.js";import{C as st}from"./circle-x-BAhr6pcr.js";import{R as vt,a as Rs}from"./radio-group-DK_jRckd.js";import{M as qa}from"./map-pin-C3pGZQZE.js";import{P as Oa}from"./pencil-REu6gFhk.js";import{T as Ia,a as Fa,b as Ls,c as Ms}from"./tabs-CnEyqDc1.js";import{a as Je}from"./dateFormat-DcK9TW6a.js";import{E as Ns}from"./external-link-BGCut1Xj.js";import{H as La}from"./history-p0hbaprV.js";import{T as Ft}from"./trash-2-DZzhOmp5.js";import{P as Nt}from"./plus-KzjM6UO2.js";import"./index-B-TYoAC3.js";import"./circle-B3BzJXz1.js";import"./index-eRKAauYJ.js";/**
2 * @license lucide-react v0.462.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const Ma=da("Workflow",[["rect",{width:"8",height:"8",x:"3",y:"3",rx:"2",key:"by2w9f"}],["path",{d:"M7 11v4a2 2 0 0 0 2 2h4",key:"xkn7yn"}],["rect",{width:"8",height:"8",x:"13",y:"13",rx:"2",key:"1cgmvn"}]]),yt=!0,Ua=s=>Math.round(s*100)/100;function Us({replacementTotal:s,creditNoteAmount:n,priorCreditApplied:r}){const o=Number(s??0)||0,h=Number(n??0)||0,l=Number(r??0)||0;return Math.max(0,Ua(o-h-l))}const Ha={intake:"Intake",revocation:"Access revocation",credit:"Credit note",replacement:"Replacement product",closed:"Closed"},Bs=[{value:"new",label:"New",tone:"bg-slate-500/15 text-slate-700 dark:text-slate-300",short:"Just converted from a refund request — nothing has happened yet.",meaning:"The case exists but no credit note has been issued and the customer still has access to the original product.",cause:"A refund request was set to 'program_swap', which created this case via program-swap-create.",next:"Identify the platform (Kajabi or SamCart) and start the access-revocation step.",group:"intake"},{value:"credit_note_pending",label:"Credit Note Pending",tone:"bg-amber-500/15 text-amber-700 dark:text-amber-300",short:"Revocation started — the credit note has not been issued yet.",meaning:"Work is underway on the original product: cancellation or revocation has been requested but is not confirmed.",cause:"Someone actioned the case from 'new' — typically a SamCart manual-cancel request or a Kajabi revoke attempt.",next:"Confirm the original access was actually revoked, then issue the credit note.",group:"revocation"},{value:"access_revoked_ready_for_credit_note",label:"Ready for credit note",tone:"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300",short:"Access is revoked — the credit note can now be issued.",meaning:"The original product access has been confirmed revoked. The credit gate's second condition is satisfied.",cause:"A speaker or admin confirmed revocation, stamping access_revoked_at on the case.",next:"Issue the credit note (program-swap-issue-credit-note).",group:"revocation"},{value:"credit_note_issued",label:"Credit Note Issued",tone:"bg-sky-500/15 text-sky-700 dark:text-sky-300",short:"Credit note issued and emailed — the customer can now pick a replacement.",meaning:"The credit note PDF was generated, emailed, and the credit balance was written to the customer's wallet. The 12-month expiry clock is running.",cause:"program-swap-issue-credit-note completed, and enforce_swap_credit_gate allowed the transition.",next:"Agree the replacement product with the customer.",group:"credit"},{value:"selecting_product",label:"Selecting Product",tone:"bg-indigo-500/15 text-indigo-700 dark:text-indigo-300",short:"Not currently used — the app never writes this status.",meaning:"Intended to mark the window while a customer chooses a replacement. The database accepts it but no case has ever held it.",cause:"Nothing in the app writes this value.",next:"Ignore. Treat 'Credit Note Issued' as the replacement-selection stage.",group:"replacement",usage:"unused"},{value:"top_up_required",label:"Top-up Required",tone:"bg-orange-500/15 text-orange-700 dark:text-orange-300",short:"The replacement costs more than the credit — a top-up is owed.",meaning:"A replacement was chosen whose price exceeds the available credit. The difference is stored on top_up_amount_due.",cause:"The replacement price was compared to the credit balance and came out higher.",next:"Create the Stripe top-up payment link or invoice and send it to the customer.",group:"replacement"},{value:"top_up_sent",label:"Top-up Sent",tone:"bg-orange-500/15 text-orange-700 dark:text-orange-300",short:"The customer has been sent a payment link — waiting on payment.",meaning:"A Stripe payment link or invoice exists for the outstanding difference and is awaiting payment.",cause:"program-swap-create-topup-link created the link and marked top_up_status as 'sent'.",next:"Wait for stripe-topup-sync to pick up the payment, or record a confirmed manual payment.",group:"replacement"},{value:"top_up_paid",label:"Top-up Paid",tone:"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300",short:"Not currently used — payment is tracked on the top-up status column instead.",meaning:"The database accepts this value, but a paid top-up is recorded on the separate top_up_status column and the case moves straight to 'Product Swapped'.",cause:"Nothing in the app writes this value.",next:"Ignore. Read the Top-up status column for payment state.",group:"replacement",usage:"unused"},{value:"product_swapped",label:"Product Swapped",tone:"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300",short:"Speakers have been asked to grant access — this is NOT finished.",meaning:"Every speaker on the replacement product has been sent a grant request. The commission ledger rows do not exist until someone confirms the re-allocation.",cause:"The grant requests were sent from the case drawer.",next:"Chase the speaker for confirmation, then confirm the re-allocation so the ledger is written and the case can complete.",group:"replacement"},{value:"completed",label:"Completed",tone:"bg-emerald-600/20 text-emerald-700 dark:text-emerald-300",short:"Done — replacement access confirmed and the ledger settled.",meaning:"Access to the replacement was confirmed granted and the case is closed. Any leftover credit stays on the customer's wallet.",cause:"An admin confirmed the grant, or force-completed the case manually.",next:"Nothing. Reopen only if the customer disputes the outcome.",group:"closed"},{value:"returned_to_pending_refund",label:"Returned to Refund",tone:"bg-rose-500/15 text-rose-700 dark:text-rose-300",short:"The customer declined the swap — it went back to the refund queue.",meaning:"The swap was abandoned and the underlying refund request is live again in the Refunds Hub.",cause:"Someone returned the case to the refund lane.",next:"Handle it as a normal refund in the Refunds Hub.",group:"closed"},{value:"cancelled",label:"Cancelled",tone:"bg-muted text-muted-foreground",short:"Cancelled — no swap, no refund, no further action.",meaning:"The case was stopped deliberately. It stays visible for audit and no longer blocks deletion of the refund request.",cause:"An admin cancelled the case from the drawer or the row menu.",next:"Nothing.",group:"closed"}],Ba=Bs,za=Object.fromEntries(Bs.map(s=>[s.value,s])),Lt=new Set(["completed","returned_to_pending_refund","cancelled"]),Ka=new Set(["credit_note_issued","selecting_product","top_up_required","top_up_sent","top_up_paid","product_swapped","completed"]),Ga=[{value:"none",label:"None",meaning:"No top-up owed — the credit covers the replacement."},{value:"pending",label:"Pending",meaning:"A top-up is owed but no link or invoice has been sent yet."},{value:"sent",label:"Sent",meaning:"A Stripe payment link or invoice is with the customer, awaiting payment."},{value:"paid",label:"Paid",meaning:"Money was actually collected — a Stripe PaymentIntent or a confirmed manual reference exists."},{value:"void",label:"Void",meaning:"The top-up was cancelled or reversed and is no longer owed."}],Va=["intake","revocation","credit","replacement","closed"];function Wa({className:s}){const[n,r]=a.useState(!1);return e.jsxs(Ie,{open:n,onOpenChange:r,children:[e.jsx(ca,{asChild:!0,children:e.jsxs(S,{variant:"ghost",size:"sm",className:s,children:[e.jsx(la,{className:"h-4 w-4 mr-1.5"})," What do these mean?"]})}),e.jsxs(Fe,{className:"max-w-3xl max-h-[85vh] overflow-y-auto",children:[e.jsxs(Le,{children:[e.jsx(Me,{children:"Program Swap case statuses"}),e.jsx(Ve,{children:"Every value the case status can hold, in lifecycle order — what it means, how a case got there, and what to do next."})]}),e.jsxs("div",{className:"rounded-md border border-border bg-muted/40 p-3 text-sm",children:[e.jsx("div",{className:"font-medium mb-1",children:"The credit gate"}),e.jsxs("p",{className:"text-muted-foreground",children:["No case can pass ",e.jsx("span",{className:"font-mono text-xs",children:"credit_note_issued"})," until both conditions hold: the credit note has been issued ",e.jsx("em",{children:"and"})," access to the original product has been revoked. The database enforces this, so a case stuck before the gate is missing one of those two things."]})]}),e.jsx("div",{className:"space-y-6 mt-2",children:Va.map(o=>{const h=Bs.filter(l=>l.group===o);return h.length===0?null:e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-wide text-muted-foreground font-medium",children:Ha[o]}),h.map(l=>e.jsxs("div",{className:"rounded-md border border-border p-3 space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Se,{variant:"secondary",className:`inline-flex items-center whitespace-nowrap rounded-md px-2 py-0.5 text-xs font-medium ${l.tone}`,children:l.label}),e.jsx("span",{className:"font-mono text-[11px] text-muted-foreground",children:l.value}),l.usage==="unused"&&e.jsx(Se,{variant:"outline",className:"text-[10px]",children:"Not currently used"}),Ka.has(l.value)&&e.jsx(Se,{variant:"outline",className:"text-[10px]",children:"After the credit gate"})]}),e.jsx("p",{className:"text-sm",children:l.meaning}),e.jsxs("div",{className:"grid gap-1 text-xs text-muted-foreground",children:[e.jsxs("div",{children:[e.jsx("span",{className:"font-medium text-foreground",children:"How it got here: "}),l.cause]}),e.jsxs("div",{children:[e.jsx("span",{className:"font-medium text-foreground",children:"What to do next: "}),l.next]})]})]},l.value))]},o)})}),e.jsxs("div",{className:"space-y-2 mt-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-wide text-muted-foreground font-medium",children:"Top-up status column"}),e.jsx("table",{className:"w-full text-sm border border-border rounded-md overflow-hidden",children:e.jsx("tbody",{children:Ga.map(o=>e.jsxs("tr",{className:"border-t border-border first:border-t-0",children:[e.jsx("td",{className:"p-2 align-top font-mono text-xs w-24",children:o.value}),e.jsx("td",{className:"p-2 align-top text-muted-foreground",children:o.meaning})]},o.value))})})]})]})]})}function Ys({label:s,count:n,tone:r,tip:o,selected:h,onClick:l}){return e.jsxs(ua,{children:[e.jsx(pa,{asChild:!0,children:e.jsxs("button",{type:"button","aria-pressed":h,onClick:l,className:`inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-xs font-medium transition-colors ${r??"bg-muted text-muted-foreground"} ${h?"border-primary ring-2 ring-primary/40":"border-transparent hover:border-border"}`,children:[e.jsx("span",{children:s}),e.jsx("span",{className:"tabular-nums opacity-70",children:n})]})}
6),e.jsx(xa,{className:"max-w-xs",children:o})]})}function Ya({rows:s,value:n,onChange:r,className:o}){const{counts:h,order:l}=a.useMemo(()=>{const c=new Map;for(const f of s)c.set(f.status,(c.get(f.status)??0)+1);const k=Bs.map(f=>f.value),i=[...c.keys()].filter(f=>!k.includes(f)).sort();return{counts:c,order:[...k,...i]}},[s]),p=a.useMemo(()=>s.filter(c=>!Lt.has(c.status)).length,[s]),b=c=>r(n===c?"all":c);return e.jsx(ma,{delayDuration:200,children:e.jsxs("div",{className:`flex flex-wrap items-center gap-2 ${o??""}`,children:[e.jsx(Ys,{label:"All cases",count:s.length,tone:"bg-primary/10 text-primary",tip:"Every case in the hub, whatever its status. Deleted cases live on the Deleted tab.",selected:n==="all",onClick:()=>r("all")}),e.jsx(Ys,{label:"Active",count:p,tone:"bg-primary/10 text-primary",tip:"Cases still in flight — everything except Completed, Returned to Refund and Cancelled.",selected:n==="active",onClick:()=>r("active")}),e.jsx("span",{className:"h-5 w-px bg-border mx-1","aria-hidden":!0}),l.map(c=>{const k=h.get(c)??0,i=n===c;if(k===0&&!i)return null;const f=za[c];return e.jsx(Ys,{label:(f==null?void 0:f.label)??c,count:k,tone:f==null?void 0:f.tone,tip:(f==null?void 0:f.short)??`Unrecognised status "${c}" found in the data.`,selected:i,onClick:()=>b(c)},c)}),e.jsx(Wa,{className:"ml-auto"})]})})}function tt(s){if(!s)return"—";try{return Ps(new Date(s),"dd/MM/yyyy HH:mm")}catch{return"—"}}const Ja="Subscription data is synced from SamCart and is known to lag. Only 8 of 38 SamCart swap cases have a subscription record at all — treat this as a hint, not proof. Always confirm in SamCart itself.";function Xa({customerId:s}
6){const[n,r]=a.useState(!1),[o,h]=a.useState(!1),[l,p]=a.useState([]);a.useEffect(()=>{if(!s)return;let c=!1;return(async()=>{r(!0),h(!1);const{data:k,error:i}=await j.from("subscriptions").select("samcart_subscription_id, status, recurring_price, billing_frequency, next_rebill_date, product_name").eq("customer_id",s).order("next_rebill_date",{ascending:!1,nullsFirst:!1});c||(i?h(!0):p(k??[]),r(!1))})(),()=>{c=!0}},[s]);const b=l.filter(c=>(c.status??"").toLowerCase()==="active");return e.jsxs("div",{className:"space-y-1 text-xs",children:[n?e.jsxs("div",{className:"text-muted-foreground inline-flex items-center gap-1",children:[e.jsx(Y,{className:"h-3 w-3 animate-spin"})," Loading subscription data…"]}):s?o?e.jsx("div",{className:"text-muted-foreground",children:"Couldn't load subscription data."}):b.length>0?e.jsx("div",{className:"rounded-md border border-destructive/40 bg-destructive/10 p-2 text-destructive space-y-0.5",children:b.map((c,k)=>e.jsxs("div",{children:[e.jsx("strong",{children:"Active SamCart subscription found"})," — ",c.product_name??"unnamed product",","," ",c.recurring_price!=null?`$${Number(c.recurring_price).toFixed(2)}`:"price unknown"," ",c.billing_frequency??"",", next rebill"," ",c.next_rebill_date?tt(c.next_rebill_date):"unknown",". This will keep charging until cancelled."]},k))}):l.length>0?e.jsxs("div",{className:"text-muted-foreground space-y-0.5",children:[e.jsx("div",{children:"Subscriptions on record (none active):"}),l.map((c,k)=>e.jsxs("div",{className:"font-mono",children:[c.samcart_subscription_id??"—"," · ",c.product_name??"—"," · ",c.status??"—"]},k))]}):e.jsx("div",{className:"text-muted-foreground",children:"No SamCart subscription found for this customer in our data."}):e.jsx("div",{className:"text-muted-foreground",children:"No customer record linked to this case — subscription data unavailable."}),e.jsx("div",{className:"text-muted-foreground",children:Ja})]})}function Za({row:s,onChanged:n}){const[r,o]=a.useState(null),[h,l]=a.useState(s.samcart_order_id??""),[p,b]=a.useState(""),[c,k]=a.useState(!1),i=s.samcart_cancellation_outcome,f=y=>{l(s.samcart_order_id??""),b(s.samcart_manual_confirmation_notes??""),o(y)},O=async()=>{if(r){k(!0);try{const{data:y,error:A}=await j.functions.invoke("program-swap-confirm-samcart-revocation",{body:{case_id:s.id,outcome:r,...r==="cancelled"?{samcart_order_id:h.trim()||null}:{},notes:p.trim()||null}});if(A)throw A;if(!(y!=null&&y.ok)){d.error((y==null?void 0:y.error)??"Could not record the SamCart step");return}d.success(r==="cancelled"?"SamCart cancellation recorded":"Recorded as nothing to cancel"),o(null),n()}catch(y){d.error((y==null?void 0:y.message)??"Could not record the SamCart step")}finally{k(!1)}}};return e.jsxs(e.Fragment,{children:[e.jsxs(je,{className:i==="cancelled"?"border-emerald-500/40 bg-emerald-500/5":i==="not_applicable"?"border-border bg-muted/30":"border-amber-500/40 bg-amber-500/5",children:[e.jsx(De,{className:"pb-2",children:e.jsxs(Ee,{className:"text-sm flex items-center gap-2",children:[e.jsx(ha,{className:"h-4 w-4"})," SamCart cancellation (manual)"]})}),e.jsx(be,{className:"space-y-3 text-xs",children:i?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:i==="cancelled"?"flex items-center gap-2 font-medium text-emerald-700 dark:text-emerald-300":"flex items-center gap-2 font-medium text-muted-foreground",children:i==="cancelled"?e.jsxs(e.Fragment,{children:[e.jsx(Ae,{className:"h-3.5 w-3.5"}),"SamCart cancelled on ",tt(s.samcart_manual_confirmation_at)," by"," ",e.jsx("span",{className:"font-mono",children:s.samcart_manual_confirmation_by_email??"—"})]}):e.jsxs(e.Fragment,{children:[e.jsx(Zs,{className:"h-3.5 w-3.5"}),"Marked as nothing to cancel on"," ",tt(s.samcart_manual_confirmation_at)," by"," ",e.jsx("span",{className:"font-mono",children:s.samcart_manual_confirmation_by_email??"—"})]})}),s.samcart_manual_confirmation_notes&&e.jsxs("div",{className:"text-muted-foreground",children:["Notes: ",s.samcart_manual_confirmation_notes]}),i==="cancelled"&&s.samcart_order_id&&e.jsxs("div",{className:"text-muted-foreground",children:["SamCart order ",e.jsx("span",{className:"font-mono",children:s.samcart_order_id})]}),e.jsx(S,{size:"sm",variant:"ghost",onClick:()=>f(i==="cancelled"?"cancelled":"not_applicable"),children:"Update"})]}):e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"text-amber-800 dark:text-amber-300",children:"SamCart is not cancelled automatically. Sending the revocation request only emails the customer and the product owner. If this purchase has a payment plan or subscription, it keeps billing until someone cancels it inside SamCart."}),e.jsx(Xa,{customerId:s.customer_id}),e.jsxs("div",{className:"flex flex-wrap gap-2 pt-1",children:[e.jsx(S,{size:"sm",onClick:()=>f("cancelled"),children:"Record SamCart cancellation"}),e.jsxs(S,{size:"sm",variant:"ghost",onClick:()=>f("not_applicable"),children:[e.jsx(Zs,{className:"h-3.5 w-3.5 mr-1"}),"No recurring subscription — nothing to cancel"]})]})]})})]}),e.jsx(Ie,{open:r!==null,onOpenChange:y=>!y&&o(null),children:e.jsxs(Fe,{className:"max-w-md",children:[e.jsxs(Le,{children:[e.jsx(Me,{children:r==="not_applicable"?"No recurring subscription to cancel":"Record SamCart cancellation"}),e.jsx(Ve,{children:r==="not_applicable"?"Records that this purchase is a one-off with nothing recurring to cancel in SamCart.":"Records that you cancelled the order / subscription inside SamCart. This does not change the access-revocation record."})]}),e.jsxs("div",{className:"space-y-3",children:[r==="cancelled"&&e.jsxs("div",{className:"space-y-1",children:[e.jsx(M,{className:"text-xs",children:"SamCart order ID (optional)"}),e.jsx(ee,{value:h,onChange:y=>l(y.target.value)})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(M,{className:"text-xs",children:"Notes (optional)"}),e.jsx(ee,{value:p,onChange:y=>b(y.target.value),placeholder:"e.g. cancelled subscription 5130068, refunded nothing"})]})]}),e.jsxs(fs,{children:[e.jsx(S,{variant:"ghost",onClick:()=>
6o(null),disabled:c,children:"Cancel"}),e.jsxs(S,{onClick:()=>void O(),disabled:c,children:[c&&e.jsx(Y,{className:"h-3.5 w-3.5 mr-1 animate-spin"}),"Confirm"]})]})]})})]})}function Ye(s){if(!s)return"—";try{return Ps(new Date(s),"dd/MM/yyyy HH:mm")}catch{return"—"}}function wt(s){const n={pending:"bg-amber-500/15 text-amber-700 dark:text-amber-300",sent:"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300",delivered:"bg-emerald-600/20 text-emerald-700 dark:text-emerald-300",failed:"bg-destructive/15 text-destructive",bounced:"bg-destructive/15 text-destructive"};return e.jsx(Se,{variant:"secondary",className:n[s]??"bg-muted text-muted-foreground",children:s})}const Js={product_speaker_auto:{label:"Product → speaker (auto)",blurb:"Use the speaker automatically resolved from the original product. Pick this when the auto-resolved recipient above is correct."},manual_override:{label:"Manual override",blurb:"You edited the recipient email/name above and it now differs from the auto-resolved value. Use this when the auto-resolution was wrong and you're substituting a different owner."},manual_entry:{label:"Manual entry (no auto match)",blurb:"The product couldn't be linked to a speaker automatically, so you're entering the recipient by hand. Use this for one-off products, older catalog entries, or bundles without a mapped owner."},unresolved:{label:"Unresolved — skip speaker email",blurb:"Send only the customer notification and skip the speaker email entirely. NOT available for SamCart cases — for SamCart, the speaker email is the revocation request itself, so a recipient is required."}};function Qa({row:s,onChanged:n}){const r=(s.original_source_platform??"").toLowerCase(),o=r==="kajabi",h=r==="samcart",[l,p]=a.useState(!1),[b,c]=a.useState(s.auto_resolved_owner_email),[k,i]=a.useState(s.auto_resolved_owner_name),[f,O]=a.useState(s.final_owner_email_used??s.auto_resolved_owner_email??""),[y,A]=a.useState(s.final_owner_name_used??s.auto_resolved_owner_name??""),[T,E]=a.useState(s.owner_resolution_method??"product_speaker_auto"),[_,g]=a.useState(s.owner_resolution_notes??""),[F,q]=a.useState(!1),[J,w]=a.useState(null),$=a.useCallback(async(u=!1)=>{if(!(!u&&s.auto_resolved_owner_email)){p(!0),w(null);try{const D=String(s.original_product_id??"").trim();if(!D){w("This case has no original_product_id — the recipient cannot be auto-resolved. Enter it manually below.");return}const we=/^[0-9a-f-]{36}$/i.test(D),he=async(de,ce)=>{const{data:le,error:ie}=await ce();return ie?(w(`Lookup failed: ${ie.message} (${de})`),{speakerId:null,failed:!0}):{speakerId:(le==null?void 0:le.speaker_id)??null,failed:!1}},Ue=()=>he("products.id",async()=>await j.from("products").select("speaker_id").eq("id",D).maybeSingle()),_s=()=>he("products.platform_product_id",async()=>await j.from("products").select("speaker_id").eq("platform_product_id",D).maybeSingle()),gs=()=>he("kajabi_offers.id",async()=>await j.from("kajabi_offers").select("speaker_id").eq("id",D).maybeSingle()),He=()=>he("kajabi_offers.kajabi_offer_id",async()=>await j.from("kajabi_offers").select("speaker_id").eq("kajabi_offer_id",D).maybeSingle()),Qe=we?[Ue,_s]:[_s],m=we?[gs,He]:[He],C=o?[...m,...Qe]:[...Qe,...m];let H=null;for(const de of C){const ce=await de();if(ce.failed)return;if(ce.speakerId){H=ce.speakerId;break}}if(!H){w(`No product record with a speaker was found for this case's original_product_id (${D}). Assign a speaker to the product under Products, then click Re-resolve — or enter the recipient manually below.`);return}const{data:Q,error:ae}=await j.from("speakers").select("id, name, support_email").eq("id",H).maybeSingle();if(ae){w(`Lookup failed: ${ae.message} (speakers)`);return}if(!Q){w(`Speaker ${H} not found — enter the recipient manually below.`);return}const te=Q.support_email??null,ne=Q.name??null;if(te||w(`Speaker '${ne??H}' has no support_email — add one, then click Re-resolve.`),te||ne){c(te),i(ne),!f&&te&&O(te),!y&&ne&&A(ne);const{error:de}=await j.from("program_swap_cases").update({auto_resolved_owner_email:te,auto_resolved_owner_name:ne,auto_resolved_speaker_id:H}).eq("id",s.id);de&&w(`Resolved, but saving it failed: ${de.message}`),n()}}catch(D){w(`Lookup failed: ${(D==null?void 0:D.message)??String(D)}`),console.warn("auto-resolve owner failed",D)}finally{p(!1)}}},[s.id,s.original_product_id,s.auto_resolved_owner_email,o]);a.useEffect(()=>{$()},[$]),a.useEffect(()=>{c(s.auto_resolved_owner_email),i(s.auto_resolved_owner_name),w(null),O(s.final_owner_email_used??s.auto_resolved_owner_email??""),A(s.final_owner_name_used??s.auto_resolved_owner_name??""),E(s.owner_resolution_method??"product_speaker_auto"),g(s.owner_resolution_notes??"")},[s.id]),a.useEffect(()=>{if(s.owner_resolution_method)return;const u=f.trim().toLowerCase(),D=(b??"").trim().toLowerCase();!u&&!D?E(h?"manual_entry":"unresolved"):D&&u===D?E("product_speaker_auto"):D&&u&&u!==D?E("manual_override"):!D&&u&&E("manual_entry")},[f,b,s.owner_resolution_method,h]);
6const[pe,I]=a.useState(!1),K=!!s.access_revoked_at,U=a.useMemo(()=>F?o?K?T!=="unresolved"&&!f.trim()?"Enter the speaker recipient's email or switch to 'Unresolved'.":null:"Kajabi access has not been revoked yet — run the Kajabi cancel step first.":h?T==="unresolved"?"SamCart requires a resolved speaker recipient — the speaker email is the revocation request itself.":f.trim()?null:"Enter the speaker recipient's email — the email is the SamCart revocation request.":K?T!=="unresolved"&&!f.trim()?"Enter the speaker recipient's email or switch to 'Unresolved'.":null:"Access has not been revoked yet.":"Confirm the recipient before sending.",[F,o,h,K,T,f]),_e=U===null,xe=async()=>{I(!0);try{const{data:u,error:D}=await j.functions.invoke("program-swap-send-revocation-emails",{body:{case_id:s.id,final_owner_email:T==="unresolved"?null:f.trim(),final_owner_name:y.trim()||null,owner_resolution_method:T,owner_resolution_notes:_.trim()||null}});if(D)throw new Error(D.message);u!=null&&u.ok?u!=null&&u.samcart_revoke_stamped?d.success("Customer notified + speaker asked to revoke SamCart access."):d.success(u!=null&&u.speaker_skipped?"Customer notified. Speaker recipient unresolved — skipped.":"Customer and speaker notified."):d.error(`Some emails failed — retry. ${(u==null?void 0:u.error)??""}${u!=null&&u.customer_sent?" (customer sent)":""}`),n(),me()}catch(u){d.error(`Send failed: ${(u==null?void 0:u.message)??"Unknown error"}`)}finally{I(!1)}},[Ne,Z]=a.useState([]),[se,ye]=a.useState(!0),[P,re]=a.useState(null),me=a.useCallback(async()=>{ye(!0);const{data:u,error:D}=await j.from("program_swap_correspondence").select("*").eq("program_swap_case_id",s.id).order("created_at",{ascending:!1});D?d.error(`Correspondence: ${D.message}`):Z(u??[]),ye(!1)},[s.id]);a.useEffect(()=>{me()},[me]);const oe=Js[T],v=new Set(["customer_revocation_notice","speaker_revocation_notice"]),L=a.useMemo(()=>Ne.filter(u=>v.has(u.email_type)&&(u.delivery_status==="sent"||u.delivery_status==="delivered")),[Ne]),G=s.status==="access_revoked_ready_for_credit_note"||L.length>0,ge=a.useMemo(()=>{const u=L.map(D=>D.sent_at??D.created_at).filter(Boolean);return u.length===0?null:u.sort().slice(-1)[0]},[L]);return e.jsxs(je,{children:[e.jsx(De,{className:"pb-3",children:e.jsxs(Ee,{className:"text-sm flex items-center gap-2",children:[e.jsx(fa,{className:"h-4 w-4"})," Phase 1 — Revoke access & notify"]})}),e.jsxs(be,{className:"space-y-4",children:[h&&!K&&e.jsx("div",{className:"rounded-md border border-amber-500/40 bg-amber-500/5 p-3 text-xs space-y-1",children:e.jsxs("div",{className:"flex items-start gap-2 text-amber-800 dark:text-amber-300",children:[e.jsx(qe,{className:"h-4 w-4 shrink-0 mt-0.5"}),e.jsxs("div",{children:[e.jsx("strong",{children:"SamCart revocation flow"}),e.jsxs("p",{className:"mt-1 text-muted-foreground",children:["SamCart doesn't allow revoking a customer's access via API. Instead, resolve the speaker/product owner below and send the notification — the speaker email IS the revocation request (they remove access in whichever system they use to manage that program, and reply-all to confirm). Once you send successfully, the case will be stamped as revoked with method"," ",e.jsx("span",{className:"font-mono",children:"speaker_revoke_requested"}),". This does not cancel anything in SamCart — see the SamCart cancellation step below."]})]})]})}),K&&e.jsxs("div",{className:s.access_revoked_method==="speaker_revoke_requested"?"rounded-md border border-amber-500/40 bg-amber-500/5 p-3 text-xs space-y-1":s.access_revoked_method==="samcart_manual"?"rounded-md border border-border bg-muted/30 p-3 text-xs space-y-1":"rounded-md border border-emerald-500/40 bg-emerald-500/5 p-3 text-xs space-y-1",children:[s.access_revoked_method==="speaker_revoke_requested"?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-2 text-amber-800 dark:text-amber-300 font-medium",children:[e.jsx(Qs,{className:"h-3.5 w-3.5"}),"Revocation emails sent on ",Ye(s.access_revoked_at)]}),e.jsx("div",{className:"text-muted-foreground",children:"The customer was notified and the product owner was asked to remove access. Nothing has been cancelled in SamCart — the original order and any recurring subscription keep billing until the step below is recorded."})]}):s.access_revoked_method==="samcart_manual"?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-2 font-medium",children:[e.jsx(ht,{className:"h-3.5 w-3.5"}),"Recorded as revoked on ",Ye(s.access_revoked_at)," (legacy manual entry)"]}),e.jsx("div",{className:"text-muted-foreground",children:"Stamped by the old manual acknowledgement step, before revocation emails and SamCart cancellation were tracked separately."})]}):e.jsxs("div",{className:"flex items-center gap-2 text-emerald-700 dark:text-emerald-300 font-medium",children:[e.jsx(Ae,{className:"h-3.5 w-3.5"}),"Access revoked on ",Ye(s.access_revoked_at)]}),e.jsxs("div",{className:"text-muted-foreground",children:["Method: ",e.jsx("span",{className:"font-mono",children:s.access_revoked_method??"—"}),s.access_revoked_by_email&&e.jsxs(e.Fragment,{children:[" ","· by ",e.jsx("span",{className:"font-mono",children:s.access_revoked_by_email})]}),s.samcart_order_id&&e.jsxs(e.Fragment,{children:[" ","· SamCart order ",e.jsx("span",{className:"font-mono",children:s.samcart_order_id})]})]})]}),h&&e.jsx(Za,{row:s,onChanged:n}),e.jsxs("div",{className:"rounded-md border border-border p-3 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wide",children:"Speaker / product owner recipient"}),e.jsxs(S,{size:"sm",variant:"ghost",disabled:l,onClick:()=>{c(null),$(!0)},children:[e.jsx(et,{className:`h-3 w-3 mr-1 ${l?"animate-spin":""}`}),"Re-resolve"]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Auto-resolved:"," ",b?e.jsxs("span",{className:"font-mono text-foreground",children:[k?`${k} `:"","<",b,">"]}):e.jsx("span",{className:"italic",children:"none — enter recipient manually below"}),J&&e.jsx("span",{className:"block mt-1 text-amber-700 dark:text-amber-300",children:J})]}),e.jsxs("div",{className:"grid sm:grid-cols-2 gap-2",children:[e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Recipient name"}),e.jsx(ee,{value:y,onChange:u=>A(u.target.value),disabled:G})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Recipient email"}),e.jsx(ee,{type:"email",value:f,onChange:u=>O(u.target.value),disabled:G})]})]}),e.jsxs("div",{className:"grid sm:grid-cols-2 gap-2",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-1.5 mb-1",children:[e.jsx(M,{className:"text-xs",children:"Resolution method"}),e.jsxs(Dt,{children:[e.jsx(Et,{asChild:!0,children:e.jsx("button",{type:"button",className:"text-muted-foreground hover:text-foreground transition-colors","aria-label":"Resolution method help",children:e.jsx(ht,{className:"h-3 w-3"})})}),e.jsxs(qt,{align:"start",className:"w-80 text-xs space-y-2",children:[e.jsx("div",{className:"font-semibold text-sm",children:"Resolution method"}),e.jsx("p",{className:"text-muted-foreground",children:"How the speaker/product-owner recipient was determined. Choose the option that best describes the recipient you just entered."}),e.jsx("ul",{className:"space-y-1.5",children:Object.keys(Js).map(u=>{const D=Js[u];return e.jsxs("li",{className:"border-t border-border pt-1.5 first:border-0 first:pt-0",children:[e.jsx("div",{className:"font-medium text-foreground",children:D.label}),e.jsx("div",{className:"text-muted-foreground",children:D.blurb})]},u)})})]})]})]}),e.jsxs(us,{value:T,onValueChange:u=>E(u),disabled:G,children:[e.jsx(ps,{children:e.jsx(xs,{})}),e.jsxs(hs,{children:[e.jsx(ve,{value:"product_speaker_auto",children:"Product → speaker (auto)"}),e.jsx(ve,{value:"manual_override",children:"Manual override"}),e.jsx(ve,{value:"manual_entry",children:"Manual entry (no auto match)"}),e.jsxs(ve,{value:"unresolved",disabled:h,children:["Unresolved — skip speaker email",h?" (not available for SamCart)":""]})]})]}),e.jsx("div",{className:"text-[11px] text-muted-foreground mt-1 leading-snug",children:oe.blurb})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Resolution notes (optional)"}
6),e.jsx(ee,{value:_,onChange:u=>g(u.target.value),placeholder:"Why this recipient was chosen",disabled:G})]})]}),!G&&e.jsxs("div",{className:"flex items-start gap-2 pt-1",children:[e.jsx(Ds,{id:"recipient-confirm",checked:F,onCheckedChange:u=>q(u===!0)}),e.jsx(M,{htmlFor:"recipient-confirm",className:"text-xs leading-snug cursor-pointer",children:"I confirm this is the correct recipient for the speaker / product-owner notification."})]})]}),G?e.jsxs("div",{className:"rounded-md border border-emerald-500/40 bg-emerald-500/5 p-3 text-xs flex items-start gap-2 text-emerald-800 dark:text-emerald-300",children:[e.jsx(Ae,{className:"h-4 w-4 shrink-0 mt-0.5"}),e.jsxs("div",{children:[e.jsxs("div",{className:"font-medium",children:["Revocation notifications sent",ge?` on ${Ye(ge)}`:"","."]}),e.jsx("div",{className:"text-muted-foreground mt-0.5",children:"Phase 1 is complete — this step cannot be re-sent. See the correspondence log below for full details."})]})]}):e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 pt-1",children:[e.jsx("div",{className:"text-xs text-muted-foreground max-w-md",children:U??(h?"Sends the customer confirmation AND the speaker revocation request. [email protected] is CC'd on both.":"Customer email goes to the original buyer. Speaker email goes to the resolved owner. [email protected] is CC'd on both.")}),e.jsxs(S,{size:"sm",onClick:xe,disabled:pe||!_e,children:[pe?e.jsx(Y,{className:"h-3.5 w-3.5 mr-1 animate-spin"}):e.jsx(Qs,{className:"h-3.5 w-3.5 mr-1"}),h&&!K?"Send revocation request":"Send revocation notifications"]})]}),e.jsxs("div",{className:"rounded-md border border-border",children:[e.jsxs("div",{className:"px-3 py-2 border-b border-border flex items-center justify-between",children:[e.jsxs("div",{className:"text-xs font-semibold uppercase tracking-wide",children:["Correspondence (",Ne.length,")"]}),e.jsxs(S,{size:"sm",variant:"ghost",disabled:se,onClick:me,children:[e.jsx(et,{className:`h-3 w-3 mr-1 ${se?"animate-spin":""}`}),"Refresh"]})]}),se?e.jsxs("div",{className:"p-3 text-xs text-muted-foreground",children:[e.jsx(Y,{className:"h-3 w-3 animate-spin inline mr-1"})," Loading…"]}):Ne.length===0?e.jsx("div",{className:"p-3 text-xs text-muted-foreground italic",children:"No emails sent yet for this case."}):e.jsx("ul",{className:"divide-y divide-border",children:Ne.map(u=>e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>re(u),className:"w-full text-left p-3 text-xs space-y-1 hover:bg-muted/40 transition-colors focus:outline-none focus:bg-muted/40",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("div",{className:"font-medium truncate",children:u.subject}),wt(u.delivery_status)]}),e.jsxs("div",{className:"text-muted-foreground",children:[e.jsx("span",{className:"uppercase tracking-wide",children:u.email_type.replace(/_/g," ")})," ","· to ",e.jsx("span",{className:"font-mono",children:u.recipient_email}),u.cc_emails&&u.cc_emails.length>0&&e.jsxs(e.Fragment,{children:[" · cc ",e.jsx("span",{className:"font-mono",children:u.cc_emails.join(", ")})]})]}),e.jsxs("div",{className:"text-muted-foreground",children:[u.sent_at?`Sent ${Ye(u.sent_at)}`:`Created ${Ye(u.created_at)}`,u.provider_message_id&&e.jsxs(e.Fragment,{children:[" · id ",e.jsx("span",{className:"font-mono",children:u.provider_message_id})]}),u.sent_by_email&&e.jsxs(e.Fragment,{children:[" · by ",e.jsx("span",{className:"font-mono",children:u.sent_by_email})]})]}),u.error_message&&e.jsxs("div",{className:"text-destructive flex items-start gap-1",children:[e.jsx(st,{className:"h-3 w-3 mt-0.5 shrink-0"}),e.jsx("span",{children:u.error_message})]}),e.jsx("div",{className:"text-[10px] text-muted-foreground italic pt-0.5",children:"Click to view the full email"})]})},u.id))})]}),e.jsx(Ie,{open:!!P,onOpenChange:u=>!u&&re(null),children:e.jsxs(Fe,{className:"max-w-3xl max-h-[85vh] overflow-y-auto",children:[e.jsxs(Le,{children:[e.jsx(Me,{className:"text-base",children:(P==null?void 0:P.subject)??"Email"}),e.jsx(Ve,{className:"text-xs space-y-0.5",children:P&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("span",{className:"uppercase tracking-wide",children:P.email_type.replace(/_/g," ")})," ","· ",wt(P.delivery_status)]}),e.jsxs("div",{children:["To ",e.jsx("span",{className:"font-mono",children:P.recipient_email}),P.cc_emails&&P.cc_emails.length>0&&e.jsxs(e.Fragment,{children:[" · cc ",e.jsx("span",{className:"font-mono",children:P.cc_emails.join(", ")})]})]}),e.jsxs("div",{children:[P.sent_at?`Sent ${Ye(P.sent_at)}`:`Created ${Ye(P.created_at)}`,P.sent_by_email&&e.jsxs(e.Fragment,{children:[" · by ",e.jsx("span",{className:"font-mono",children:P.sent_by_email})]}),P.provider_message_id&&e.jsxs(e.Fragment,{children:[" · id ",e.jsx("span",{className:"font-mono",children:P.provider_message_id})]})]})]})})]}),(P==null?void 0:P.error_message)&&e.jsxs("div",{className:"rounded-md border border-destructive/40 bg-destructive/5 p-2 text-xs text-destructive flex items-start gap-1",children:[e.jsx(st,{className:"h-3 w-3 mt-0.5 shrink-0"}),e.jsx("span",{children:P.error_message})]}),P!=null&&P.body_html?e.jsx("iframe",{title:"Email preview",sandbox:"",srcDoc:P.body_html,className:"w-full min-h-[520px] rounded-md border border-border bg-white"}):P!=null&&P.body_text?e.jsx("pre",{className:"text-xs whitespace-pre-wrap bg-muted/40 rounded-md p-3 border border-border max-h-[520px] overflow-y-auto",children:P.body_text}):e.jsx("div",{className:"text-xs text-muted-foreground italic",children:"No email body stored."})]})})]})]})}const kt=5,St=s=>!!s&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);function er({caseRow:s,onCompleted:n}
6){const[r,o]=a.useState(!0),[h,l]=a.useState(!1),[p,b]=a.useState([]),[c,k]=a.useState({source_product_id:null,source_product_name:s.original_product_name,source_speaker_id:null}),[i,f]=a.useState(""),[O,y]=a.useState(""),[A,T]=a.useState(""),E=Number(s.credit_note_amount??0),_=Number(s.prior_credit_applied??0),g=s.top_up_status==="paid"?Number(s.top_up_amount_due??0):0,F=a.useMemo(()=>Math.round(p.reduce((I,K)=>I+(K.item_price||0),0)*100)/100,[p]),q=a.useMemo(()=>Math.round((E+_-F)*100)/100,[E,_,F]),J=q>0&&q<kt,w=q>0&&!J?q:0;a.useEffect(()=>{let I=!1;return(async()=>{o(!0);try{const{data:K}=await j.from("program_swap_replacement_items").select("id, product_id, product_name, product_price, source_platform").eq("case_id",s.id).order("created_at",{ascending:!0});let U=null,_e=s.original_product_name,xe=null;if(St(s.original_product_id)){const{data:Z}=await j.from("products").select("id, name, speaker_id").eq("id",s.original_product_id).maybeSingle();Z&&(U=Z.id,_e=Z.name??_e,xe=Z.speaker_id??null)}const Ne=[];for(const Z of K??[]){let se=null;const ye=Z.product_id??null;let P=null,re=null,me="manual",oe="";const v=Number(Z.product_price??0);if(Z.source_platform==="kajabi"&&Z.product_id){const{data:L}=await j.from("kajabi_offers").select("id, title, price, current_sale_price, speaker_id").eq("id",Z.product_id).maybeSingle();if(L){P=L.speaker_id??null;const G=Number(L.current_sale_price??0),ge=Number(L.price??0);G>0?(re=G,me="product_current_sale_price",oe="resolved from kajabi_offers.current_sale_price"):ge>0?(re=ge,me="product_price",oe="resolved from kajabi_offers.price"):v>0&&(re=v,me="product_price",oe="resolved from replacement item price (kajabi offer had no price)")}}else if(St(Z.product_id)){se=Z.product_id;const{data:L}=await j.from("products").select("id, name, speaker_id, price, current_sale_price").eq("id",Z.product_id).maybeSingle();if(L){P=L.speaker_id??null;const G=Number(L.current_sale_price??0),ge=Number(L.price??0);G>0?(re=G,me="product_current_sale_price",oe="resolved from products.current_sale_price"):ge>0?(re=ge,me="product_price",oe="resolved from products.price"):v>0&&(re=v,me="product_price",oe="resolved from replacement item price (product had no price)")}}Ne.push({item_id:Z.id,new_product_id:se,new_product_id_raw:ye,new_product_name:Z.product_name,new_speaker_id:P,commission_base:re,commission_base_source:me,commission_base_notes:oe,source_platform:Z.source_platform??"unknown",item_price:v})}I||(k({source_product_id:U,source_product_name:_e,source_speaker_id:xe}),b(Ne),o(!1))}catch(K){console.error(K),I||(d.error(`Resolution failed: ${(K==null?void 0:K.message)??K}`),o(!1))}})(),()=>{I=!0}},[s.id,s.original_product_id,s.original_product_name]);const $=p.length>0&&i!==""&&O!==""&&!h&&!r,pe=async()=>{var K;if(p.length===0)return;const I=Math.round((E+_+g)*100)/100;if(F>I+.01){d.error(`Consumed $${F.toFixed(2)} exceeds credit + prior credit + top-up $${I.toFixed(2)}. Correct item prices before completing this case.`);return}l(!0);try{const{data:U,error:_e}=await j.functions.invoke("program-swap-confirm-reallocation",{body:{case_id:s.id,old_speaker_paid:i||null,affiliate_paid:O||null,operator_notes:A||null}});if(_e)throw new Error(await Xe(_e));if(!(U!=null&&U.ok)){d.error((U==null?void 0:U.message)??(U==null?void 0:U.error)??"Re-allocation failed");return}(K=U.result)!=null&&K.idempotent?d.success("This case was already completed. Nothing was changed."):d.success(p.length>1?`Re-allocation confirmed. ${p.length} adjustments written. Case completed.`:"Re-allocation confirmed. Case completed."),n()}catch(U){console.error(U),d.error(`Failed: ${(U==null?void 0:U.message)??U}`)}finally{l(!1)}};return e.jsxs(je,{className:"border-amber-500/40 bg-amber-500/5",children:[e.jsx(De,{className:"pb-3",children:e.jsxs(Ee,{className:"text-sm flex items-center gap-2",children:[e.jsx(qe,{className:"h-4 w-4 text-amber-600"}),"Confirm re-allocation & complete case"]})}),e.jsx(be,{className:"space-y-4",children:r?e.jsxs("div",{className:"text-xs text-muted-foreground",children:[e.jsx(Y,{className:"h-3 w-3 animate-spin inline mr-1"})," Resolving replacement items / speakers / commission bases…"]}):p.length===0?e.jsx("div",{className:"text-xs text-muted-foreground italic",children:"Add at least one replacement product before completing the case."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3 text-xs",children:[e.jsxs("div",{className:"rounded-md border border-border p-2 bg-background/60",children:[e.jsx("div",{className:"font-medium mb-1",children:"From (original)"}),e.jsxs("div",{children:["Product: ",e.jsx("span",{className:"font-mono",children:c.source_product_name??"—"})]}),e.jsxs("div",{children:["Speaker: ",e.jsx("span",{className:"font-mono",children:c.source_speaker_id??"—"})]}),e.jsxs("div",{children:["Credit note: $",E.toFixed(2)]}),_>
60&&e.jsxs("div",{children:["Prior credit applied: $",_.toFixed(2)]}),e.jsxs("div",{children:["Top-up collected: $",g.toFixed(2)]})]}),e.jsxs("div",{className:"rounded-md border border-border p-2 bg-background/60",children:[e.jsxs("div",{className:"font-medium mb-1",children:["To (new) — ",p.length," ",p.length===1?"item":"items"]}),e.jsx("div",{className:"space-y-2",children:p.map((I,K)=>e.jsxs("div",{className:"border-t border-border/50 first:border-t-0 pt-1 first:pt-0",children:[e.jsxs("div",{className:"font-mono",children:[K+1,". ",I.new_product_name??"—"]}),e.jsxs("div",{children:["Speaker: ",e.jsx("span",{className:"font-mono",children:I.new_speaker_id??"—"})]}),e.jsxs("div",{children:["Commission base: ",I.commission_base!=null?`$${I.commission_base.toFixed(2)}`:"—",e.jsxs("span",{className:"text-muted-foreground ml-1",children:["(",I.commission_base_source,")"]})]}),e.jsxs("div",{children:["Item price: $",I.item_price.toFixed(2)]})]},I.item_id))}),e.jsxs("div",{className:"mt-2 pt-2 border-t border-border/50",children:[e.jsxs("div",{children:["Consumed by items: $",F.toFixed(2)]}),q>0?J?e.jsxs("div",{className:"text-amber-700 dark:text-amber-300",children:["Residue $",q.toFixed(2)," → auto write-off (< $",kt,")."]}):e.jsxs("div",{children:["Credit remaining: $",w.toFixed(2)," (kept as live balance)"]}):e.jsx("div",{children:"Credit remaining: $0.00"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(M,{className:"text-xs font-semibold",children:"Was the original speaker already paid commission on this sale?"}),e.jsxs(vt,{value:i,onValueChange:I=>f(I),className:"flex gap-4",children:[e.jsxs("label",{className:"flex items-center gap-1 text-sm cursor-pointer",children:[e.jsx(Rs,{value:"yes"})," Yes (clawback pending)"]}),e.jsxs("label",{className:"flex items-center gap-1 text-sm cursor-pointer",children:[e.jsx(Rs,{value:"no"})," No"]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(M,{className:"text-xs font-semibold",children:"Was the affiliate already paid commission on this sale?"}),e.jsxs(vt,{value:O,onValueChange:I=>y(I),className:"flex gap-4",children:[e.jsxs("label",{className:"flex items-center gap-1 text-sm cursor-pointer",children:[e.jsx(Rs,{value:"yes"})," Yes (clawback pending)"]}),e.jsxs("label",{className:"flex items-center gap-1 text-sm cursor-pointer",children:[e.jsx(Rs,{value:"no"})," No"]}),e.jsxs("label",{className:"flex items-center gap-1 text-sm cursor-pointer",children:[e.jsx(Rs,{value:"unknown"})," Unknown (manual review)"]})]})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(M,{className:"text-xs",children:"Notes (optional)"}),e.jsx(Ze,{value:A,onChange:I=>T(I.target.value),rows:2,placeholder:"Anything the finance / commissions team needs to know"})]}),e.jsxs(S,{size:"sm",onClick:pe,disabled:!$,children:[h?e.jsx(Y,{className:"h-3.5 w-3.5 mr-1 animate-spin"}):e.jsx(Ae,{className:"h-3.5 w-3.5 mr-1"}),"Confirm re-allocation & complete case",p.length>1?` (${p.length} adjustments)`:""]})]})})]})}function sr(s){if(!s)return"—";try{return Ps(new Date(s),"dd/MM/yyyy HH:mm")}catch{return"—"}}function tr({row:s,onChanged:n}){const[r,o]=a.useState(!1),[h,l]=a.useState(""),[p,b]=a.useState(!1),[c,k]=a.useState(!1),i=s.ghl_informed_at??null,f=async O=>{b(!0);try{const{data:y,error:A}=await j.functions.invoke("program-swap-mark-ghl-informed",{body:{case_id:s.id,informed:O,...O?{notes:h.trim()||null}:{}}});if(A)throw A;if(!(y!=null&&y.ok)){d.error((y==null?void 0:y.error)??"Could not update the GoHighLevel flag");return}d.success(O?"Marked as GoHighLevel informed":"GoHighLevel flag cleared"),k(!1),n()}catch(y){d.error((y==null?void 0:y.message)??"Could not update the GoHighLevel flag")}finally{b(!1)}};return e.jsxs(e.Fragment,{children:[e.jsxs(je,{className:i?"border-emerald-500/40 bg-emerald-500/5":void 0,children:[e.jsx(De,{className:"pb-2",children:e.jsxs(Ee,{className:"text-sm flex items-center gap-2",children:[e.jsx(Ma,{className:"h-4 w-4"})," GoHighLevel informed"]})}),e.jsx(be,{className:"space-y-2 text-xs",children:i?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-2 font-medium text-emerald-700 dark:text-emerald-300",children:[e.jsx(Ae,{className:"h-3.5 w-3.5"}),"GoHighLevel informed on ",sr(i)," by"," ",e.jsx("span",{className:"font-mono",children:s.ghl_informed_by_email??"—"})]}),s.ghl_informed_notes&&e.jsxs("div",{className:"text-muted-foreground",children:["Notes: ",s.ghl_informed_notes]}),e.jsx(S,{size:"sm",variant:"ghost",onClick:()=>k(!0),disabled:p,children:"Undo"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(Ds,{id:`ghl-informed-${s.id}`,checked:r,onCheckedChange:O=>o(O===!0)}),e.jsx(M,{htmlFor:`ghl-informed-${s.id}`,className:"text-xs font-normal",children:"GoHighLevel has been informed of this swap / top-up"})]}),e.jsx("p",{className:"text-muted-foreground",children:"Tick once the purchase-confirmation workflows and speaker-side integrations have been fired for the replacement product."}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(M,{className:"text-xs",children:"Notes (optional)"}),e.jsx(ee,{value:h,onChange:O=>l(O.target.value)})]}),e.jsxs(S,{size:"sm",disabled:!r||p,onClick:()=>void f(!0),children:[p&&e.jsx(Y,{className:"h-3.5 w-3.5 mr-1 animate-spin"}),"Save"]})]})})]}),e.jsx(rs,{open:c,onOpenChange:k,children:e.jsxs(ns,{children:[e.jsxs(is,{children:[e.jsx(os,{children:"Clear the GoHighLevel flag?"}),e.jsx(ds,{children:"This removes the recorded confirmation (who, when, notes) and logs the change in the case audit trail."})]}),e.jsxs(cs,{children:[e.jsx(ls,{disabled:p,children:"Cancel"}),e.jsx(ms,{disabled:p,onClick:O=>{O.preventDefault(),f(!1)},children:"Clear flag"})]})]})})]})}function ar(s){return s?[s.line1,s.line2,[s.city,s.region,s.postal_code].filter(
6Boolean).join(", "),s.country].filter(Boolean).join(" · "):""}function Ct({row:s,onSaved:n,disabled:r}){const[o,h]=a.useState(!1),[l,p]=a.useState(!1),[b,c]=a.useState(s.top_up_invoice_billing_address??{}),k=ar(s.top_up_invoice_billing_address),i=async()=>{p(!0);try{const{data:f,error:O}=await j.functions.invoke("program-swap-create-topup-link",{body:{case_id:s.id,update_billing_address:b}});if(O)throw new Error(O.message);if(f&&f.ok===!1)throw new Error(f.error??"Save failed");d.success("Invoice billing address saved"),h(!1),n()}catch(f){d.error(`Save address: ${(f==null?void 0:f.message)??"failed"}`)}finally{p(!1)}};return e.jsx("div",{className:"rounded-md border border-border/60 bg-muted/30 p-2 text-xs",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(qa,{className:"h-3.5 w-3.5 mt-0.5 text-muted-foreground shrink-0"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-[10px] uppercase tracking-wide text-muted-foreground font-semibold",children:"Invoice billing address"}),e.jsx("div",{className:"mt-0.5 break-words",children:k||e.jsx("span",{className:"text-muted-foreground italic",children:"No address on file — the invoice will show name + email only."})})]}),e.jsxs(Dt,{open:o,onOpenChange:h,children:[e.jsx(Et,{asChild:!0,children:e.jsxs(S,{variant:"ghost",size:"sm",className:"h-6 px-2 text-xs",disabled:r,onClick:()=>c(s.top_up_invoice_billing_address??{}),children:[e.jsx(Oa,{className:"h-3 w-3 mr-1"}),k?"Edit":"Add"]})}),e.jsxs(qt,{className:"w-80 space-y-2",align:"end",children:[e.jsx("div",{className:"text-xs font-medium",children:"Billing address (Stripe invoice bill-to)"}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("div",{children:[e.jsx(M,{className:"text-[10px]",children:"Line 1"}),e.jsx(ee,{value:b.line1??"",onChange:f=>c({...b,line1:f.target.value}),className:"h-8 text-xs"})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-[10px]",children:"Line 2"}),e.jsx(ee,{value:b.line2??"",onChange:f=>c({...b,line2:f.target.value}),className:"h-8 text-xs"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-1.5",children:[e.jsxs("div",{children:[e.jsx(M,{className:"text-[10px]",children:"City"}),e.jsx(ee,{value:b.city??"",onChange:f=>c({...b,city:f.target.value}),className:"h-8 text-xs"})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-[10px]",children:"Region / State"}),e.jsx(ee,{value:b.region??"",onChange:f=>c({...b,region:f.target.value}),className:"h-8 text-xs"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-1.5",children:[e.jsxs("div",{children:[e.jsx(M,{className:"text-[10px]",children:"Postal code"}),e.jsx(ee,{value:b.postal_code??"",onChange:f=>c({...b,postal_code:f.target.value}),className:"h-8 text-xs"})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-[10px]",children:"Country (ISO)"}),e.jsx(ee,{value:b.country??"",onChange:f=>c({...b,country:f.target.value}),placeholder:"US",className:"h-8 text-xs"})]})]})]}),e.jsxs("div",{className:"flex justify-end gap-1.5 pt-1",children:[e.jsx(S,{size:"sm",variant:"ghost",className:"h-7 text-xs",onClick:()=>h(!1),disabled:l,children:"Cancel"}),e.jsxs(S,{size:"sm",className:"h-7 text-xs",onClick:i,disabled:l,children:[l&&e.jsx(Y,{className:"h-3 w-3 mr-1 animate-spin"}),"Save"]})]})]})]})]})})}const rr=["open","acknowledged","escalated"];async function Mt(s){const{data:n,error:r}=await j.from("integrity_anomalies").select("id, code, severity, message, suggested_fix, status, last_seen_at").eq("suite","program_swap").in("status",rr).contains("context",{case_id:s}).order("last_seen_at",{ascending:!1});return r?(console.warn("fetchOpenSwapAnomalies failed",r.message),[]):n??[]}const as=s=>s==null?"—":`$${Number(s).toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}`;function Rt({caseId:s,amountDue:n,disabled:r,onDone:o}){const[h,l]=a.useState(!1),[p,b]=a.useState(!1),[c,k]=a.useState(""),[i,f]=a.useState(""),[O,y]=a.useState(""),[A,T]=a.useState(!1),E=n==null?null:Number(n),_=O.trim()===""?null:Number(O),g=_!=null&&(!Number.isFinite(_)||_<=0),F=_??E,q=F!=null&&E!=null&&Math.abs(E-F)>.01,J=()=>{k(""),f(""),y(""),T(!1)},w=async()=>
6{if(c.trim().length<10){d.error("A reason of at least 10 characters is required.");return}if(!i.trim()){d.error("A payment reference is required.");return}if(g){d.error("Amount must be a positive number.");return}if(q&&!A){d.error("The amount differs from the amount due — tick the override box to record it.");return}b(!0);try{const{data:$,error:pe}=await j.rpc("swap_mark_top_up_paid_manually",{p_case_id:s,p_reason:c.trim(),p_reference:i.trim(),p_amount:_,p_paid_at:new Date().toISOString(),p_allow_amount_mismatch:A});if(pe)throw new Error(pe.message);const I=$??{};(await Mt(s)).length>0?d.warning(`Payment of ${as(Number(I.amount))} recorded — but the commission adjustment rows did not create. See the warning on the case.`,{duration:1e4}):I.status_advanced===!1?d.warning(`Payment of ${as(Number(I.amount))} recorded, but the case did not advance to Product Swapped (credit note or access revocation still outstanding). No adjustment rows yet.`,{duration:1e4}):d.success(`Top-up of ${as(Number(I.amount))} recorded as paid.`);try{await j.functions.invoke("program-swap-create-topup-link",{body:{case_id:s,notify_paid_team_alert:!0}})}catch(U){console.warn("top_up_paid team alert dispatch failed (non-blocking)",U)}l(!1),J(),o()}catch($){d.error(($==null?void 0:$.message)??"Could not record the payment")}finally{b(!1)}};return e.jsxs(e.Fragment,{children:[e.jsxs(S,{size:"sm",variant:"outline",disabled:r,onClick:()=>l(!0),children:[e.jsx(Ae,{className:"h-3.5 w-3.5 mr-1"})," Mark top-up paid"]}),e.jsx(Ie,{open:h,onOpenChange:$=>{p||(l($),$||J())},children:e.jsxs(Fe,{className:"max-w-lg",children:[e.jsxs(Le,{children:[e.jsx(Me,{children:"Record a manual top-up payment"}),e.jsx(Ve,{children:"Only for money confirmed collected OUTSIDE Stripe (bank transfer, cheque) or where a Stripe webhook failed. This moves the case to Product Swapped, allows speaker access to be granted, and writes the commission adjustment rows. It cannot be auto-reversed."})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"text-sm",children:["Amount due: ",e.jsx("span",{className:"font-medium",children:as(E)})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs(M,{htmlFor:"topup-reference",children:["Payment reference ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx(ee,{id:"topup-reference",value:i,onChange:$=>f($.target.value),placeholder:"Bank reference, cheque number or Stripe charge id"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Bank reference, cheque number or Stripe charge id — this is the evidence the payment actually happened."})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(M,{htmlFor:"topup-amount",children:"Amount collected"}),e.jsx(ee,{id:"topup-amount",inputMode:"decimal",value:O,onChange:$=>y($.target.value),placeholder:E!=null?E.toFixed(2):"0.00"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Leave blank to record the full amount due. This exact figure is what gets booked to the commission ledger."})]}),q&&e.jsxs("div",{className:"rounded-md border border-amber-300 bg-amber-50 dark:border-amber-800 dark:bg-amber-950/40 p-2.5 space-y-2",children:[e.jsxs("div",{className:"flex items-start gap-2 text-xs text-amber-900 dark:text-amber-100",children:[e.jsx(qe,{className:"h-4 w-4 shrink-0 mt-0.5"}),e.jsxs("span",{children:["You are recording ",as(F)," against an amount due of ",as(E),". The difference of ",as(Math.abs((E??0)-(F??0)))," will remain uncollected, and the speaker commission base will be calculated on the lower figure."]})]}),e.jsxs("label",{className:"flex items-start gap-2 text-xs text-amber-900 dark:text-amber-100",children:[e.jsx(Ds,{checked:A,onCheckedChange:$=>T($===!0),className:"mt-0.5"}),e.jsx("span",{children:"I confirm the short/over payment above is correct and intended."})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs(M,{htmlFor:"topup-reason",children:["Reason ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx(Ze,{id:"topup-reason",value:c,onChange:$=>k($.target.value),rows:3,placeholder:"e.g. Bank transfer received 08/08/2026, confirmed against the FNB statement by finance."}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Minimum 10 characters. Stored on the audit trail."})]})]}),e.jsxs(fs,{children:[e.jsx(S,{variant:"outline",onClick:()=>l(!1),disabled:p,children:"Cancel"}),e.jsxs(S,{onClick:w,disabled:p,children:[p&&e.jsx(Y,{className:"h-3.5 w-3.5 mr-1 animate-spin"}),"Record payment"]})]})]})})]})}function At({caseId:s,refreshKey:n=0}
6){const[r,o]=a.useState([]);return a.useEffect(()=>{let h=!1;return(async()=>{const l=await Mt(s);h||o(l)})(),()=>{h=!0}},[s,n]),r.length===0?null:e.jsxs("div",{className:"rounded-md border border-amber-300 bg-amber-50 dark:border-amber-800 dark:bg-amber-950/40 p-2 space-y-1.5",children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-xs font-medium text-amber-900 dark:text-amber-100",children:[e.jsx(qe,{className:"h-3.5 w-3.5"}),"Bookkeeping incomplete — commission adjustment rows were not created"]}),r.map(h=>e.jsxs("div",{className:"text-xs text-amber-800 dark:text-amber-200",children:[e.jsx("span",{className:"font-mono text-[10px] mr-1.5 px-1 py-0.5 rounded bg-amber-100 dark:bg-amber-900",children:h.code}),h.message,h.suggested_fix&&e.jsx("div",{className:"text-[11px] opacity-80 mt-0.5",children:h.suggested_fix})]},h.id)),e.jsx("div",{className:"text-[11px] text-amber-800/80 dark:text-amber-200/80",children:"The payment itself is recorded. Finance must resolve the gap above before the speaker commission for this swap is correct."})]})}const Ke=s=>new Intl.NumberFormat("en-US",{style:"currency",currency:"USD"}).format(Number(s??0));function Tt({caseId:s,label:n,disabled:r,onSent:o}){const[h,l]=a.useState(!1),[p,b]=a.useState(!1),[c,k]=a.useState(!1),[i,f]=a.useState(null),O=async()=>{b(!0),f(null);try{const{data:g,error:F}=await j.functions.invoke("program-swap-create-topup-link",{body:{case_id:s,preview:!0}});if(F)throw new Error(await Xe(F));if(!g||g.ok===!1)throw new Error((g==null?void 0:g.error)??"Preview failed");f(g)}catch(g){d.error(`Prepare invoice: ${(g==null?void 0:g.message)??"failed"}`),l(!1)}finally{b(!1)}},y=g=>{l(g),g&&O()},A=async()=>{k(!0);try{const{data:g,error:F}=await j.functions.invoke("program-swap-create-topup-link",{body:{case_id:s}});if(F)throw new Error(await Xe(F));if(!g||g.ok===!1)throw new Error((g==null?void 0:g.error)??"Send failed");d.success(`Invoice ${g.invoice_number??""} created & emailed`),l(!1),o()}catch(g){d.error(`Approve & send: ${(g==null?void 0:g.message)??"failed"}`),O()}finally{k(!1)}},T=i==null?void 0:i.money,E=!!(T!=null&&T.mismatch),_=i==null?void 0:i.billing_address;return e.jsxs(Ie,{open:h,onOpenChange:y,children:[e.jsxs(S,{size:"sm",disabled:r,onClick:()=>y(!0),children:[e.jsx(_a,{className:"h-3.5 w-3.5 mr-1"}),n]}),e.jsxs(Fe,{className:"max-w-2xl max-h-[85vh] overflow-y-auto",children:[e.jsxs(Le,{children:[e.jsx(Me,{children:"Prepare top-up invoice"}),e.jsx(Ve,{children:"Read-only preview built from a fresh server read of this case. Nothing is created in Stripe until you approve."})]}),p&&e.jsxs("div",{className:"py-10 flex items-center justify-center text-sm text-muted-foreground",children:[e.jsx(Y,{className:"h-4 w-4 mr-2 animate-spin"})," Loading preview…"]}),!p&&i&&T&&e.jsxs("div",{className:"space-y-5 text-sm",children:[E&&e.jsxs("div",{className:"rounded-md border border-destructive/50 bg-destructive/10 p-3 space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2 font-semibold text-destructive",children:[e.jsx(qe,{className:"h-4 w-4"})," Amounts disagree — do not send"]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 font-mono text-xs",children:[e.jsx("div",{children:"Stored on the case (would be billed)"}),e.jsx("div",{className:"text-right font-semibold",children:Ke(T.stored_amount_due)}),e.jsx("div",{children:"Products and credits come to"}),e.jsx("div",{className:"text-right font-semibold",children:Ke(T.recomputed_amount_due)})]}),e.jsxs("p",{className:"text-xs text-destructive",children:["This case's stored top-up (",Ke(T.stored_amount_due),") does not match what its products and credits come to (",Ke(T.recomputed_amount_due),"). Do not send. Re-save the replacement item to recalculate, or raise it."]})]}),e.jsxs("section",{className:"space-y-2",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"The money"}),e.jsxs("div",{className:"rounded-md border p-3 font-mono text-xs space-y-1",children:[T.items.length===0&&e.jsx("div",{className:"text-muted-foreground",children:"No replacement items on this case."}),T.items.map((g,F)=>e.jsxs("div",{className:"flex justify-between gap-4",children:[e.jsx("span",{className:"truncate",children:g.name}),e.jsx("span",{children:Ke(g.price)})]},F)),e.jsxs("div",{className:"flex justify-between gap-4 text-muted-foreground",children:[e.jsx("span",{children:"Credit note"}),e.jsxs("span",{children:["-",Ke(T.credit_note_amount)]})]}),e.jsxs("div",{className:"flex justify-between gap-4 text-muted-foreground",children:[e.jsx("span",{children:"Prior credit applied"}),e.jsxs("span",{children:["-",Ke(T.prior_credit_applied)]})]}),e.jsxs("div",{className:"border-t pt-1 mt-1 flex justify-between gap-4 font-semibold",children:[e.jsx("span",{children:"Amount due"}),e.jsx("span",{children:Ke(T.stored_amount_due)})]})]})]}),e.jsxs("section",{className:"space-y-1",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"Where it goes"}),e.jsxs("div",{className:"rounded-md border p-3 space-y-1 text-xs",children:[e.jsxs("div",{children:["To: ",e.jsx("span",{className:"font-medium",children:i.customer_email??"—"}),i.customer_name?` (${i.customer_name})`:""]}),e.jsxs("div",{children:["Cc: ",(i.cc_emails??[]).join(", ")||"—"]}
6),e.jsxs("div",{children:["Bill to:"," ",_?[_.line1,_.line2,_.city,_.region,_.postal_code,_.country].filter(Boolean).join(", "):e.jsx("span",{className:"text-muted-foreground",children:i.billing_address_note})]})]})]}),e.jsxs("section",{className:"space-y-1",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"The paperwork"}),e.jsxs("div",{className:"rounded-md border p-3 space-y-1 text-xs",children:[e.jsxs("div",{children:["Memo: ",i.paperwork.memo]}),e.jsxs("div",{children:["Payment terms: due in ",i.paperwork.days_until_due," days"]}),e.jsx("div",{className:"text-muted-foreground",children:i.paperwork.invoice_number_note})]})]}),i.open_invoice&&e.jsxs("div",{className:"rounded-md border border-amber-300 bg-amber-50 dark:border-amber-800 dark:bg-amber-950/40 p-3 text-xs text-amber-800 dark:text-amber-200",children:["Sending will void ",i.open_invoice.invoice_number??"the existing invoice"," and issue a replacement."]}),e.jsxs("section",{className:"space-y-1",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"The email"}),e.jsxs("div",{className:"rounded-md border p-3 space-y-3 text-xs",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Subject: "}),i.email.subject]}),e.jsxs("div",{className:"rounded-md bg-muted p-3 space-y-2",children:[e.jsx("div",{className:"text-[10px] font-semibold uppercase tracking-widest text-primary",children:i.email.eyebrow}),e.jsx("div",{className:"text-sm font-semibold",children:i.email.heading}),e.jsx("p",{children:i.email.greeting}),e.jsx("p",{children:i.email.intro}),i.email.items.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"text-[10px] uppercase tracking-wide text-muted-foreground",children:i.email.items_label}),e.jsx("ul",{className:"list-disc pl-4",children:i.email.items.map((g,F)=>e.jsxs("li",{children:[g.name," — ",g.price_formatted]},F))})]}),e.jsxs("div",{className:"text-center py-2",children:[e.jsx("div",{className:"text-[10px] uppercase tracking-wide text-muted-foreground",children:i.email.amount_label}),e.jsx("div",{className:"text-lg font-bold text-primary",children:i.email.amount_formatted})]}),e.jsxs("div",{className:"text-center",children:[e.jsx("span",{className:"inline-block rounded-md bg-primary px-3 py-1.5 text-primary-foreground font-semibold",children:i.email.cta_label}),e.jsx("div",{className:"text-muted-foreground mt-1",children:i.email.hosted_url})]}),e.jsx("p",{children:i.email.invoice_note}),e.jsx("p",{className:"whitespace-pre-line",children:i.email.signoff})]})]})]})]}),e.jsxs(fs,{children:[e.jsx(S,{variant:"outline",onClick:()=>l(!1),disabled:c,children:"Cancel"}),e.jsxs(S,{onClick:A,disabled:p||c||E||!i,children:[c?e.jsx(Y,{className:"h-3.5 w-3.5 mr-1 animate-spin"}):e.jsx(ga,{className:"h-3.5 w-3.5 mr-1"}),"Approve & send ",T?`— ${Ke(T.stored_amount_due)}`:""]})]})]})]})}const nr={credit_issued:"Credit issued",redeemed_against_case:"Credit used on a swap",coupon_issued:"Coupon issued",coupon_voided_reinstated:"Coupon voided — credit put back",swap_reversed:"Credit returned: swap reversed",manual_adjustment:"Manual adjustment",historic_activity_pre_ledger:"Earlier activity (before history was kept)"};function $t(s,n="USD"){if(s==null)return"—";try{return new Intl.NumberFormat("en-US",{style:"currency",currency:n}).format(Number(s))}catch{return`$${Number(s).toFixed(2)}`}}function ir({email:s,customerName:n,currency:r="USD",onClose:o}){const[h,l]=a.useState([]),[p,b]=a.useState(!0),[c,k]=a.useState(null);return a.useEffect(()=>{let i=!1;return(async()=>{b(!0);const{data:f,error:O}=await j.from("credit_ledger").select("id, entry_type, amount_delta, balance_after, related_case_id, notes, created_at").ilike("customer_email",s).order("created_at",{ascending:!1}).limit(200);i||(O?(k(O.message),l([])):l(f??[]),b(!1))})(),()=>{i=!0}},[s]),e.jsx(ja,{open:!0,onOpenChange:i=>{i||o()},children:e.jsxs(ba,{side:"right",className:"w-full sm:max-w-xl overflow-y-auto",children:[e.jsxs(va,{children:[e.jsx(Na,{children:"Credit history"}),e.jsxs(ya,{children:[n?`${n} — `:"",s]})]}),e.jsx("div",{className:"mt-4",children:p?e.jsxs("div",{className:"py-12 text-center text-muted-foreground text-sm",children:[e.jsx(Y,{className:"h-4 w-4 animate-spin inline mr-2"})," Loading history…"]}):c?e.jsxs("div",{className:"text-sm text-destructive",children:["Error loading history: ",c]}):h.length===0?e.jsx("div",{className:"py-12 text-center text-sm text-muted-foreground",children:"No credit history for this customer."}):e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/40 text-xs uppercase tracking-wide text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left p-2",children:"Date"}),e.jsx("th",{className:"text-left p-2",children:"What happened"}),e.jsx("th",{className:"text-right p-2",children:"Amount"}),e.jsx("th",{className:"text-right p-2",children:"Balance after"}),e.jsx("th",{className:"p-2"})]})}),e.jsx("tbody",{children:h.map(i=>e.jsxs("tr",{className:"border-t border-border align-top",children:[e.jsx("td",{className:"p-2 text-xs whitespace-nowrap",children:Je(i.created_at)}),e.jsxs("td",{className:"p-2 text-xs",children:[e.jsx("div",{children:nr[i.entry_type]??i.entry_type}),i.notes&&e.jsx("div",{className:"text-muted-foreground",children:i.notes})]}),e.jsxs("td",{className:`p-2 text-right tabular-nums text-xs ${Number(i.amount_delta??0)<0?"text-destructive":"text-emerald-600"}`,children:[Number(i.amount_delta??0)>0?"+":"",$t(i.amount_delta,r)]}),e.jsx("td",{className:"p-2 text-right tabular-nums text-xs",children:$t(i.balance_after,r)}),e.jsx("td",{className:"p-2 text-right",children:i.related_case_id&&e.jsxs($s,{to:`/admin/program-swap?case=${i.related_case_id}`,className:"inline-flex items-center gap-1 text-primary hover:underline text-xs",children:["case ",e.jsx(Ns,{className:"h-3 w-3"})]})})]},i.id))})]})})]})})}function Ut(s){return s.includes("admin")||s.includes("management")}const at={issue:"Only Sally or Martin can record a coupon — send them the code, amount and platform",markUsed:"Only Sally or Martin can do this — ask them to mark the code used",void:"Only Sally or Martin can void a code"},or="Only Sally or Martin can do this. Send them the customer email, code, platform and amount.";function nt(s){const n=s??"Something went wrong.";return n.includes("Not authorised")?or:n}function As(s,n="USD"){if(s==null)return"—";try{return new Intl.NumberFormat("en-US",{style:"currency",currency:n}).format(Number(s))}catch{return`$${Number(s).toFixed(2)}`}}function dr(s){const n=(s??"").toLowerCase();return n==="active"?e.jsx(Se,{className:"bg-emerald-600 hover:bg-emerald-600 text-white",children:"active"}):n==="expired"?e.jsx(Se,{className:"bg-red-600 hover:bg-red-600 text-white",children:"EXPIRED"}):n.includes("fully reserved")?e.jsx(Se,{className:"bg-amber-500 hover:bg-amber-500 text-white whitespace-normal h-auto text-center leading-tight py-1",children:s}):n==="used up"?e.jsx(Se,{variant:"secondary",children:"used up"}):e.jsx(Se,{variant:"outline",children:s??"—"})}function cr({onChanged:s}){const{roles:n}
6=Ot(),r=Ut(n),[o,h]=a.useState([]),[l,p]=a.useState(!0),[b,c]=a.useState(null),[k,i]=a.useState(""),[f,O]=a.useState(null),[y,A]=a.useState(null),T=async()=>{p(!0),c(null);const{data:_,error:g}=await j.from("vw_customer_credit_lookup").select("*").order("credit_created_at",{ascending:!1}).limit(1e3);g?(c(g.message),h([])):h(_??[]),p(!1)};a.useEffect(()=>{T()},[]);const E=a.useMemo(()=>{const _=k.trim().toLowerCase();return _?o.filter(g=>[g.customer_name,g.credit_email,g.other_known_emails].filter(Boolean).some(F=>String(F).toLowerCase().includes(_))):o},[o,k]);return e.jsxs("div",{className:"space-y-3",children:[e.jsx(je,{children:e.jsxs(be,{className:"p-3 flex flex-wrap items-center gap-2",children:[e.jsx(ee,{placeholder:"Search by name or any known email…",value:k,onChange:_=>i(_.target.value),className:"max-w-md"}),e.jsxs("div",{className:"text-xs text-muted-foreground ml-auto",children:[E.length," of ",o.length]})]})}),e.jsx(je,{children:e.jsx(be,{className:"p-0 overflow-x-auto",children:l?e.jsxs("div",{className:"p-12 text-center text-muted-foreground",children:[e.jsx(Y,{className:"h-5 w-5 animate-spin inline mr-2"})," Loading balances…"]}):b?e.jsxs("div",{className:"p-6 text-sm text-destructive",children:["Error loading credit balances: ",b]}):E.length===0?e.jsx("div",{className:"p-12 text-center text-sm text-muted-foreground",children:"No customers with credit match this search."}):e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/40 text-xs uppercase tracking-wide text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left p-3",children:"Customer"}),e.jsx("th",{className:"text-left p-3",children:"Credit email"}),e.jsx("th",{className:"text-left p-3",children:"Other known emails"}),e.jsx("th",{className:"text-right p-3",children:"Available"}),e.jsx("th",{className:"text-left p-3",children:"Status"}),e.jsx("th",{className:"text-left p-3",children:"Expires"}),e.jsx("th",{className:"text-right p-3",children:"Open coupons"}),e.jsx("th",{className:"text-left p-3",children:"Coupon history"}),e.jsx("th",{className:"text-left p-3",children:"Case"}),e.jsx("th",{className:"p-3 w-px"})]})}),e.jsx("tbody",{children:E.map((_,g)=>{const F=_.days_until_expiry!=null&&_.days_until_expiry<30&&_.days_until_expiry>=0,q=!_.credit_email||(_.available_credit??0)<=0||(_.credit_status??"").toLowerCase()==="expired";return e.jsxs("tr",{className:"border-t border-border hover:bg-muted/30",children:[e.jsx("td",{className:"p-3",children:e.jsx("div",{className:"font-medium",children:_.customer_name??"—"})}),e.jsx("td",{className:"p-3 text-xs",children:_.credit_email??"—"}),e.jsx("td",{className:"p-3 text-xs text-muted-foreground max-w-[220px] truncate",title:_.other_known_emails??"",children:_.other_known_emails??"—"}),e.jsx("td",{className:"p-3 text-right tabular-nums font-medium",children:As(_.available_credit,_.currency??"USD")}),e.jsx("td",{className:"p-3",children:dr(_.credit_status)}),e.jsx("td",{className:"p-3 text-xs",children:_.credit_expires_at?e.jsxs(e.Fragment,{children:[e.jsx("div",{children:Je(_.credit_expires_at)}),_.days_until_expiry!=null&&e.jsx("div",{className:F?"text-red-600 font-medium":"text-muted-foreground",children:_.days_until_expiry<0?`expired ${Math.abs(_.days_until_expiry)}d ago`:`${_.days_until_expiry}d left`})]}):"—"}),e.jsx("td",{className:"p-3 text-right tabular-nums",children:_.open_coupons??0}),e.jsx("td",{className:"p-3 text-xs text-muted-foreground max-w-[240px] truncate",title:_.coupon_history??"",children:_.coupon_history??"—"}),e.jsx("td",{className:"p-3 text-xs",children:_.source_case_id?e.jsxs($s,{to:`/admin/program-swap?case=${_.source_case_id}`,className:"inline-flex items-center gap-1 text-primary hover:underline",children:["open ",e.jsx(Ns,{className:"h-3 w-3"})]}):"—"}),e.jsxs("td",{className:"p-3 text-right whitespace-nowrap space-x-1",children:[e.jsxs(S,{size:"sm",variant:"ghost",disabled:!_.credit_email,title:"Every credit change for this customer",onClick:()=>A(_),children:[e.jsx(La,{className:"h-3.5 w-3.5 mr-1"})," History"]}),e.jsxs(S,{size:"sm",variant:"outline",disabled:q||!r,title:r?"Records a coupon you have already created in SamCart or Kajabi, and deducts the credit":at.issue,onClick:()=>O(_),children:[e.jsx(wa,{className:"h-3.5 w-3.5 mr-1"})," Coupon"]})]})]},`${_.credit_email}-${g}`)})})]})})}),e.jsx("p",{className:"text-xs text-muted-foreground px-1",children:"Recording a coupon deducts the customer's credit immediately. Codes must be created manually in SamCart or Kajabi — usage is then detected automatically each night, and unused codes are auto-voided and the credit reinstated."}),f&&e.jsx(lr,{row:f,onClose:()=>O(null),onSuccess:()=>{T(),s==null||s()}}),(y==null?void 0:y.credit_email)&&e.jsx(ir,{email:y.credit_email,customerName:y.customer_name,currency:y.currency??"USD",onClose:()=>A(null)})]})}function lr({row:s,onClose:n,onSuccess:r}){const o=Number(s.available_credit??0),[h,l]=a.useState(""),[p,b]=a.useState("samcart"),[c,k]=a.useState(o.toFixed(2)),[i,f]=a.useState("30"),[O,y]=a.useState(""),[A,T]=a.useState(!1),[E,_]=a.useState(!1),g=a.useMemo(()=>{const q=Number(i);if(!Number.isFinite(q)||q<=0)return"the auto-void date";const J=new Date;return J.setDate(J.getDate()+Math.round(q)),Je(J.toISOString())},[i]),F=async()=>{var Z;const q=h.trim().toUpperCase(),J=Number(c),w=Number(i);if(!q){d.error("Coupon code is required");return}if(!(J>0)){d.error("Amount must be greater than zero");return}if(J>o){d.error(`Amount cannot exceed available credit (${As(o,s.currency??"USD")})`);return}if(!s.credit_email){d.error("This row has no credit email");return}T(!0);const{data:$}=await j.auth.getUser(),pe=((Z=$.user)==null?void 0:Z.email)??void 0,{data:I,error:K}=await j.rpc("credit_coupon_issue",{p_customer_email:s.credit_email,p_coupon_code:q,p_platform:p,p_amount:J,p_
6issued_by_email:pe,p_currency:s.currency??"USD",p_valid_days:w,p_notes:O.trim()||void 0});if(T(!1),K){d.error(nt(K.message));return}const U=I??{},_e=U.currency??s.currency??"USD",xe=[];U.deducted!=null&&xe.push(`${As(Number(U.deducted),_e)} deducted`),U.available_after!=null&&xe.push(`${As(Number(U.available_after),_e)} credit left`),U.auto_void_after&&xe.push(`auto-voids ${new Date(U.auto_void_after).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"})}`);const Ne=U.coupon_code??q;d.success(xe.length?`Coupon ${Ne} recorded — ${xe.join(", ")}`:"Coupon recorded"),r(),n()};return e.jsx(Ie,{open:!0,onOpenChange:q=>{!q&&!A&&(_(!1),n())},children:e.jsxs(Fe,{className:"max-w-md",children:[e.jsxs(Le,{children:[e.jsx(Me,{children:"Record a coupon you have already created"}),e.jsxs(Ve,{children:["For ",s.customer_name??s.credit_email,". Available:"," ",e.jsx("span",{className:"font-medium",children:As(o,s.currency??"USD")})]})]}),e.jsxs("div",{className:"rounded-md border border-amber-500/40 bg-amber-500/10 p-2 text-xs text-amber-900 dark:text-amber-200",children:[e.jsx("strong",{children:"This form does not create the coupon."})," Create the code in SamCart or Kajabi yourself first, then record it here so the customer's credit is deducted and the code is tracked."]}),e.jsxs("div",{className:"rounded-md border border-border bg-muted/40 p-2 text-[11px] leading-snug text-muted-foreground",children:[e.jsx("strong",{className:"text-foreground",children:"If access was granted by hand instead of the customer going through checkout"}),", come straight back to the Coupon register and press ",e.jsx("strong",{children:"Mark used"}),". Otherwise this code auto-voids on ",g," and the credit goes back to the customer."]}),e.jsxs("div",{className:"flex items-start gap-2 px-1",children:[e.jsx(Ds,{id:"coupon-confirm-created",checked:E,onCheckedChange:q=>_(q===!0)}),e.jsx(M,{htmlFor:"coupon-confirm-created",className:"text-xs font-normal leading-snug",children:"I have already created this exact code in SamCart/Kajabi"})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Coupon code *"}),e.jsx(ee,{value:h,onChange:q=>l(q.target.value.toUpperCase()),placeholder:"E.G. SWAP-JANE-100",className:"uppercase"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Platform *"}),e.jsxs(us,{value:p,onValueChange:q=>b(q),children:[e.jsx(ps,{children:e.jsx(xs,{})}),e.jsxs(hs,{children:[e.jsx(ve,{value:"samcart",children:"SamCart"}),e.jsx(ve,{value:"kajabi",children:"Kajabi"})]})]})]}),e.jsxs("div",{children:[e.jsxs(M,{className:"text-xs",children:["Amount (",s.currency??"USD",") *"]}),e.jsx(ee,{type:"number",min:"0.01",max:o,step:"0.01",value:c,onChange:q=>k(q.target.value)})]})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Valid days before auto-void"}),e.jsx(ee,{type:"number",min:"1",step:"1",value:i,onChange:q=>f(q.target.value)})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Notes (optional)"}),e.jsx(Ze,{value:O,onChange:q=>y(q.target.value),rows:2})]})]}),e.jsxs(fs,{children:[e.jsx(S,{variant:"ghost",onClick:()=>{_(!1),n()},disabled:A,children:"Cancel"}),e.jsxs(S,{onClick:F,disabled:A||!E,children:[A&&e.jsx(Y,{className:"h-4 w-4 mr-2 animate-spin"}),"Record coupon"]})]})]})})}function Ht(s,n="USD"){if(s==null)return"—";try{return new Intl.NumberFormat("en-US",{style:"currency",currency:n}).format(Number(s))}catch{return`$${Number(s).toFixed(2)}`}}function mr(s){const n=(s??"").toLowerCase();return n==="issued"?e.jsx(Se,{className:"bg-blue-600 hover:bg-blue-600 text-white",children:"issued"}):n==="redeemed"?e.jsx(Se,{className:"bg-emerald-600 hover:bg-emerald-600 text-white",children:"redeemed"}):n==="voided"?e.jsx(Se,{variant:"secondary",children:"voided"}):e.jsx(Se,{variant:"outline",children:s??"—"})}function ur({onChanged:s}){const{roles:n}
6=Ot(),r=Ut(n),[o,h]=a.useState([]),[l,p]=a.useState(!0),[b,c]=a.useState(null),[k,i]=a.useState("all"),[f,O]=a.useState("all"),[y,A]=a.useState(""),[T,E]=a.useState(null),[_,g]=a.useState(null),F=async()=>{p(!0),c(null);const{data:w,error:$}=await j.from("vw_credit_coupon_register").select("*").order("issued_at",{ascending:!1}).limit(1e3);$?(c($.message),h([])):h(w??[]),p(!1)};a.useEffect(()=>{F()},[]);const q=a.useMemo(()=>{const w=y.trim().toLowerCase();return o.filter($=>k!=="all"&&($.status??"").toLowerCase()!==k||f!=="all"&&($.platform??"").toLowerCase()!==f?!1:w?[$.coupon_code,$.customer_email,$.customer_name].filter(Boolean).some(pe=>String(pe).toLowerCase().includes(w)):!0)},[o,k,f,y]),J=()=>{F(),s==null||s()};return e.jsxs("div",{className:"space-y-3",children:[e.jsx(je,{children:e.jsxs(be,{className:"p-3 flex flex-wrap items-center gap-2",children:[e.jsx(ee,{placeholder:"Search coupon, name, email…",value:y,onChange:w=>A(w.target.value),className:"max-w-sm"}),e.jsxs(us,{value:k,onValueChange:i,children:[e.jsx(ps,{className:"w-[160px]",children:e.jsx(xs,{})}),e.jsxs(hs,{children:[e.jsx(ve,{value:"all",children:"All statuses"}),e.jsx(ve,{value:"issued",children:"Issued"}),e.jsx(ve,{value:"redeemed",children:"Redeemed"}),e.jsx(ve,{value:"voided",children:"Voided"})]})]}),e.jsxs(us,{value:f,onValueChange:O,children:[e.jsx(ps,{className:"w-[160px]",children:e.jsx(xs,{})}),e.jsxs(hs,{children:[e.jsx(ve,{value:"all",children:"All platforms"}),e.jsx(ve,{value:"samcart",children:"SamCart"}),e.jsx(ve,{value:"kajabi",children:"Kajabi"})]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground ml-auto",children:[q.length," of ",o.length]})]})}),e.jsx(je,{children:e.jsx(be,{className:"p-0 overflow-x-auto",children:l?e.jsxs("div",{className:"p-12 text-center text-muted-foreground",children:[e.jsx(Y,{className:"h-5 w-5 animate-spin inline mr-2"})," Loading coupons…"]}):b?e.jsxs("div",{className:"p-6 text-sm text-destructive",children:["Error loading coupons: ",b]}):q.length===0?e.jsx("div",{className:"p-12 text-center text-sm text-muted-foreground",children:"No coupons match these filters."}):e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/40 text-xs uppercase tracking-wide text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left p-3",children:"Coupon"}),e.jsx("th",{className:"text-left p-3",children:"Platform"}),e.jsx("th",{className:"text-left p-3",children:"Customer"}),e.jsx("th",{className:"text-right p-3",children:"Amount"}),e.jsx("th",{className:"text-left p-3",children:"Status"}),e.jsx("th",{className:"text-left p-3",children:"Issued"}),e.jsx("th",{className:"text-left p-3",children:"Auto-void"}),e.jsx("th",{className:"text-left p-3",children:"Redeemed"}),e.jsx("th",{className:"text-left p-3",children:"Voided"}),e.jsx("th",{className:"p-3"})]})}),e.jsx("tbody",{children:q.map(w=>e.jsxs("tr",{className:"border-t border-border hover:bg-muted/30 align-top",children:[e.jsxs("td",{className:"p-3",children:[e.jsx("div",{className:"font-mono text-xs font-medium",children:w.coupon_code}),w.sweep_note&&e.jsxs("div",{className:"mt-1 text-[11px] text-amber-700 dark:text-amber-400",children:["⚠ ",w.sweep_note]})]}),e.jsx("td",{className:"p-3 text-xs",children:w.platform??"—"}),e.jsxs("td",{className:"p-3",children:[e.jsx("div",{className:"text-sm",children:w.customer_name??"—"}),e.jsx("div",{className:"text-xs text-muted-foreground",children:w.customer_email??"—"})]}),e.jsx("td",{className:"p-3 text-right tabular-nums",children:Ht(w.amount,w.currency??"USD")}),e.jsx("td",{className:"p-3",children:mr(w.status)}),e.jsxs("td",{className:"p-3 text-xs",children:[e.jsx("div",{children:Je(w.issued_at)}),w.issued_by_email&&e.jsxs("div",{className:"text-muted-foreground",children:["by ",w.issued_by_email]})]}),e.jsx("td",{className:"p-3 text-xs",children:Je(w.auto_void_after)}),e.jsx("td",{className:"p-3 text-xs",children:w.redeemed_at?e.jsxs(e.Fragment,{children:[e.jsx("div",{children:Je(w.redeemed_at)}),w.redeemed_order_ref&&e.jsx("div",{className:"text-muted-foreground font-mono text-[11px]",children:w.redeemed_order_ref}),w.redeemed_detected_by&&e.jsxs("div",{className:"text-muted-foreground",children:["via ",w.redeemed_detected_by]})]}):"—"}),e.jsx("td",{className:"p-3 text-xs",children:w.voided_at?e.jsxs(e.Fragment,{children:[e.jsx("div",{children:Je(w.voided_at)}),w.void_reason&&e.jsx("div",{className:"text-muted-foreground max-w-[180px] truncate",title:w.void_reason,children:w.void_reason})]}):"—"}),e.jsx("td",{className:"p-3 text-right",children:(w.status??"").toLowerCase()==="issued"&&e.jsxs("div",{className:"flex items-center justify-end gap-1",children:[e.jsxs(S,{size:"sm",variant:"outline",disabled:!r,title:r?void 0:at.markUsed,onClick:()=>E(w),children:[e.jsx(Ae,{className:"h-3.5 w-3.5 mr-1"})," Mark used"]}),e.jsxs(S,{size:"sm",variant:"ghost",disabled:!r,title:r?void 0:at.void,onClick:()=>g(w),children:[e.jsx(st,{className:"h-3.5 w-3.5 mr-1"})," Void"]})]})})]},w.coupon_code))})]})})}),e.jsx("p",{className:"text-xs text-muted-foreground px-1",children:"Coupon usage is auto-detected nightly from SamCart and Kajabi data; unused coupons are auto-voided after their window and the credit is reinstated automatically."}),T&&e.jsx(pr,{row:T,onClose:()=>E(null),onSuccess:J}),_&&e.jsx(xr,{row:_,onClose:()=>g(null),onSuccess:J})]})}function pr({row:s,onClose:n,onSuccess:r}
6){const[o,h]=a.useState(""),[l,p]=a.useState(!1),b=async()=>{var i;p(!0);const{data:c}=await j.auth.getUser(),{error:k}=await j.rpc("credit_coupon_mark_redeemed",{p_coupon_code:s.coupon_code,p_order_ref:o.trim()||void 0,p_detected_by:((i=c.user)==null?void 0:i.email)??"manual"});if(p(!1),k){d.error(nt(k.message));return}d.success(`Coupon ${s.coupon_code} marked as redeemed`),r(),n()};return e.jsx(Ie,{open:!0,onOpenChange:c=>!c&&!l&&n(),children:e.jsxs(Fe,{className:"max-w-sm",children:[e.jsxs(Le,{children:[e.jsx(Me,{children:"Mark coupon as used"}),e.jsxs(Ve,{children:[e.jsx("span",{className:"font-mono",children:s.coupon_code})," for ",s.customer_email]})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Order reference (optional)"}),e.jsx(ee,{value:o,onChange:c=>h(c.target.value),placeholder:"e.g. SC-12345"})]}),e.jsxs(fs,{children:[e.jsx(S,{variant:"ghost",onClick:n,disabled:l,children:"Cancel"}),e.jsxs(S,{onClick:b,disabled:l,children:[l&&e.jsx(Y,{className:"h-4 w-4 mr-2 animate-spin"}),"Mark used"]})]})]})})}function xr({row:s,onClose:n,onSuccess:r}
6){const[o,h]=a.useState(""),[l,p]=a.useState(!1),b=async()=>{if(!o.trim()){d.error("Reason is required");return}p(!0);const{error:c}=await j.rpc("credit_coupon_void",{p_coupon_code:s.coupon_code,p_reason:o.trim()});if(p(!1),c){d.error(nt(c.message));return}d.success("Credit reinstated — remember to deactivate the code in SamCart/Kajabi."),r(),n()};return e.jsx(Ie,{open:!0,onOpenChange:c=>!c&&!l&&n(),children:e.jsxs(Fe,{className:"max-w-sm",children:[e.jsxs(Le,{children:[e.jsx(Me,{children:"Void coupon & reinstate credit"}),e.jsxs(Ve,{children:[e.jsx("span",{className:"font-mono",children:s.coupon_code})," — ",Ht(s.amount,s.currency??"USD")]})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Reason *"}),e.jsx(Ze,{value:o,onChange:c=>h(c.target.value),rows:3})]}),e.jsxs(fs,{children:[e.jsx(S,{variant:"ghost",onClick:n,disabled:l,children:"Cancel"}),e.jsxs(S,{variant:"destructive",onClick:b,disabled:l,children:[l&&e.jsx(Y,{className:"h-4 w-4 mr-2 animate-spin"}),"Void & reinstate"]})]})]})})}function Ge(s,n="USD"){if(s==null)return"—";try{return new Intl.NumberFormat("en-US",{style:"currency",currency:n}).format(Number(s))}catch{return`$${Number(s).toFixed(2)}`}}function hr({row:s,onClose:n,onSuccess:r}
6){const[o,h]=a.useState(!0),[l,p]=a.useState(0),[b,c]=a.useState("USD"),[k,i]=a.useState(0),[f,O]=a.useState(!1),[y,A]=a.useState(""),[T,E]=a.useState("keep"),[_,g]=a.useState(!1),[F,q]=a.useState([]),[J,w]=a.useState(!1),[$,pe]=a.useState(!1);a.useEffect(()=>{let se=!1;return(async()=>{var D,we;h(!0);const[ye,P,re,me,oe]=await Promise.all([j.from("customer_credit_balances").select("balance_amount, currency").eq("source_case_id",s.id),j.from("program_swap_cases").select("top_up_amount_collected, top_up_amount_due, top_up_status").eq("id",s.id).maybeSingle(),j.from("program_swap_adjustments").select("id, status, old_speaker_commission_paid, affiliate_commission_paid, currency").eq("program_swap_case_id",s.id),j.from("speaker_ledger_entries").select("id, status").eq("program_swap_case_id",s.id),j.from("program_swap_replacement_items").select("source_platform").eq("case_id",s.id)]);if(se)return;q((oe.data??[]).map(he=>String(he.source_platform??"").toLowerCase()));const v=ye.data??[];p(v.reduce((he,Ue)=>he+Number(Ue.balance_amount??0),0));const L=re.data??[];c(((D=v[0])==null?void 0:D.currency)??((we=L[0])==null?void 0:we.currency)??"USD");const G=P.data;i((G==null?void 0:G.top_up_status)==="paid"?Number((G==null?void 0:G.top_up_amount_collected)??(G==null?void 0:G.top_up_amount_due)??0):Number((G==null?void 0:G.top_up_amount_collected)??0));const ge=L.some(he=>he.status!=="void"&&(he.old_speaker_commission_paid||he.affiliate_commission_paid)),u=(me.data??[]).some(he=>["paid","confirmed"].includes(String(he.status??"")));O(ge||u),h(!1)})(),()=>{se=!0}},[s.id]);const I=a.useMemo(()=>Math.round((Number(s.credit_note_amount??0)+Number(s.prior_credit_applied??0)-l)*100)/100,[s.credit_note_amount,s.prior_credit_applied,l]),K=!s.credit_note_expires_at||new Date(s.credit_note_expires_at).getTime()<=Date.now(),U=F.includes("samcart"),_e=F.some(se=>se!=="samcart"),xe=U&&_e?"I have removed access in Kajabi, and I understand the speaker will be emailed to remove the other access":U?"I understand the speaker will be emailed to remove access":"I have removed access in Kajabi",Ne=async()=>{var oe;w(!0);const{data:se,error:ye}=await j.rpc("reverse_program_swap",{p_case_id:s.id,p_reason:y.trim(),p_expiry_mode:T});if(w(!1),ye){const v=ye,L=[v.message,v.details,v.hint].filter(Boolean).join(" — ");d.error(`Reversal failed: ${L||"Unknown database error"}${v.code?` (${v.code})`:""}`,{duration:2e4});return}const P=se??{},re=P.currency??b,me=[`${Ge(Number(P.credit_returned),re)} credit returned`,`new balance ${Ge(Number(P.new_available_balance),re)}`,`${P.adjustments_voided??0} adjustment row(s) voided`];d.success(`Swap reversed — ${me.join(", ")}`),P.commission_already_paid_warning&&d.warning("Commission was already paid on this swap — finance clawback needed."),Number(P.top_up_collected??0)>0&&d.warning(`${Ge(Number(P.top_up_collected),re)} was paid by card. Refund that in Stripe separately.`),pe(!0);try{const{data:v,error:L}=await j.functions.invoke("program-swap-reverse-notify",{body:{case_id:s.id}});if(L)d.error(`${await Xe(L,"Emails could not be sent")} — use "Resend reversal emails" on the case to try again.`);else if(v!=null&&v.ok)d.success("Emails sent: the speaker was notified and the customer told her credit is back.");else{const G=((v==null?void 0:v.owner_emails)??[]).filter(D=>!D.sent),ge=G.map(D=>D.product_name??"replacement item").join(", "),u=(v==null?void 0:v.customer_error)??((oe=G[0])==null?void 0:oe.error)??(v==null?void 0:v.error)??"Unknown error";d.error(`Some emails did not send${ge?` (${ge})`:""}: ${u} — use "Resend reversal emails" on the case.`,{duration:15e3})}}finally{pe(!1)}r(),n()},Z=!o&&!J&&!$&&y.trim().length>=10&&_&&I>0&&!(T==="keep"&&K);return e.jsx(Ie,{open:!0,onOpenChange:se=>{!se&&!J&&n()},children:e.jsxs(Fe,{className:"max-w-lg",children:[e.jsxs(Le,{children:[e.jsx(Me,{children:"Reverse this program swap?"}),e.jsx(Ve,{children:"The credit spent on the replacement goes back to the customer and the swap's finance rows are voided. The original order is never cancelled or refunded. Emails go out automatically: the speaker for each replacement item is told access has been removed or asked to remove it, and the customer is told her credit is back."})]}),o?e.jsxs("div",{className:"py-8 text-center text-muted-foreground text-sm",children:[e.jsx(Y,{className:"h-4 w-4 animate-spin inline mr-2"})," Checking this case…"]}):e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"rounded-md border border-border bg-muted/40 p-3 text-xs space-y-1",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Customer:"})," ",s.customer_name_display??s.customer_name??"—"," (",s.customer_email??"—",")"]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Original product:"})," ",s.original_product_name??"—"]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Replacement product:"})," ",s.selected_replacement_product_name??"—"]}),e.jsxs("div",{className:"pt-1 border-t border-border mt-1",children:[e.jsx("span",{className:"text-muted-foreground",children:"Credit note:"})," ",Ge(s.credit_note_amount,b),Number(s.prior_credit_applied??0)>0&&e.jsxs(e.Fragment,{children:[" + earlier credit used ",Ge(s.prior_credit_applied,b)]})," − leftover still on the case ",Ge(l,b)]}),e.jsxs("div",{className:"font-medium text-sm",children:["Credit going back: ",Ge(I,b)]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"New available balance:"})," ",Ge(l+I,b)]})]}),I<=0&&e.jsx("div",{className:"rounded-md border border-destructive/40 bg-destructive/10 p-2 text-xs text-destructive",children:"There is no credit to give back on this case."}),f&&e.jsxs("div",{className:"rounded-md border border-amber-500/40 bg-amber-500/10 p-2 text-xs text-amber-900 dark:text-amber-200 flex gap-2",children:[e.jsx(qe,{className:"h-4 w-4 shrink-0 mt-0.5"}),e.jsx("span",{children:"Commission has already been paid on this swap — finance clawback needed."})]}),k>0&&e.jsxs("div",{className:"rounded-md border border-destructive/40 bg-destructive/10 p-2 text-xs text-destructive flex gap-2",children:[e.jsx(qe,{className:"h-4 w-4 shrink-0 mt-0.5"}),e.jsxs("span",{children:["This customer also paid ",Ge(k,b)," by card. Refund that in Stripe separately. This action does not refund it."]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(M,{className:"text-xs",children:"Expiry of the returned credit"}),e.jsxs(us,{value:T,onValueChange:se=>E(se),children:[e.jsx(ps,{children:e.jsx(xs,{})}),e.jsxs(hs,{children:[e.jsxs(ve,{value:"keep",children:["Keep the original date",s.credit_note_expires_at?` (${Je(s.credit_note_expires_at)})`:""]}),e.jsx(ve,{value:"fresh",children:"Start fresh 12 months"})]})]}),T==="keep"&&K&&e.jsx("p",{className:"text-xs text-destructive",children:'The original expiry has already passed. Choose "Start fresh 12 months".'})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(M,{htmlFor:"reverse-reason",className:"text-xs",children:"Reason (required, at least 10 characters)"}),e.jsx(Ze,{id:"reverse-reason",value:y,onChange:se=>A(se.target.value),rows:3,placeholder:"e.g. Customer no longer wants the replacement programme and asked for her credit back",disabled:J})]}),e.jsxs("div",{className:"flex items-start gap-2 px-1",children:[e.jsx(Ds,{id:"reverse-access-confirmed",checked:_,onCheckedChange:se=>g(se===!0)}),e.jsx(M,{htmlFor:"reverse-access-confirmed",className:"text-xs font-normal leading-snug",children:xe})]})]}),e.jsxs(fs,{children:[e.jsx(S,{variant:"ghost",onClick:n,disabled:J||$,children:"Cancel"}),e.jsxs(S,{onClick:()=>void Ne(),disabled:!Z,children:[(J||$)&&e.jsx(Y,{className:"h-4 w-4 mr-2 animate-spin"}),$?"Sending emails…":"Reverse swap"]})]})]})})}function fr({caseId:s,refreshKey:n}){var h;
6const[r,o]=a.useState({state:"loading"});if(a.useEffect(()=>{let l=!0;return o({state:"loading"}),j.functions.invoke("program-swap-cancel-product",{body:{case_id:s,dry_run:!0}}).then(({data:p,error:b})=>{if(l)if(p!=null&&p.ok&&p.kajabi_offer_id)o({state:"ok",id:String(p.kajabi_offer_id),title:p.offer_title??null,source:p.resolved_source??null});else{const c=(p==null?void 0:p.details)??{};o({state:"unresolved",error:(p==null?void 0:p.error)??(b==null?void 0:b.message)??"Could not resolve the Kajabi offer",candidates:c.candidates??c.succeeded_charges_found??[]})}}).catch(p=>{l&&o({state:"unresolved",error:(p==null?void 0:p.message)??"Preview unavailable",candidates:[]})}),()=>{l=!1}},[s,n]),r.state==="loading")return e.jsx("span",{className:"text-muted-foreground",children:"Resolving…"});if(r.state==="ok"){const l=!!r.source&&/^[cde]_/.test(r.source),p=(h=r.source)!=null&&h.startsWith("c_")?"resolved live from refund - not stored on case":"resolved live - not stored on case";return e.jsxs("div",{children:[e.jsxs("span",{title:r.source??void 0,children:[r.title??"Untitled offer"," ",e.jsxs("span",{className:"text-muted-foreground",children:["(",r.id,")"]})]}),l&&e.jsx("div",{className:"text-xs text-muted-foreground",children:p})]})}return e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"text-destructive",children:["Not resolved — ",r.error]}),r.candidates.length>0&&e.jsx("ul",{className:"text-xs text-muted-foreground list-disc pl-4",children:r.candidates.map(l=>e.jsxs("li",{children:[l.offer_title??"Untitled"," (",l.kajabi_offer_id,")",l.amount!=null?` — $${l.amount}`:""]},l.kajabi_offer_id))})]})}function Xs(s){const n=s==null?void 0:s.raw_audit_json;return Array.isArray(n)&&n.some(r=>(r==null?void 0:r.action)==="swap_reversed")}function rt(s){const n=Ba.find(r=>r.value===s);return e.jsx(Se,{variant:"secondary",className:`inline-flex items-center whitespace-nowrap rounded-md px-2 py-0.5 text-xs font-medium ${(n==null?void 0:n.tone)??"bg-muted text-muted-foreground"}`,children:(n==null?void 0:n.label)??s})}function W(s){return s==null?"—":new Intl.NumberFormat("en-US",{style:"currency",currency:"USD"}).format(s)}function Re(s){if(!s)return"—";try{return Ps(new Date(s),"dd/MM/yyyy")}catch{return"—"}}function Pt(s){if(!s)return"—";try{return Ps(new Date(s),"dd/MM/yyyy HH:mm")}catch{return"—"}}function _r(s){const n=(s==null?void 0:s.action)??"unknown",r=s??{},o=r.error?String(r.error):"";switch(n){case"case_created_from_refund":return{title:"Case created from refund",detail:"Inserted row into program_swap_cases (program-swap-create).",tone:"default"};case"credit_note_issued":return{title:"Credit note issued",detail:"PDF generated & emailed to customer. program-swap-issue-credit-note → program_swap_credit_balances upsert.",tone:"success"};case"original_product_cancelled":return{title:"Original product cancelled",detail:"Cancelled on source platform (program-swap-cancel-product).",tone:"success"};case"samcart_manual_cancel_required":return{title:"Manual SamCart cancellation required",detail:"Admin must cancel the order inside SamCart and acknowledge.",tone:"warn"};case"samcart_manual_cancel_acknowledged":return{title:"Manual SamCart cancellation acknowledged",detail:"Admin confirmed the SamCart order/subscription was cancelled in SamCart.",tone:"success"};case"samcart_cancellation_not_applicable":return{title:"SamCart cancellation not applicable",detail:"Operator recorded that there is no recurring subscription to cancel.",tone:"success"};case"ghl_informed_marked":return{title:"GoHighLevel informed",detail:"Operator confirmed the GoHighLevel workflows were fired for the replacement product.",tone:"success"};case"ghl_informed_cleared":return{title:"GoHighLevel flag cleared",detail:"Operator un-ticked the GoHighLevel confirmation.",tone:"warn"};case"kajabi_offer_granted":return{title:"Kajabi offer granted",detail:`Granted offer ${r.kajabi_offer_id??""} to ${r.email??"customer"}.`,tone:"success"};case"kajabi_grant_failed":case"kajabi_grant_error":return{title:"Kajabi grant failed",detail:o||"Grant attempt failed — see manual fulfillment required.",tone:"error"};case"kajabi_contact_not_found":return{title:"Kajabi contact not found",detail
6:`No Kajabi contact for ${r.email??"customer email"}.`,tone:"warn"};case"kajabi_lookup_error":return{title:"Kajabi lookup error",detail:o,tone:"error"};case"manual_fulfillment_required":return{title:"Manual fulfillment required",detail:r.reason?String(r.reason):"Cannot auto-grant — handle manually.",tone:"warn"};case"credit_balance_saved":return{title:"Credit balance saved",detail:`Remaining balance ${r.amount!=null?W(Number(r.amount)):""} stored in program_swap_credit_balances.`,tone:"default"};case"credit_balance_upsert_failed":return{title:"Credit balance save failed",detail:o,tone:"error"};case"top_up_required":return{title:"Top-up required",detail:`Replacement total exceeds credit by ${r.amount!=null?W(Number(r.amount)):""}.`,tone:"warn"};case"topup_link_created":return{title:"Stripe top-up link created",detail:r.url?String(r.url):"Payment link created (program-swap-create-topup-link).",tone:"success"};case"status_change":return{title:"Status change",detail:`→ ${r.to??"?"}`,tone:"default"};case"original_amount_set_manually":return{title:"Original amount set manually",detail:`Set to ${r.amount!=null?W(Number(r.amount)):""}; recalculated 90% credit / 10% deduction.`,tone:"default"};case"completed_manual":return{title:"Force-completed by admin",detail:"Admin closed the case manually — bypassing the normal replacement/top-up flow. Use only when the case is truly done outside the automated flow.",tone:"success"};case"completed_speaker_granted":return{title:"Access granted → Completed",detail:"Admin confirmed the speaker granted replacement access to the customer. Case closed.",tone:"success"};case"speaker_grant_request_sent":return{title:"Speaker grant request sent",detail:`Emailed ${r.recipient_email??"speaker"} asking them to grant access to ${r.product_name??"replacement product"}.`,tone:"success"};case"speaker_grant_request_failed":return{title:"Speaker grant request failed",detail:o||"Could not send grant request — retry from the drawer.",tone:"error"};case"speaker_grant_request_unresolved":return{title:"Speaker grant request unresolved",detail:`No speaker/owner could be resolved for ${r.product_name??"replacement product"} — handle manually.`,tone:"warn"};case"speaker_revoke_stamp":return{title:"SamCart access marked revoked",detail:`Speaker (${r.recipient_email??"recipient"}) was emailed the SamCart revocation request. access_revoked_at stamped with method '${r.method??"speaker_revoke_requested"}'.`,tone:"success"};default:return{title:String(n),detail:"",tone:"default"}}}async function Ts(s,n,r,o){const h=Array.isArray(n)?n:[];h.push({at:new Date().toISOString(),...r});const{error:l}=await j.from("program_swap_cases").update({...o,raw_audit_json:h}).eq("id",s);if(l)throw l}async function Bt(s){if(Number(s.prior_credit_applied??0)>0)try{await j.functions.invoke("program-swap-cancel-credit-anomaly",{body:{case_id:s.id}})}catch(n){console.error("cancel-with-prior-credit anomaly not recorded",n)}}function Ir(){const[s,n]=ka(),[r,o]=a.useState([]),[h,l]=a.useState(!0),[p,b]=a.useState("active"),[c,k]=a.useState(""),[i,f]=a.useState(s.get("case")),[O,y]=a.useState([]),[A,T]=a.useState(null),[E,_]=a.useState(!1),[g,F]=a.useState(null),[q,J]=a.useState(!1),[w,$]=a.useState(""),[pe,I]=a.useState(null),[K,U]=a.useState([]),[_e,xe]=a.useState(!1),[Ne,Z]=a.useState({}),[se,ye]=a.useState(null),[P,re]=a.useState(null),[me,oe]=a.useState(null),v=a.useCallback(async m=>{var C;oe(m);try{const{data:H,error:Q}=await j.functions.invoke("program-swap-reverse-notify",{body:{case_id:m}});if(Q){d.error(await Xe(Q,"Could not send the reversal emails"));return}if(H!=null&&H.ok)d.success("Reversal emails sent");else{const ae=((H==null?void 0:H.owner_emails)??[]).filter(ne=>!ne.sent),te=(H==null?void 0:H.customer_error)??((C=ae[0])==null?void 0:C.error)??(H==null?void 0:H.error)??"Unknown error";d.error(`Some emails did not send: ${te}`)}}finally{oe(null)}},[]),{allRoles:L}=It(),G=L.includes("admin")||L.includes("management"),ge=["product_swapped","completed","top_up_paid"],u=a.useCallback(async()=>{l(!0);const{data:m,error:C}=await j.from("program_swap_cases").select("*").is("deleted_at",null).order("created_at",{ascending:!1});if(C)d.error(C.message);else{const H=m??[],Q=H.filter(te=>{var ne;return!((ne=te.customer_name)!=null&&ne.trim())}).map(te=>te.customer_email),ae=await bt(Q);o(H.map(te=>{var ne;return{...te,customer_name_display:((ne=te.customer_name)==null?void 0:ne.trim())||ae.get((te.customer_email??"").trim().toLowerCase())||null}}))}l(!1)},[]),D=a.useCallback(async()=>{var ne;xe(!0);const{data:m,error:C}=await j.from("program_swap_cases").select("*").not("deleted_at","is",null).order("deleted_at",{ascending:!1});if(C){d.error(C.message),xe(!1);return}const H=m??[],Q=await bt(H.filter(de=>{var ce;return!((ce=de.customer_name)!=null&&ce.trim())}).map(de=>de.customer_email)),ae=H.map(de=>{var ce;return{...de,customer_name_display:((ce=de.customer_name)==null?void 0:ce.trim())||Q.get((de.customer_email??"").trim().toLowerCase())||null}});U(ae);const te=Array.from(new Set(ae.map(de=>
6de.deleted_by).filter(Boolean)));if(te.length){const{data:de,error:ce}=await j.from("profiles").select("id, display_name, email").in("id",te);if(ce)d.error(`Could not resolve who deleted these cases: ${ce.message}`);else{const le={};for(const ie of de??[])le[ie.id]=((ne=ie.display_name)==null?void 0:ne.trim())||ie.email||ie.id;Z(le)}}xe(!1)},[]),we=a.useCallback(async(m,C)=>{_(!0);try{const{data:H,error:Q}=await j.rpc("delete_program_swap_case",{p_case_id:m.id,p_reason:C.trim()});if(Q)throw Q;const ae=H;if(ae&&ae.ok===!1)throw new Error(ae.error??"Failed to delete case");d.success("Program Swap case deleted"),T(null),$(""),await Promise.all([u(),D()])}catch(H){d.error((H==null?void 0:H.message)??"Failed to delete case")}finally{_(!1)}},[u,D]),he=a.useCallback(async m=>{ye(m.id);try{const{data:C,error:H}=await j.rpc("restore_program_swap_case",{p_case_id:m.id});if(H)throw H;const Q=C;if(Q&&Q.ok===!1)throw new Error(Q.error??"Failed to restore case");d.success("Program Swap case restored"),await Promise.all([u(),D()])}catch(C){d.error((C==null?void 0:C.message)??"Failed to restore case")}finally{ye(null)}},[u,D]);a.useEffect(()=>{let m=!1;if(!(A!=null&&A.refund_request_id)){I(null);return}return(async()=>{const{data:C}=await j.from("refund_requests").select("status").eq("id",A.refund_request_id).maybeSingle();m||I((C==null?void 0:C.status)??null)})(),()=>{m=!0}},[A==null?void 0:A.refund_request_id]),a.useEffect(()=>{u(),D()},[u,D]),a.useEffect(()=>{(async()=>{const{data:m,error:C}=await j.rpc("get_program_swap_assignees");if(C){d.error(`Failed to load team: ${C.message}`);return}const H=(m??[]).map(Q=>{var ae,te;return{id:Q.id,name:((ae=Q.display_name)==null?void 0:ae.trim())||((te=Q.email)==null?void 0:te.split("@")[0])||"Unnamed",email:Q.email??null}}).sort((Q,ae)=>Q.name.localeCompare(ae.name));y(H)})()},[]);const Ue=a.useMemo(()=>{const m=c.trim().toLowerCase();return r.filter(C=>{if(p==="active"){if(Lt.has(C.status))return!1}else if(p!=="all"&&C.status!==p)return!1;return m?(C.customer_email??"").toLowerCase().includes(m)||(C.customer_name_display??C.customer_name??"").toLowerCase().includes(m)||(C.original_product_name??"").toLowerCase().includes(m):!0})},[r,c,p]),_s=a.useCallback(async m=>{J(!0);try{await Ts(m.id,m.raw_audit_json,{action:"cancelled"},{status:"cancelled",cancelled_at:new Date().toISOString()}),await Bt(m),d.success("Case cancelled"),F(null),await u()}catch(C){d.error((C==null?void 0:C.message)??"Could not cancel case")}finally{J(!1)}},[u]),gs=a.useMemo(()=>r.find(m=>m.id===i)??null,[r,i]),He=m=>{f(m),n({case:m})},Qe=()=>{f(null);const m=new URLSearchParams(s);m.delete("case"),n(m)};return e.jsxs("div",{className:"container max-w-none 2xl:px-8 py-6 space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground mb-1",children:[e.jsxs($s,{to:"/admin/refunds",className:"hover:underline inline-flex items-center gap-1",children:[e.jsx(Sa,{className:"h-3 w-3"})," Refunds Hub"]}),e.jsx("span",{children:"/"}),e.jsx("span",{children:"Program Swap Hub"})]}),e.jsxs("h1",{className:"text-2xl font-bold tracking-tight flex items-center gap-2",children:[e.jsx(Ca,{className:"h-6 w-6 text-primary"})," Program Swap Hub"]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Operational workflow for refund-to-swap conversions. No Stripe charges, refunds, or financial adjustments are made from this hub."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(S,{variant:"outline",size:"sm",asChild:!0,children:e.jsx($s,{to:"/admin/program-swap/adjustments",children:"Swap adjustments"})}),e.jsxs(S,{variant:"outline",size:"sm",onClick:()=>u(),children:[e.jsx(et,{className:`h-4 w-4 mr-2 ${h?"animate-spin":""}`})," Refresh"]})]})]}),e.jsxs(Ia,{defaultValue:"cases",className:"space-y-4",children:[e.jsxs(Fa,{children:[e.jsx(Ls,{value:"cases",children:"Cases"}),e.jsx(Ls,{value:"credit-balances",children:"Credit balances"}),e.jsx(Ls,{value:"coupon-register",children:"Coupon register"}),e.jsxs(Ls,{value:"deleted",children:["Deleted",K.length?` (${K.length})`:""]})]}
6),e.jsxs(Ms,{value:"cases",className:"space-y-4 mt-0",children:[e.jsx(je,{children:e.jsxs(be,{className:"p-3 space-y-3",children:[e.jsx(Ya,{rows:r,value:p,onChange:b}),e.jsxs("div",{className:"border-t border-border pt-3 flex flex-wrap items-center gap-2",children:[e.jsx(ee,{placeholder:"Search customer, email, product",value:c,onChange:m=>k(m.target.value),className:"max-w-sm"}),e.jsxs("div",{className:"text-xs text-muted-foreground ml-auto",children:["Showing ",Ue.length," of ",r.length]})]})]})}),e.jsx(je,{children:e.jsx(be,{className:"p-0 overflow-x-auto",children:h?e.jsxs("div",{className:"p-12 text-center text-muted-foreground",children:[e.jsx(Y,{className:"h-5 w-5 animate-spin inline mr-2"})," Loading cases…"]}):Ue.length===0?e.jsx("div",{className:"p-12 text-center text-muted-foreground text-sm",children:"No Program Swap cases match this filter."}):e.jsxs("table",{className:"w-full text-xs",children:[e.jsx("thead",{className:"bg-muted/40 text-[10px] uppercase tracking-wide text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left px-2 py-1.5 whitespace-nowrap sticky left-0 z-20 bg-muted",children:"Customer"}),e.jsx("th",{className:"text-left px-2 py-1.5 whitespace-nowrap",children:"Original product"}),e.jsx("th",{className:"text-right px-2 py-1.5 whitespace-nowrap",children:"Original"}),e.jsx("th",{className:"text-left px-2 py-1.5 whitespace-nowrap",children:"Expires"}),e.jsx("th",{className:"text-left px-2 py-1.5 whitespace-nowrap",children:"Assigned"}),e.jsx("th",{className:"text-left px-2 py-1.5 whitespace-nowrap",children:"Status"}),e.jsx("th",{className:"text-left px-2 py-1.5 whitespace-nowrap",children:"Replacement"}),e.jsx("th",{className:"text-right px-2 py-1.5 whitespace-nowrap",children:"Top-up"}),e.jsx("th",{className:"text-left px-2 py-1.5 whitespace-nowrap",children:"Created / updated"}),e.jsx("th",{className:"px-2 py-1.5 sticky right-0 z-20 bg-muted"})]})}),e.jsx("tbody",{children:Ue.map(m=>e.jsxs("tr",{className:"border-t border-border hover:bg-muted/30 cursor-pointer group",onClick:()=>He(m.id),children:[e.jsxs("td",{className:"px-2 py-1.5 max-w-[190px] sticky left-0 z-10 bg-card group-hover:bg-muted/30",children:[e.jsx("div",{className:"font-medium truncate",title:m.customer_name_display??m.customer_name??void 0,children:m.customer_name_display??m.customer_name??"—"}),e.jsx("div",{className:"text-[11px] text-muted-foreground truncate",title:m.customer_email??void 0,children:m.customer_email??"—"})]}),e.jsx("td",{className:"px-2 py-1.5 max-w-[170px] truncate",title:m.original_product_name??void 0,children:m.original_product_name??"—"}),e.jsx("td",{className:"px-2 py-1.5 text-right tabular-nums whitespace-nowrap",children:W(m.original_purchase_amount)}),e.jsx("td",{className:"px-2 py-1.5 whitespace-nowrap",children:Re(m.credit_note_expires_at)}),e.jsx("td",{className:"px-2 py-1.5 whitespace-nowrap max-w-[110px] truncate",title:m.assigned_to_name??void 0,children:m.assigned_to_name??"—"}),e.jsx("td",{className:"px-2 py-1.5",children:e.jsxs("div",{className:"flex flex-nowrap items-center gap-1",children:[rt(m.status),Xs(m)&&e.jsx(Se,{variant:"secondary",className:"bg-muted text-muted-foreground whitespace-nowrap",children:"Reversed"})]})}),e.jsx("td",{className:"px-2 py-1.5 max-w-[170px] truncate",title:m.selected_replacement_product_name??void 0,children:m.selected_replacement_product_name??"—"}),e.jsxs("td",{className:"px-2 py-1.5 text-right tabular-nums whitespace-nowrap",children:[e.jsx("div",{children:W(m.top_up_amount_due)}),e.jsx("div",{className:"text-[11px] text-muted-foreground",children:m.top_up_status})]}),e.jsxs("td",{className:"px-2 py-1.5 whitespace-nowrap",children:[e.jsx("div",{children:Re(m.created_at)}),e.jsx("div",{className:"text-[11px] text-muted-foreground",children:Re(m.updated_at)})]}),e.jsx("td",{className:"px-2 py-1.5 text-right sticky right-0 z-10 bg-card group-hover:bg-muted/30",children:e.jsxs("div",{className:"flex items-center justify-end gap-1",children:[e.jsx(S,{size:"sm",variant:"ghost",onClick:C=>{C.stopPropagation(),He(m.id)},children:"Open"}),e.jsxs(Pa,{children:[e.jsx(Da,{asChild:!0,children:e.jsx(S,{size:"icon",variant:"ghost",className:"h-8 w-8",onClick:C=>C.stopPropagation(),children:e.jsx(Ra,{className:"h-4 w-4"})})}),e.jsxs(Ea,{align:"end",onClick:C=>C.stopPropagation(),children:[e.jsxs(Fs,{disabled:m.status==="cancelled",onClick:C=>{C.stopPropagation(),F(m)},children:[e.jsx(Zs,{className:"h-4 w-4 mr-2"})," Cancel case"]}),G&&ge.includes(m.status)&&!Xs(m)&&e.jsxs(Fs,{onClick:C=>{C.stopPropagation(),re(m)},children:[e.jsx(Aa,{className:"h-4 w-4 mr-2"})," Reverse swap"]}),G&&Xs(m)&&e.jsxs(Fs,{disabled:me===m.id,onClick:C=>{C.stopPropagation(),v(m.id)},children:[e.jsx(Qs,{className:"h-4 w-4 mr-2"})," Resend reversal emails"]}),e.jsxs(Fs,{className:"text-destructive focus:text-destructive",onClick:C=>{C.stopPropagation(),$(""),T(m)},children:[e.jsx(Ft,{className:"h-4 w-4 mr-2"})," Delete duplicate"]})]})]})]})})]},m.id))})]})})})]}),e.jsx(Ms,{value:"credit-balances",className:"mt-0",children:e.jsx(cr,{onChanged:()=>u()})}),e.jsx(Ms,{value:"coupon-register",className:"mt-0",children:e.jsx(ur,{onChanged:()=>u()})}),e.jsx(Ms,{value:"deleted",className:"mt-0",children:e.jsxs(je,{children:[e.jsxs(De,{className:"pb-2",children:[e.jsx(Ee,{className:"text-base",children:"Deleted cases"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Soft-deleted Program Swap cases. Nothing here is destroyed — restore returns the case to the Hub."})]}),e.jsx(be,{className:"p-0 overflow-x-auto",children:_e?e.jsxs("div",{className:"p-12 text-center text-muted-foreground",children:[e.jsx(Y,{className:"h-5 w-5 animate-spin inline mr-2"})," Loading deleted cases…"]}):K.length===0?e.jsx("div",{className:"p-12 text-center text-muted-foreground text-sm",children:"No deleted Program Swap cases."}):e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/40 text-xs uppercase tracking-wide text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left p-3",children:"Customer"}),e.jsx("th",{className:"text-left p-3",children:"Original product"}),e.jsx("th",{className:"text-left p-3",children:"Status at deleti
6on"}),e.jsx("th",{className:"text-left p-3",children:"Reason"}),e.jsx("th",{className:"text-left p-3",children:"Deleted by"}),e.jsx("th",{className:"text-left p-3",children:"Deleted"}),e.jsx("th",{className:"p-3"})]})}),e.jsx("tbody",{children:K.map(m=>e.jsxs("tr",{className:"border-t border-border",children:[e.jsxs("td",{className:"p-3",children:[e.jsx("div",{className:"font-medium",children:m.customer_name_display??m.customer_name??"—"}),e.jsx("div",{className:"text-xs text-muted-foreground",children:m.customer_email??"—"})]}),e.jsx("td",{className:"p-3",children:m.original_product_name??"—"}),e.jsx("td",{className:"p-3",children:rt(m.status)}),e.jsx("td",{className:"p-3 text-xs max-w-[280px]",children:m.deletion_reason??"—"}),e.jsx("td",{className:"p-3 text-xs",children:m.deleted_by?Ne[m.deleted_by]??"…":"—"}),e.jsx("td",{className:"p-3 text-xs",children:Re(m.deleted_at??null)}),e.jsx("td",{className:"p-3 text-right",children:e.jsx(S,{size:"sm",variant:"outline",disabled:se===m.id,onClick:()=>void he(m),children:se===m.id?e.jsxs(e.Fragment,{children:[e.jsx(Y,{className:"h-3.5 w-3.5 animate-spin mr-1.5"})," Restoring…"]}):"Restore"})})]},m.id))})]})})]})})]}),gs&&e.jsx(gr,{row:gs,teamMembers:O,onClose:Qe,onChanged:u}),e.jsx(rs,{open:!!A,onOpenChange:m=>{!m&&!E&&(T(null),$(""))},children:e.jsxs(ns,{children:[e.jsxs(is,{children:[e.jsx(os,{children:"Delete this duplicate Program Swap case?"}),e.jsx(ds,{asChild:!0,children:e.jsxs("div",{children:[e.jsx("p",{children:"The case is removed from the Hub and kept in the Deleted tab, where it can be restored. A reason is required."}),A&&e.jsxs("div",{className:"mt-3 rounded-md border border-border bg-muted/40 p-3 text-xs space-y-1",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Customer:"})," ",A.customer_name_display??A.customer_name??"—"," (",A.customer_email??"—",")"]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Original product:"})," ",A.original_product_name??"—"]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Status:"})," ",A.status]})]}),pe==="program_swap"&&e.jsxs("div",{className:"mt-3 rounded-md border border-amber-500/40 bg-amber-500/10 p-3 text-xs text-amber-900 dark:text-amber-200 flex gap-2",children:[e.jsx(qe,{className:"h-4 w-4 shrink-0 mt-0.5"}),e.jsx("span",{children:"The refund ticket for this case is still in Program Swap. If the customer still needs a refund decision, use Return to Refunds Hub instead — deleting the case here leaves that ticket unworkable until the case is restored."})]}),e.jsxs("div",{className:"mt-3 space-y-1.5",children:[e.jsx(M,{htmlFor:"swap-delete-reason",className:"text-xs",children:"Reason (required)"}),e.jsx(Ze,{id:"swap-delete-reason",value:w,onChange:m=>$(m.target.value),placeholder:"e.g. Duplicate of case created earlier the same day",className:"text-sm",disabled:E})]})]})})]}),e.jsxs(cs,{children:[e.jsx(ls,{disabled:E,children:"Cancel"}),e.jsx(ms,{disabled:E||w.trim().length<3,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",onClick:m=>{m.preventDefault(),A&&we(A,w)},children:E?"Deleting…":"Delete duplicate"})]})]})}),e.jsx(rs,{open:!!g,onOpenChange:m=>{m||F(null)},children:e.jsxs(ns,{children:[e.jsxs(is,{children:[e.jsx(os,{children:"Cancel this program swap?"}),e.jsxs(ds,{children:["The case for ",(g==null?void 0:g.customer_name_display)??(g==null?void 0:g.customer_name)??(g==null?void 0:g.customer_email)??"this customer"," will be marked cancelled and stay visible for audit. No refund is issued and no access is changed."]})]}),e.jsxs(cs,{children:[e.jsx(ls,{disabled:q,children:"Keep case"}),e.jsx(ms,{disabled:q,onClick:m=>{m.preventDefault(),g&&_s(g)},children:q?"Cancelling…":"Cancel case"})]})]})}),P&&e.jsx(hr,{row:P,onClose:()=>re(null),onSuccess:()=>{u()}})]})}function gr({row:s,teamMembers:n,onClose:r,onChanged:o}){const{user:h,allRoles:l}=It(),p=l.includes("admin")||l.includes("management")||l.includes("super_admin"),b=l.includes("admin")||l.includes("management")||l.includes("super_admin")||l.includes("moderator"),[c,k]=a.useState(0),[i,f]=a.useState([]),[O,y]=a.useState(!0),[A,T]=a.useState([]),[E,_]=a.useState(""),[g,F]=a.use
6State([]),[q,J]=a.useState(!1),[w,$]=a.useState(""),[pe,I]=a.useState(""),[K,U]=a.useState(!1),[_e,xe]=a.useState(s.internal_notes??""),[Ne,Z]=a.useState(s.notes??""),[se,ye]=a.useState(!1),[P,re]=a.useState(!1),[me,oe]=a.useState(!1),[v,L]=a.useState(null),[G,ge]=a.useState(""),[u,D]=a.useState(null),[we,he]=a.useState(null),[Ue,_s]=a.useState(0),[gs,He]=a.useState(!1),[Qe,m]=a.useState(""),[C,H]=a.useState(!1),[Q,ae]=a.useState(""),[te,ne]=a.useState(""),[de,ce]=a.useState(!1),le=(Array.isArray(s.raw_audit_json)?[...s.raw_audit_json].reverse().find(t=>(t==null?void 0:t.action)==="swap_reversed"):null)??null,ie=!!le,[zs,zt]=a.useState(0),es=s.status==="completed"||zs>0||ie,ys=a.useCallback(async()=>{y(!0);const[{data:t,error:x},{count:N}]=await Promise.all([j.from("program_swap_replacement_items").select("*").eq("case_id",s.id).order("created_at",{ascending:!0}),j.from("program_swap_adjustments").select("id",{count:"exact",head:!0}).eq("program_swap_case_id",s.id)]);x?d.error(x.message):f(t??[]),zt(N??0),y(!1)},[s.id]);a.useEffect(()=>{ys()},[ys]),a.useEffect(()=>{xe(s.internal_notes??""),Z(s.notes??""),ge(s.original_purchase_amount!=null?String(s.original_purchase_amount):"")},[s.id]),a.useEffect(()=>{if(!s.customer_email){D(null),he(null);return}(async()=>{var ue,Te;const{data:t}=await j.from("customer_credit_balances").select("id, balance_amount, credit_note_expires_at, currency, source_case_id").ilike("customer_email",s.customer_email).eq("currency","USD").gt("balance_amount",0).or(`credit_note_expires_at.is.null,credit_note_expires_at.gt.${new Date().toISOString()}`).order("credit_note_expires_at",{ascending:!0,nullsFirst:!1}),x=t??[],N=Ce=>Math.round(Ce.reduce((ss,We)=>ss+Number(We.balance_amount||0),0)*100)/100,R=x.filter(Ce=>Ce.source_case_id!==s.id),B=x.filter(Ce=>Ce.source_case_id===s.id),z=N(R),X=N(B);D(z>0?{balance_amount:z,credit_note_expires_at:((ue=R[0])==null?void 0:ue.credit_note_expires_at)??null}:null),he(X>0?{balance_amount:X,credit_note_expires_at:((Te=B[0])==null?void 0:Te.credit_note_expires_at)??null}:null)})()},[s.id,s.customer_email,Ue]),a.useEffect(()=>{(async()=>{const{data:t,error:x}=await j.from("speakers").select("id, name").order("name");if(x){d.error(`Failed to load speakers: ${x.message}`);return}T(t??[])})()},[]),a.useEffect(()=>{if(!E){F([]),$("");return}J(!0),$(""),(async()=>{const[{data:t,error:x},{data:N,error:R}]=await Promise.all([j.from("kajabi_offers").select("id, kajabi_offer_id, title, price, current_sale_price, core_offer_summary, custom_image_url").eq("speaker_id",E).eq("is_active",!0).order("title"),j.from("products").select("id, platform_product_id, name, price, current_sale_price, product_contents, image_url").eq("speaker_id",E).eq("is_active",!0).order("name")]);x&&d.error(`Kajabi offers: ${x.message}`),R&&d.error(`Products: ${R.message}`);const B=(t??[]).map(V=>V.id).filter(Boolean),z=(N??[]).map(V=>V.platform_product_id).filter(Boolean),[{data:X},{data:ue}]=await Promise.all([B.length?j.from("kajabi_purchases").select("kajabi_offer_id, activated_at, created_at").in("kajabi_offer_id",B):Promise.resolve({data:[]}),z.length?j.from("orders").select("platform_product_id, purchase_date").in("platform_product_id",z):Promise.resolve({data:[]})]),Te=new Map;for(const V of X??[]){const Oe=String(V.kajabi_offer_id),$e=V.activated_at??V.created_at;if(!$e)continue;const ke=Te.get(Oe);(!ke||ke<$e)&&Te.set(Oe,$e)}const Ce=new Map;for(const V of ue??[]){const Oe=String(V.platform_product_id),$e=V.purchase_date;if(!$e)continue;const ke=Ce.get(Oe);(!ke||ke<$e)&&Ce.set(Oe,$e)}const ss=(t??[]).map(V=>({id:V.id,source_platform:"kajabi",external_id:V.kajabi_offer_id??null,name:V.title,price:V.current_sale_price??V.price??null,description:V.core_offer_summary??null,image_url:V.custom_image_url??null,last_ordered_at:Te.get(String(V.id))??null})),We=(N??[]).map(V=>({id:V.id,source_platform:"samcart",external_id:V.platform_product_id??null,name:V.name,price:V.current_sale_price??V.price??null,description:V.product_contents??null,image_url:V.image_url??null,last_ordered_at:V.platform_product_id?Ce.get(String(V.platform_product_id))??null:null}));F([...ss,...We]),J(!1)})()},[E]);const fe=a.useMemo(()=>g.find(t=>`${t.source_platform}:${t.id}`===w)??null,[g,w]),Be=a.useMemo(()=>i.reduce((t,x)=>t+(Number(x.product_price)||0),0),[i]),js=Number(s.credit_note_amount??0),ws=Number(s.prior_credit_applied??0),bs=Us({replacementTotal:Be,creditNoteAmount:js,priorCreditApplied:ws}),it=Be<=js?Math.round((js-Be)*100)/100:0,Ks=(u==null?void 0:u.balance_amount)??0,Es=Math.min(Ks,bs),Kt=new Set(["credit_note_issued","selecting_product","top_up_required","top_up_sent"]),Gt=b&&Ks>0&&bs>0&&Kt.has(s.status)&&s.top_up_status!=="paid"&&!ie&&!s.deleted_at,Vt=async()=>{const t=Number(Qe);if(!Number.isFinite(t)||t<=0){d.error("Enter an amount greater than 0.");return}const x=Math.min(Math.round(t*100)/100,Es);L("apply_credit");try{const{data:N,error:R}=await j.functions.invoke("program-swap-apply-prior-credit",{body:{case_id:s.id,amount:x,invoice_voided:!!s.top_up_stripe_invoice_id}});if(R)throw new Error(await Xe(R,"Could not apply credit"));if(!(N!=null&&N.ok))throw new Error((N==null?void 0:N.error)??"Could not apply credit");const B=N.result??{},z=Number(B.applied??x),X=Number(B.requested_amount??x);B.clamped?d.success(`Applied ${W(z)} of the ${W(X)} requested — that is the full spendable balance.`):d.success(`Applied ${W(z)} of prior credit.`),He(!1),_s(ue=>ue+1),o()}catch(N){d.error((N==null?void 0:N.message)??"Could not apply credit")}finally{L(null)}},vs=Array.isArray(s.raw_audit_json)?s.raw_audit_json:[],Gs=vs.find(t=>(t==null?void 0:t.action)==="original_product_cancelled"),ot=(Gs==null?void 0:Gs.at)??null,ze=(s.original_source_platform??"").toLowerCase(),qs=new Set(["product_swapped","top_up_required","top_up_sent","top_up_paid","completed","cancelled","returned_to_pending_refund"]).has(s.status),Os=async(t,x)=>{L("save");try{await Ts(s.id,s.raw_audit_json,x,t),o(),d.success("Saved")}catch(N){d.error(N.message)}finally{L(null)}},dt=async(t,x)=>{var N;try{const{data:R}=await j.auth.getUser(),{data:B}=await j.from("program_swap_cases").select("raw_audit_json").eq("id",s.id).maybeSingle(),z=Array.isArray(B==null?void 0:B.raw_audit_json)?[...B.raw_audit_json]:Array.isArray(s.raw_audit_json)?[...s.raw_audit_json]:[];z.push({at:new Date().toISOString(),action:"edge_function_call_failed",fn:t,error:x,by_email:((N=R==null?void 0:R.user)==null?void 0:N.email)??null}),await j.from("program_swap_cases").update({raw_audit_json:z}).eq("id",s.id)}catch(R){console.error("could not persist edge_function_call_failed",R)}},Is=async(t,x,N)=>{L(t);try{const{data:R,error:B}=await j.functions.invoke(x,{body:{case_id:s.id}});if(B)throw new Error(await Xe(B,`${N} failed`));if(R&&R.ok===!1)throw new Error(R.error??`${N} failed`);return o(),R}catch(R){const B=(R==null?void 0:R.message)??"failed";return await dt(x,B),d.error(`${N}: ${B}`),null}finally{L(null)}},Wt=async()=>{const t=Number(G);if(!(t>0)){d.error("Enter a positive amount");return}const x=Math.round(t*100)/100,N=0,R=new Date;R.setMonth(R.getMonth()+6),await Os({original_purchase_amount:t,credit_note_amount:x,credit_note_discount_or_fee_amount:N,credit_note_percentage_deducted:0,credit_note_expires_at:R.toISOString()},{action:"original_amount_set_manually",amount:t})},Yt=async()=>{const t=await Is("cancel_product","program-swap-cancel-product","Cancel original product");t!=null&&t.ok&&t.platform==="kajabi"&&d.success("Kajabi access revoked")},Jt=async()=>{const t=await Is("issue_credit_note","program-swap-issue-credit-note","Send credit note");t!=null&&t.ok&&!t.already_issued&&d.success(`Credit note emailed to ${t.emailed_to}`)},Xt=async()=>{const t=await Is("provision","program-swap-provision-replacement","Provision replacements");t!=null&&t.ok&&(t.all_items_requested===!1?d.warning(`Provisioned with ${t.grant_requests_unresolved??0}
6 unresolved item(s) — case held. `+(t.manual_notes??[]).join(" · ")):t.top_up_required?d.info(`Top-up required: $${t.top_up_amount}`):t.credit_balance_saved!=null?d.success(`Provisioned. Credit balance $${t.credit_balance_saved} saved.`):d.success("Provisioned & completed"))},Zt=async()=>{L("topup_resend");try{const{data:t,error:x}=await j.functions.invoke("program-swap-create-topup-link",{body:{case_id:s.id,resend_email:!0}});if(x)throw new Error(await Xe(x,"Resend failed"));if(t&&t.ok===!1)throw new Error(t.error??"Resend failed");d.success("Payment email re-sent (copy to [email protected])"),o()}catch(t){const x=(t==null?void 0:t.message)??"failed";await dt("program-swap-create-topup-link",x),d.error(`Resend payment email: ${x}`)}finally{L(null)}},Qt=async()=>{const t=await Is("provision","program-swap-provision-replacement","Send speaker grant requests");t!=null&&t.ok&&(t.all_items_requested===!1?d.warning(`Sent with ${t.grant_requests_unresolved??0} unresolved item(s) — case held. `+(t.manual_notes??[]).join(" · ")):d.success("Speaker grant requests sent"))},ct=()=>{k(t=>t+1),o()},ea=async t=>{const x=n.find(N=>N.id===t)??null;return Os({assigned_to_user_id:t==="__none__"?null:t,assigned_to_name:t==="__none__"?null:(x==null?void 0:x.name)??null,assigned_to_email:t==="__none__"?null:(x==null?void 0:x.email)??null,assigned_at:t==="__none__"?null:new Date().toISOString()},{action:"assigned",user_id:t==="__none__"?null:t})},sa=async()=>{var z;if(!fe){d.error("Select a speaker, then a program/offer");return}if(es){d.error("Case is frozen — cannot add or edit replacement items after adjustments are written.");return}const t=fe,x=t.price;let N=x,R=null,B=null;if(C){const X=Number(Q);if(!Number.isFinite(X)||X<=0){d.error("Override price must be a positive number.");return}const ue=te.trim();if(!ue){d.error("A reason is required for a price override (e.g. coupon code + swap offer price).");return}if(x!=null&&X>x&&!de){d.error("Charging above catalog price — tick the confirmation box before saving.");return}N=Math.round(X*100)/100,R=`Price override: catalog ${x!=null?x.toFixed(2):"n/a"} → ${N.toFixed(2)}. Reason: ${ue}`,B={action:"replacement_price_overridden",product_id:t.id,product_name:t.name,catalog_price:x,override_price:N,reason:ue}}L("add_item");try{const{data:X}=await j.auth.getUser(),ue=((z=X==null?void 0:X.user)==null?void 0:z.email)??null;let Te=t.id;if(t.source_platform==="kajabi"){const{data:ke,error:ks}=await j.from("kajabi_offers").select("kajabi_offer_id, title").eq("id",t.id).maybeSingle();if(ks)throw ks;let Ss=null;if((ke==null?void 0:ke.kajabi_offer_id)!=null){const{data:ts,error:Cs}=await j.from("products").select("id").eq("platform_product_id",String(ke.kajabi_offer_id)).maybeSingle();if(Cs)throw Cs;Ss=(ts==null?void 0:ts.id)??null}if(!Ss){const{data:ts,error:Cs}=await j.from("products").select("id").eq("source_platform","kajabi").eq("name",(ke==null?void 0:ke.title)??t.name).maybeSingle();if(Cs)throw Cs;Ss=(ts==null?void 0:ts.id)??null}if(!Ss)throw new Error(`"${t.name}" has no matching product record, so the commission ledger cannot reference it. Create the product under Products (matching the Kajabi offer), then add the replacement again.`);Te=Ss}const{error:Ce}=await j.from("program_swap_replacement_items").insert({case_id:s.id,product_id:Te,product_name:t.name,product_price:N,source_platform:t.source_platform,notes:R});if(Ce)throw Ce;$(""),_(""),I(""),U(!1),H(!1),ae(""),ne(""),ce(!1),await ys();const ss=Be+(N??0),We=Us({replacementTotal:ss,creditNoteAmount:js,priorCreditApplied:ws}),V=Array.isArray(s.raw_audit_json)?[...s.raw_audit_json]:[],Oe=new Date().toISOString();V.push({at:Oe,action:"replacement_added",product_id:t.id,source_platform:t.source_platform,product_name:t.name,price:N,catalog_price:x,price_overridden:B!=null}),B&&V.push({at:Oe,by_email:ue,...B});const{error:$e}=await j.from("program_swap_cases").update({selected_replacement_product_name:t.name,selected_replacement_product_price:N,top_up_amount_due:We,raw_audit_json:V}).eq("id",s.id);if($e)throw $e;o(),d.success(B?"Replacement added (price override recorded)":"Replacement added")}catch(X){d.error(X.message)}finally{L(null)}},ta=async t=>{L(`rm_${t}`);try{const x=i.find(z=>z.id===t),{error:N}=await j.from("program_swap_replacement_items").delete().eq("id",t);if(N)throw N;await ys();const R=Be-(Number(x==null?void 0:x.product_price)||0),B=Us({replacementTotal:R,creditNoteAmount:js,priorCreditApplied:ws});await Ts(s.id,s.raw_audit_json,{action:"replacement_removed",item_id:t},{top_up_amount_due:B}),o()}catch(x){d.error(x.message)}finally{L(null)}}
6,[lt,mt]=a.useState(null),[ut,Vs]=a.useState(""),[pt,Ws]=a.useState(""),aa=t=>{mt(t.id),Vs(t.product_price!=null?String(t.product_price):""),Ws("")},xt=()=>{mt(null),Vs(""),Ws("")},ra=async t=>{var z;if(es){d.error("Case is frozen — item prices cannot be edited after adjustments are written.");return}const x=Number(ut);if(!Number.isFinite(x)||x<=0){d.error("Price must be a positive number.");return}const N=pt.trim();if(!N){d.error("A reason is required for a price correction.");return}const R=Math.round(x*100)/100,B=Number(t.product_price??0);if(R===B){d.error("Price unchanged.");return}L(`edit_${t.id}`);try{const{data:X}=await j.auth.getUser(),ue=((z=X==null?void 0:X.user)==null?void 0:z.email)??null,Te=(t.notes??"").trim(),Ce=`Price correction: ${B.toFixed(2)} → ${R.toFixed(2)}. Reason: ${N}`,ss=Te?`${Te}
7${Ce}`:Ce,{error:We}=await j.from("program_swap_replacement_items").update({product_price:R,notes:ss}).eq("id",t.id);if(We)throw We;await ys();const V=R-B,Oe=Be+V,$e=Us({replacementTotal:Oe,creditNoteAmount:js,priorCreditApplied:ws}),ke=Array.isArray(s.raw_audit_json)?[...s.raw_audit_json]:[];ke.push({at:new Date().toISOString(),action:"replacement_price_corrected",item_id:t.id,product_id:t.product_id,product_name:t.product_name,old_price:B,new_price:R,reason:N,by_email:ue});const{error:ks}=await j.from("program_swap_cases").update({top_up_amount_due:$e,raw_audit_json:ke}).eq("id",s.id);if(ks)throw ks;xt(),o(),d.success("Price corrected")}catch(X){d.error(X.message)}finally{L(null)}},na=async()=>{L("return");try{if(!s.refund_request_id){d.error("No linked refund request — cannot return to Refunds Hub. Open a manual refund row instead.");return}const{data:t,error:x}=await j.from("refund_requests").update({status:"pending",program_swap_case_id:null}).eq("id",s.refund_request_id).select("id").maybeSingle();if(x)throw x;if(!t)throw new Error("Refund request not found or you do not have permission to update it. Program Swap case was NOT changed.");await Ts(s.id,s.raw_audit_json,{action:"returned_to_refund",refund_request_id:s.refund_request_id},{status:"returned_to_pending_refund",returned_to_refund_at:new Date().toISOString()}),o(),d.success("Returned to Refunds Hub (Pending)"),ye(!1),r()}catch(t){d.error(t.message)}finally{L(null)}},ia=async()=>{L("cancel");try{await Ts(s.id,s.raw_audit_json,{action:"cancelled"},{status:"cancelled",cancelled_at:new Date().toISOString()}),await Bt(s),o(),d.success("Case cancelled"),re(!1)}catch(t){d.error(t.message)}finally{L(null)}},oa=()=>Os({internal_notes:_e,notes:Ne},{action:"notes_updated"});return e.jsx(Ie,{open:!0,onOpenChange:t=>!t&&r(),children:e.jsxs(Fe,{className:"max-w-4xl max-h-[90vh] overflow-y-auto",children:[e.jsx(Le,{children:e.jsxs(Me,{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex flex-col",children:[e.jsx("span",{children:s.customer_name_display??s.customer_name??s.customer_email??"Program Swap case"}),e.jsx("span",{className:"text-xs font-normal text-muted-foreground",children:s.customer_email})]}),e.jsxs("div",{className:"flex items-center gap-2 pr-8",children:[rt(s.status),ie&&e.jsx("span",{className:"inline-flex items-center rounded-md bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground",children:"Reversed"})]})]})}),ie&&e.jsxs("div",{className:"rounded-md border border-border bg-muted/40 p-3 text-xs space-y-1",children:[e.jsxs("div",{className:"font-medium text-foreground",children:["Swap reversed on ",Pt(le==null?void 0:le.at),(()=>{var x;const t=(x=n.find(N=>N.id===(le==null?void 0:le.actor)))==null?void 0:x.name;return t?` by ${t}`:""})(),"."]}),(le==null?void 0:le.reason)&&e.jsxs("div",{className:"text-muted-foreground",children:["Reason: ",String(le.reason)]}),e.jsxs("div",{className:"text-muted-foreground",children:["Credit returned: ",e.jsx("strong",{children:W(Number((le==null?void 0:le.credit_returned)??0))}),we&&e.jsxs(e.Fragment,{children:[" · ","Customer's available balance:"," ",e.jsx("strong",{children:W(we.balance_amount)}),we.credit_note_expires_at?`, use by ${Re(we.credit_note_expires_at)}`:""]})]}),e.jsx("div",{className:"text-muted-foreground",children:"This case is locked. Re-allocation, provisioning and status changes are disabled. Rever
7sal emails are listed in the correspondence log below."})]}),e.jsxs("div",{className:"flex items-center justify-between gap-3 rounded-md border border-border bg-muted/20 p-2",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-wide text-muted-foreground",children:"Assigned to"}),e.jsx("div",{className:"w-56",children:e.jsxs(us,{value:s.assigned_to_user_id??"__none__",onValueChange:ea,children:[e.jsx(ps,{className:"h-8 text-xs",children:e.jsx(xs,{placeholder:"Unassigned"})}),e.jsxs(hs,{children:[e.jsx(ve,{value:"__none__",children:"Unassigned"}),n.map(t=>e.jsx(ve,{value:t.id,children:t.name},t.id))]})]})})]}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-3 gap-3",children:[e.jsx(Pe,{label:"Original product",children:s.original_product_name??"—"}),ze==="kajabi"&&!s.access_revoked_at&&e.jsx(Pe,{label:"Kajabi offer to be revoked",children:e.jsx(fr,{caseId:s.id,refreshKey:s.original_product_id})}),e.jsx(Pe,{label:"Source",children:s.original_source_platform??"—"}),e.jsx(Pe,{label:"Original amount",children:W(s.original_purchase_amount)}),e.jsxs(e.Fragment,{children:[s.original_purchase_amount==null||s.credit_note_amount==null?e.jsxs("div",{className:"col-span-2 md:col-span-3 rounded-md border border-amber-500/40 bg-amber-500/10 p-3 space-y-2",children:[e.jsxs("div",{className:"flex items-start gap-2 text-xs text-amber-800 dark:text-amber-300",children:[e.jsx(qe,{className:"h-4 w-4 shrink-0 mt-0.5"}),e.jsxs("span",{children:[e.jsx("strong",{children:"Original purchase amount missing"})," — enter it below to auto-calculate the credit note."]})]}),e.jsxs("div",{className:"flex items-end gap-2",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx(M,{className:"text-xs",children:"Original purchase amount (USD)"}),e.jsx(ee,{type:"number",min:"0",step:"0.01",value:G,onChange:t=>ge(t.target.value),placeholder:"0.00"})]}),e.jsx(S,{size:"sm",disabled:v==="save"||!Number(G),onClick:Wt,children:"Calculate & Save"})]})]}):e.jsxs(e.Fragment,{children:[e.jsx(Pe,{label:s.credit_note_issued_at?"Credit note amount (issued)":"Credit note amount (calculated, not yet issued)",children:W(s.credit_note_amount)}),e.jsx(Pe,{label:"Credit expires",children:Re(s.credit_note_expires_at)})]}),e.jsx(Pe,{label:"Replacement total",children:W(Be)}),e.jsx(Pe,{label:"Top-up due",children:W(bs)}),!ie&&e.jsx(Pe,{label:"Unused credit",children:W(it)}),we&&e.jsx(Pe,{label:"Current credit balance",children:e.jsxs("span",{className:"text-emerald-700 dark:text-emerald-300",children:[W(we.balance_amount),we.credit_note_expires_at?` (expires ${Re(we.credit_note_expires_at)})`:""]})}),b&&e.jsx(Pe,{label:"Prior credit balance (from an earlier swap)",children:e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{children:u?e.jsxs("span",{className:"text-emerald-700 dark:text-emerald-300",children:[W(u.balance_amount)," (expires ",Re(u.credit_note_expires_at),")"]}):"—"}),Gt&&e.jsx(S,{size:"sm",variant:"outline",className:"h-7 text-xs",onClick:()=>{m(Es.toFixed(2)),He(!0)},children:"Apply credit"})]})}),e.jsx(Pe,{label:"Prior credit applied",children:W(ws)})]})]}),e.jsx(rs,{open:gs,onOpenChange:He,children:e.jsxs(ns,{children:[e.jsxs(is,{children:[e.jsx(os,{children:"Apply prior credit to this swap"}),e.jsx(ds,{asChild:!0,children:e.jsxs("div",{className:"space-y-2 text-sm",children:[e.jsxs("div",{children:["Spendable balance ",W(Ks)," · shortfall ",W(bs),". The most that can be applied is ",W(Es),"."]}),s.top_up_stripe_invoice_id&&e.jsx("div",{className:"text-amber-700 dark:text-amber-300",children:"This will void the current invoice. You will need to send a new one."})]})})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(M,{className:"text-xs",children:"Amount to apply (USD)"}),e.jsx(ee,{type:"number",min:"0",step:"0.01",max:Es,value:Qe,onChange:t=>m(t.target.value)})]}),e.jsxs(cs,{children:[e.jsx(ls,{disabled:v==="apply_credit",children:"Cancel"}),e.jsx(ms,{disabled:v==="apply_credit",onClick:t=>{t.preventDefault(),Vt()},children:v==="apply_credit"?"Applying…":"Apply credit"})]})]})}),(()=>{const t=ze==="samcart"&&!!s.access_revoked_at&&!s.samcart_cancellation_outcome,x=!ie&&(i.length>0||s.status==="completed")&&!s.ghl_informed_at;return!t&&!x?null:e.jsxs("div",{className:"rounded-md border border-amber-500/40 bg-amber-500/10 p-3 text-xs space-y-1",children:[e.jsxs("div",{className:"flex items-center gap-2 font-medium text-amber-800 dark:text-amber-300",children:[e.jsx(qe,{className:"h-4 w-4"})," Outstanding manual steps"]}),e.jsxs("ul",{className:"list-disc pl-5 text-amber-800 dark:text-amber-300 space-y-0.5",children:[t&&e.jsx("li",{children:"SamCart cancellation not recorded — the original order may still be billing."}),x&&e.jsx("li",{children:"GoHighLevel not yet informed."})]})]})})(),e.jsx(Qa,{row:s,onChanged:o}),ie&&s.ghl_informed_at&&e.jsxs("div",{className:"rounded-md border border-amber-500/40 bg-amber-500/10 p-3 text-xs space-y-1",children:[e.jsxs("div",{className:"flex items-center gap-2 font-medium text-amber-800 dark:text-amber-300",children:[e.jsx(qe,{className:"h-4 w-4"})," GoHighLevel cleanup required"]}),e.jsx("p",{className:"text-amber-800 dark:text-amber-300",children:"GoHighLevel was informed of this swap before it was reversed. Remove the customer's tags or workflows for the cancelled program."})]}),!ie&&yt&&(i.length>0||s.status==="completed")&&e.jsx(tr,{row:s,onChanged:o}),!yt,!ie&&(s.status==="product_swapped"||s.status==="top_up_required"&&s.top_up_status==="paid"||s.status==="top_up_sent"&&s.top_up_status==="paid"||s.status==="credit_note_issued"&&s.top_up_status!=="pending"&&s.top_up_status!=="sent")&&e.jsx(er,{caseRow:s,onCompleted:o}),e.jsxs(je,{children:[e.jsx(De,{className:"pb-3",children:e.jsx(Ee,{className:"text-sm",children:"Workflow"})}),e.jsxs(be,{className:"space-y-4",children:[e.jsx(Hs,{number:1,title:ze==="samcart"?"Request access removal (order is not refunded)":`Cancel original product${ze?` in ${ze==="kajabi"?"Kajabi":"SamCart"}`:""}`,dim:!ze,done:!!s.access_revoked_at,children:ze==="samcart"?s.access_revoked_at?e.jsxs("div",{className:"text-xs text-emerald-700 dark:text-emerald-300",children:[e.jsx(Ae,{className:"h-3.5 w-3.5 inline mr-1"}),"Revocation emails sent ",Re(s.access_revoked_at),". We do not refund this order — the amount becomes the customer's credit. If it is a payment plan or subscription, cancel it in SamCart and record it in the Phase 1 panel above so it stops billing."]}):e.jsx("div",{className:"rounded-md border border-amber-500/40 bg-amber-500/10 p-2 text-xs text-amber-800 dark:text-amber-300",children:"Ask the speaker to remove access in their own system, then send the revocation request above. Never refund this order — the amount becomes the customer's credit note. Any recurring billing must be cancelled in SamCart separately and recorded above."}):ot?e.jsxs("div",{className:"text-xs text-emerald-700 dark:text-emerald-300",children:[e.jsx(Ae,{className:"h-3.5 w-3.5 inline mr-1"})," Cancelled on ",Re(ot)]}):e.jsxs(S,{size:"sm",disabled:v==="cancel_product"||!ze,onClick:Yt,children:[v==="cancel_product"&&e.jsx(Y,{className:"h-3.5 w-3.5 mr-1 animate-spin"}),"Cancel in ",ze==="kajabi"?"Kajabi":"—"]})}),e.jsx(Hs,{number:2,title:"Generate credit note",dim:!s.credit_note_amount,done:!!s.credit_note_issued_at,children:s.credit_note_issued_at?e.jsxs("div",{className:"text-xs text-emerald-700 dark:text-emerald-300",children:[e.jsx(Ae,{className:"h-3.5 w-3.5 inline mr-1"})," Credit note sent to ",s.customer_email," on ",Re(s.credit_note_issued_at)]}):e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"The value above is calculated automatically from the original purchase. This step generates the credit-note PDF, emails it to the customer, and activates the credit."}),e.jsxs(S,{size:"sm",disabled:v==="issue_credit_note"||!s.credit_note_amount||!s.access_revoked_at,onClick:Jt,children:[v==="issue_credit_note"&&e.jsx(Y,{className:"h-3.5 w-3.5 mr-1 animate-spin"}),"Generate & Email Credit Note"]}),!s.access_revoked_at&&e.jsx("div",{className:"text-xs text-muted-foreground",children:"Complete access revocation (Phase 1) first."})]})}),e.jsx(Hs,{number:3,title:"Send speaker grant requests",dim:!s.credit_note_issued_at,done:qs,children:(()=>{const t=vs.some(R=>(R==null?void 0:R.action)==="speaker_grant_requests_deferred_pending_topup"),x=vs.some(R=>(R==null?void 0:R.action)==="deferred_grants_sent_after_topup_paid");return t&&!x&&s.top_up_status==="paid"?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"rounded-md border border-emerald-500/40 bg-emerald-500/10 p-2 text-xs text-emerald-800 dark:text-emerald-200",children:"Top-up is paid. The speaker grant requests were held while the top-up was outstanding — send them now."}),e.jsxs(S,{size:"sm",disabled:v==="provision",onClick:Qt,children:[v==="provision"&&e.jsx(Y,{className:"h-3.5 w-3.5 mr-1 animate-spin"}),"Send speaker grant requests"]})]}):qs?e.jsxs("div",{className:"text-xs text-emerald-700 dark:text-emerald-300",children:[e.jsx(Ae,{className:"h-3.5 w-3.5 inline mr-1"})," Speaker grant requests sent"]}):e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Select replacement programs below, then click ",e.jsx("strong",{children:"Confirm & Provision All Replacements"})," to email each replacement product's speaker a grant-access request (logged in the correspondence log). This does ",e.jsx("strong",{children:"not"})," grant access automatically."," ",e.jsx("strong",{children:"If the replacement total exceeds the credit note, speaker grant requests are held until the top-up is paid"})," — pay-before-access. The case will wait at ",e.jsx("strong",{children:"Product Swapped"})," until an admin confirms the speaker granted access."]})})()}),(s.status==="top_up_required"||s.top_up_status==="pending"||s.top_up_status==="sent"||s.top_up_status==="void"||s.top_up_stripe_invoice_id||s.top_up_stripe_payment_link_url)&&e.jsxs(Hs,{number:4,title:"Collect top-up payment",dim:!1,done:s.top_up_status==="paid"||s.status==="completed",children:[!s.top_up_stripe_payment_link_url&&(s.top_up_stripe_invoice_id?e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"text-xs space-y-1",children:[s.top_up_invoice_number&&e.jsxs("div",{children:["Invoice: ",e.jsx("span",{className:"font-mono font-semibold",children:s.top_up_invoice_number})]}),s.top_up_invoice_hosted_url&&e.jsxs("div",{children:["Hosted payment page:"," ",e.jsxs("a",{href:s.top_up_invoice_hosted_url,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline inline-flex items-center gap-1 break-all",children:[s.top_up_invoice_hosted_url," ",e.jsx(Ns,{className:"h-3 w-3"})]})]}),s.top_up_invoice_pdf_url&&e.jsx("div",{children:e.jsxs("a",{href:s.top_up_invoice_pdf_url,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline inline-flex items-center gap-1",children:["Download invoice PDF ",e.jsx(Ns,{className:"h-3 w-3"})]})})]}),s.top_up_status==="void"&&e.jsxs("div",{className:"rounded-md border border-amber-300 bg-amber-50 dark:border-amber-800 dark:bg-amber-950/40 p-2 space-y-2",children:[e.jsx("div",{className:"text-xs text-amber-800 dark:text-amber-200",children:"Invoice was voided / marked uncollectible — the top-up is still owed."}),e.jsx(Tt,{caseId:s.id,label:`Prepare invoice — ${W(s.top_up_amount_due)}`,disabled:v!==null||!s.top_up_amount_due,onSent:o})]}),e.jsx(Ct,{row:s,onSaved:o,disabled:v!==null||s.top_up_status==="paid"}),e.jsx(At,{caseId:s.id,refreshKey:c}),s.top_up_status!=="paid"&&s.top_up_status!=="void"&&s.status!=="completed"&&e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(S,{size:"sm",variant:"outline",disabled:v==="topup_resend",onClick:Zt,children:[v==="topup_resend"&&e.jsx(Y,{className:"h-3.5 w-3.5 mr-1 animate-spin"}),"Resend payment email"]}),p&&e.jsx(Rt,{caseId:s.id,amountDue:s.top_up_amount_due,disabled:v!==null,onDone:ct})]}),(s.top_up_status==="paid"||s.status==="completed")&&e.jsxs("div",{className:"text-xs text-emerald-700 dark:text-emerald-300",children:[e.jsx(Ae,{className:"h-3.5 w-3.5 inline mr-1"})," Top-up paid ",s.top_up_paid_at?`on ${Re(s.top_up_paid_at)}`:""]})]}):e.jsxs("div",{className:"space-y-2",children:[e.jsx(Ct,{row:s,onSaved:o,disabled:v!==null}),e.jsx(Tt,{caseId:s.id,label:`Prepare invoice — ${W(s.top_up_amount_due)}`,disabled:v!==null||!s.top_up_amount_due,onSent:o})]})),s.top_up_stripe_payment_link_url&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"text-xs",children:[e.jsx("span",{className:"inline-block px-1.5 py-0.5 rounded bg-slate-100 dar
7k:bg-slate-800 text-slate-600 dark:text-slate-300 font-mono text-[10px] mr-2",children:"LEGACY LINK"}),"Payment link sent:"," ",e.jsxs("a",{href:s.top_up_stripe_payment_link_url,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline inline-flex items-center gap-1 break-all",children:[s.top_up_stripe_payment_link_url," ",e.jsx(Ns,{className:"h-3 w-3"})]})]}),(s.top_up_status==="expired"||s.top_up_status==="failed")&&e.jsx("div",{className:"rounded-md border border-amber-300 bg-amber-50 dark:border-amber-800 dark:bg-amber-950/40 p-2 space-y-2",children:e.jsx("div",{className:"text-xs text-amber-800 dark:text-amber-200",children:s.top_up_status==="expired"?"The Stripe Checkout session for this payment link expired before the customer paid. The top-up is still owed.":"The customer's payment on this link failed. The top-up is still owed."})}),e.jsx(At,{caseId:s.id,refreshKey:c}),s.top_up_status!=="paid"&&s.status!=="completed"&&p&&e.jsx("div",{className:"flex flex-wrap gap-2",children:e.jsx(Rt,{caseId:s.id,amountDue:s.top_up_amount_due,disabled:v!==null,onDone:ct})}),(s.top_up_status==="paid"||s.status==="completed")&&e.jsxs("div",{className:"text-xs text-emerald-700 dark:text-emerald-300",children:[e.jsx(Ae,{className:"h-3.5 w-3.5 inline mr-1"})," Top-up paid ",s.top_up_paid_at?`on ${Re(s.top_up_paid_at)}`:""]})]})]})]})]}),e.jsxs(je,{children:[e.jsx(De,{className:"pb-3",children:e.jsx(Ee,{className:"text-sm",children:"Replacement products"})}),e.jsxs(be,{className:"space-y-3",children:[O?e.jsxs("div",{className:"text-xs text-muted-foreground",children:[e.jsx(Y,{className:"h-3 w-3 animate-spin inline mr-1"})," Loading…"]}):i.length===0?e.jsx("div",{className:"text-xs text-muted-foreground italic",children:"No replacement products selected yet."}):e.jsx("ul",{className:"divide-y divide-border rounded-md border border-border",children:i.map(t=>e.jsxs("li",{className:"p-2 flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:`text-sm font-medium ${ie?"line-through text-muted-foreground":""}`,children:t.product_name}),ie&&e.jsx("div",{className:"text-[11px] font-medium text-muted-foreground",children:"Cancelled — swap reversed"}),e.jsx("div",{className:"text-xs text-muted-foreground",children:W(t.product_price)}),t.notes&&e.jsx("div",{className:"text-[11px] text-amber-700 dark:text-amber-300 mt-0.5 whitespace-pre-wrap break-words",children:t.notes})]}),!es&&e.jsxs("div",{className:"flex items-center gap-1",children:[lt!==t.id&&e.jsx(S,{size:"sm",variant:"ghost",onClick:()=>aa(t),children:"Edit price"}),e.jsx(S,{size:"sm",variant:"ghost",disabled:v===`rm_${t.id}`,onClick:()=>ta(t.id),children:e.jsx(Ft,{className:"h-3.5 w-3.5"})})]})]}),lt===t.id&&!es&&e.jsxs("div",{className:"rounded-md border border-primary/30 bg-primary/5 p-2 space-y-2",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-[140px_1fr_auto_auto] gap-2 items-start",children:[e.jsxs("div",{children:[e.jsx(M,{className:"text-[11px]",children:"New price"}),e.jsx(ee,{type:"number",step:"0.01",min:"0",value:ut,onChange:x=>Vs(x.target.value),className:"h-8"})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-[11px]",children:"Reason (required)"}),e.jsx(ee,{value:pt,onChange:x=>Ws(x.target.value),placeholder:"e.g. coupon JOURNEY100 applied, catalog was wrong",className:"h-8"})]}),e.jsx("div",{className:"pt-4",children:e.jsx(S,{size:"sm",disabled:v===`edit_${t.id}`,onClick:()=>ra(t),children:v===`edit_${t.id}`?e.jsx(Y,{className:"h-3 w-3 animate-spin"}):"Save"})}),e.jsx("div",{className:"pt-4",children:e.jsx(S,{size:"sm",variant:"ghost",onClick:xt,children:"Cancel"})})]}),e.jsxs("div",{className:"text-[11px] text-muted-foreground",children:["Recorded as ",e.jsx("span",{className:"font-mono",children:"replacement_price_corrected"})," in the case audit trail. Blocked once adjustments are written."]})]})]},t.id))}),es&&e.jsxs("div",{className:"text-[11px] text-muted-foreground italic",children:["Item prices are frozen — ",ie?"this 
7swap has been reversed":s.status==="completed"?"case is completed":`${zs} adjustment${zs===1?"":"s"} already written`,"."]}),!K&&!es&&e.jsx("div",{children:e.jsxs("button",{type:"button",className:"text-xs text-primary hover:underline inline-flex items-center gap-1",onClick:()=>U(!0),children:[e.jsx(Nt,{className:"h-3.5 w-3.5"}),i.length===0?"Add a replacement product":"Add another product"]})}),K&&!es&&e.jsxs("div",{className:"space-y-2 rounded-md border border-border p-3 bg-muted/20",children:[e.jsx("div",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:"Add replacement program / offer"}),e.jsxs("div",{className:"grid sm:grid-cols-2 gap-2",children:[e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Speaker"}),e.jsxs(us,{value:E,onValueChange:_,children:[e.jsx(ps,{children:e.jsx(xs,{placeholder:"Select speaker…"})}),e.jsx(hs,{className:"max-h-[300px]",children:A.map(t=>e.jsx(ve,{value:t.id,children:t.name},t.id))})]})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Replacement program / offer"}),E?q?e.jsxs("div",{className:"h-9 px-3 flex items-center text-xs text-muted-foreground border border-input rounded-md bg-background",children:[e.jsx(Y,{className:"h-3 w-3 animate-spin mr-2"})," Loading active programs…"]}):e.jsxs("div",{className:"border border-input rounded-md bg-background p-2 space-y-1 max-h-64 overflow-y-auto",children:[e.jsx(ee,{placeholder:"Search by ID or name…",value:pe,onChange:t=>I(t.target.value),className:"h-7 text-xs sticky top-0 z-10"}),(()=>{const t=pe.trim().toLowerCase(),x=t?g.filter(z=>(z.external_id||"").toLowerCase().includes(t)||(z.name||"").toLowerCase().includes(t)||z.id.toLowerCase().includes(t)):g;if(x.length===0)return e.jsx("p",{className:"text-xs text-muted-foreground px-1 py-2",children:g.length===0?"No active programs for this speaker":"No matches"});const N=x.filter(z=>z.source_platform==="kajabi"),R=x.filter(z=>z.source_platform==="samcart"),B=z=>{const X=`${z.source_platform}:${z.id}`,ue=w===X;return e.jsxs("button",{type:"button",onClick:()=>$(X),className:`w-full text-left text-xs px-2 py-1.5 rounded border flex items-center gap-2 transition-colors ${ue?"border-primary bg-primary/10":"bg-background hover:border-primary hover:bg-primary/5 curs
7or-pointer"}`,children:[e.jsx($a,{className:"h-3 w-3 text-primary flex-shrink-0"}),e.jsxs("span",{className:"truncate flex-1",children:[z.external_id&&e.jsxs("span",{className:"text-muted-foreground font-mono mr-1",children:["#",z.external_id]}),z.name]}),z.price!=null&&e.jsx("span",{className:"text-[10px] tabular-nums text-muted-foreground ml-auto",children:W(z.price)})]},X)};return e.jsxs(e.Fragment,{children:[N.length>0&&e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-[10px] font-semibold text-muted-foreground uppercase tracking-wider pt-1 pb-0.5 border-b border-border mb-1",children:"Kajabi Offers"}),N.map(B)]}),R.length>0&&e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-[10px] font-semibold text-muted-foreground uppercase tracking-wider pt-2 pb-0.5 border-b border-border mb-1",children:"SamCart Products"}),R.map(B)]})]})})()]}):e.jsx("div",{className:"h-9 px-3 flex items-center text-xs text-muted-foreground border border-input rounded-md bg-background",children:"Pick a speaker first"})]})]}),fe&&e.jsxs("div",{className:"rounded-md bg-background border border-border p-2 text-xs space-y-1",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("div",{className:"font-medium text-sm",children:fe.name}),e.jsx("div",{className:"tabular-nums",children:W(fe.price)})]}),e.jsxs("div",{className:"flex flex-wrap gap-x-3 gap-y-0.5 text-[11px] text-muted-foreground",children:[e.jsxs("span",{children:[e.jsxs("span",{className:"uppercase tracking-wide",children:[fe.source_platform==="kajabi"?"Kajabi":"SamCart"," ID:"]})," ",e.jsx("span",{className:"font-mono",children:fe.external_id??"—"})]}),e.jsxs("span",{children:["Last ordered: ",e.jsx("strong",{className:"text-foreground",children:Re(fe.last_ordered_at)})]})]}),fe.description?e.jsx("div",{className:"text-muted-foreground whitespace-pre-wrap line-clamp-6",children:fe.description}):e.jsx("div",{className:"text-muted-foreground italic",children:"No description on file."})]}),fe&&e.jsx("div",{className:"rounded-md border border-border p-2 bg-background/60 text-xs space-y-2",children:C?e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("div",{className:"font-medium",children:"Price override (coupon / swap offer)"}),e.jsx("button",{type:"button",className:"text-muted-foreground hover:underline",onClick:()=>{H(!1),ae(""),ne(""),ce(!1)},children:"Cancel override"})]}),e.jsxs("div",{className:"grid sm:grid-cols-2 gap-2",children:[e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Override price (USD)"}),e.jsx(ee,{type:"number",step:"0.01",min:"0",value:Q,onChange:t=>{ae(t.target.value),ce(!1)},className:"h-8"}),e.jsxs("div",{className:"text-[11px] text-muted-foreground mt-0.5",children:["Catalog: ",W(fe.price)]})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Reason (required)"}),e.jsx(ee,{value:te,onChange:t=>ne(t.target.value),placeholder:"e.g. coupon JOURNEY100 — swap offer $197",className:"h-8"})]})]}),fe.price!=null&&Number(Q)>fe.price&&e.jsxs("label",{className:"flex items-start gap-2 text-[11px] text-amber-700 dark:text-amber-300",children:[e.jsx("input",{type:"checkbox",className:"mt-0.5",checked:de,onChange:t=>ce(t.target.checked)}),e.jsxs("span",{children:["Charging above catalog price (",W(fe.price),") — I confirm this is intentional."]})]})]}):e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"text-muted-foreground",children:["Effective price: ",e.jsx("strong",{className:"text-foreground tabular-nums",children:W(fe.price)})," ",e.jsx("span",{className:"text-muted-foreground",children:"(catalog)"})]}),e.jsx("button",{type:"button",className:"text-primary hover:underline",onClick:()=>{H(!0),ae(fe.price!=null?String(fe.price):""),ne(""),ce(!1)},children:"Adjust price (coupon)"})]})}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(S,{size:"sm",variant:"ghost",disabled:v==="add_item",onClick:()=>{_(""),$(""),I(""),H(!1),ae(""),ne(""),ce(!1),i.length>0&&U(!1)},children:"Cancel"}),e.jsxs(S,{size:"sm",variant:"outline",disabled:v==="add_item"||!fe,onClick:sa,children:[e.jsx(Nt,{className:"h-3.5 w-3.5 mr-1"})," Save"]})]})]}),Be>0&&e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Replacement total: ",e.jsx("strong",{children:W(Be)}),ie?e.jsx(e.Fragment,{children:" · Cancelled — swap reversed"}):e.jsxs(e.Fragment,{children:[" · ",bs>0?e.jsxs(e.Fragment,{children:["Top-up due: ",e.jsx("strong",{children:W(bs)})]}):e.jsxs(e.Fragment,{children:["Unused credit: ",e.jsx("strong",{children:W(it)})," (not cash-refundable, expires with credit note)"]})]})]}),i.length>0&&!ie&&e.jsx("div",{className:"pt-2 border-t border-border flex justify-end",children:e.jsxs(S,{size:"sm",disabled:v==="provision"||!s.credit_note_issued_at||qs,onClick:Xt,title:s.credit_note_issued_at?qs?"Replacements already provisioned.":void 0:"Issue the credit note first (Workflow step 2).",children:[v==="provision"&&e.jsx(Y,{className:"h-3.5 w-3.5 mr-1 animate-spin"}),"Confirm & Provision All Replacements"]})})]})]}),e.jsxs(je,{children:[e.jsx(De,{className:"pb-3",children:e.jsx(Ee,{className:"text-sm",children:"Notes"})}),e.jsxs(be,{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Internal notes (admin/management only)"}),e.jsx(Ze,{value:_e,onChange:t=>xe(t.target.value),rows:3})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-xs",children:"Customer-visible notes"}),e.jsx(Ze,{value:Ne,onChange:t=>Z(t.target.value),rows:3})]}),e.jsx(S,{size:"sm",variant:"outline",disabled:v==="save",onClick:oa,children:"Save notes"})]})]}),e.jsx(ft,{children:e.jsxs(je,{children:[e.jsx(_t,{asChild:!0,children:e.jsx(De,{className:"pb-3 cursor-pointer",children:e.jsxs(Ee,{className:"text-sm flex items-center justify-between",children:[e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx(Ta,{className:"h-4 w-4"})," Case actions"]}),e.jsx(gt,{className:"h-4 w-4 text-muted-foreground"})]})})}),e.jsx(jt,{children:e.jsx(be,{className:"space-y-3",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-wide text-muted-foreground",children:"Destructive case actions"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(S,{size:"sm",variant:"outline",className:"border-amber-500/40 text-amber-800 dark:text-amber-300 hover:bg-amber-500/10",disabled:!!v,onClick:()=>
7oe(!0),title:"Bypass the normal replacement/top-up flow and mark this case completed",children:"Force-complete case"}),e.jsx(S,{size:"sm",variant:"outline",className:"border-rose-500/40 text-rose-700 hover:bg-rose-500/10 dark:text-rose-300",disabled:!!v,onClick:()=>ye(!0),children:"Return to pending refund"}),e.jsx(S,{size:"sm",variant:"outline",className:"border-destructive/40 text-destructive hover:bg-destructive/10",disabled:!!v,onClick:()=>re(!0),children:"Cancel program swap"})]}),e.jsxs("div",{className:"text-[11px] text-muted-foreground leading-snug space-y-1",children:[e.jsxs("div",{children:[e.jsx("strong",{children:"Force-complete case"})," — closes the case bypassing the credit note / replacement / top-up flow. Only for cases resolved outside the automated pipeline."]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Return to pending refund"})," — abandons the swap and reopens the case in the Refunds Hub as an ordinary refund."]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Cancel program swap"})," — terminates this swap case; nothing is reopened."]})]})]})})})]})}),e.jsx(ft,{children:e.jsxs(je,{className:"border-dashed",children:[e.jsx(_t,{asChild:!0,children:e.jsx(De,{className:"pb-3 cursor-pointer",children:e.jsxs(Ee,{className:"text-sm flex items-center justify-between",children:[e.jsxs("span",{className:"inline-flex items-center gap-2",children:["Activity log",e.jsx(Se,{variant:"outline",className:"text-[10px] uppercase tracking-wide",children:"debug · temporary"}),e.jsxs("span",{className:"text-xs font-normal text-muted-foreground",children:["(",vs.length,")"]})]}),e.jsx(gt,{className:"h-4 w-4 text-muted-foreground"})]})})}),e.jsx(jt,{children:e.jsxs(be,{className:"space-y-2",children:[vs.length===0?e.jsx("div",{className:"text-xs text-muted-foreground italic",children:"No activity recorded yet."}):e.jsx("ol",{className:"space-y-2",children:[...vs].map((t,x)=>({entry:t,idx:x})).sort((t,x)=>{var B,z;const N=new Date(((B=t.entry)==null?void 0:B.at)??0).getTime();return new Date(((z=x.entry)==null?void 0:z.at)??0).getTime()-N}).map(({entry:t,idx:x})=>{const N=_r(t),R=N.tone==="success"?"border-emerald-500/40":N.tone==="warn"?"border-amber-500/40":N.tone==="error"?"border-destructive/50":"border-border",B=N.tone==="error"?"text-destructive":N.tone==="warn"?"text-amber-700 dark:text-amber-300":N.tone==="success"?"text-emerald-700 dark:text-emerald-300":"text-foreground",z=new Set(["at","action","actor"]),X={};return Object.keys(t??{}).forEach(ue=>{z.has(ue)||(X[ue]=t[ue])}),e.jsxs("li",{className:`rounded-md border ${R} bg-muted/20 p-2 text-xs space-y-1`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:`font-medium ${B}`,children:N.title}),e.jsx("span",{className:"font-mono text-[10px] text-muted-foreground",children:Pt(t==null?void 0:t.at)})]}),N.detail&&e.jsx("div",{className:"text-muted-foreground",children:N.detail}),(t==null?void 0:t.actor)&&e.jsxs("div",{className:"text-[10px] text-muted-foreground",children:["actor: ",e.jsx("span",{className:"font-mono",children:String(t.actor)})]}),Object.keys(X).length>0&&e.jsxs("details",{children:[e.jsx("summary",{className:"text-[10px] text-muted-foreground cursor-pointer",children:"payload"}),e.jsx("pre",{className:"mt-1 text-[10px] bg-background border border-border rounded p-1 overflow-x-auto",children:JSON.stringify(X,null,2)})]})]},x)})}),e.jsx("div",{className:"text-[10px] text-muted-foreground italic pt-1 border-t border-border",children:"Temporary admin debug panel — remove when no longer needed."})]})})]})}),e.jsxs(je,{children:[e.jsx(De,{className:"pb-3",children:e.jsx(Ee,{className:"text-sm",children:"Linked records"})}),e.jsxs(be,{className:"text-sm space-y-2",children:[s.refund_request_id?e.jsxs("div",{children:["Original refund request:"," ",e.jsxs($s,{to:`/admin/refunds?case=${s.refund_request_id}`,className:"text-primary hover:underline inline-flex items-center gap-1",children:[s.refund_request_id.slice(0,8),"… ",e.jsx(Ns,{className:"h-3 w-3"})]})]}):e.jsx("div",{className:"text-xs text-muted-foreground italic",children:"No linked refund request."}),s.original_order_id&&e.jsxs("div",{className:"text-xs",children:["Original order: ",e.jsx("code",{children:s.original_order_id})]})]})]}),e.jsxs(je,{children:[e.jsx(De,{className:"pb-3",children:e.jsx(Ee,{className:"text-sm",children:"Audit trail"})}),e.jsx(be,{children:e.jsx("pre",{className:"text-[11px] bg-muted/40 rounded p-3 overflow-x-auto max-h-64",children:JSON.stringify(s.raw_audit_json??[],null,2)})})]}),e.jsx(rs,{open:me,onOpenChange:oe,children:e.jsxs(ns,{children:[e.jsxs(is,{children:[e.jsx(os,{children:"Force-complete this Program Swap case?"}),e.jsxs(ds,{children:["This bypasses the normal replacement/top-up flow and marks the case as",e.
7jsx("strong",{children:" completed"}),". Use only when the case is genuinely resolved outside the automated pipeline — for example, a manual fulfilment that happened before the swap system was in place, or a case being closed after out-of-band cleanup.",e.jsx("div",{className:"mt-2 text-xs",children:"Everyday completions should go through the workflow: revoke access → credit note → replacement grant-request → speaker confirmation."})]})]}),e.jsxs(cs,{children:[e.jsx(ls,{disabled:v==="save",children:"Cancel"}),e.jsx(ms,{className:"bg-amber-600 text-white hover:bg-amber-700",disabled:v==="save",onClick:t=>{t.preventDefault(),oe(!1),Os({status:"completed",completed_at:new Date().toISOString()},{action:"completed_manual"})},children:"Force-complete"})]})]})}),e.jsx(rs,{open:se,onOpenChange:ye,children:e.jsxs(ns,{children:[e.jsxs(is,{children:[e.jsx(os,{children:"Return to pending refund?"}),e.jsxs(ds,{children:["The original refund request will be set back to ",e.jsx("strong",{children:"pending"})," and reappear in Incoming Refunds. This Program Swap case will remain linked for audit and its notes will be preserved. No financial action is taken."]})]}),e.jsxs(cs,{children:[e.jsx(ls,{disabled:v==="return",children:"Keep here"}),e.jsx(ms,{onClick:t=>{t.preventDefault(),na()},disabled:v==="return",children:v==="return"?e.jsxs(e.Fragment,{children:[e.jsx(Y,{className:"h-3 w-3 animate-spin mr-1"}),"Returning…"]}):"Return to refund"})]})]})}),e.jsx(rs,{open:P,onOpenChange:re,children:e.jsxs(ns,{children:[e.jsxs(is,{children:[e.jsx(os,{children:"Cancel this Program Swap case?"}),e.jsx(ds,{children:"This marks the case as cancelled. The linked refund request is left as-is."})]}),e.jsxs(cs,{children:[e.jsx(ls,{disabled:v==="cancel",children:"Keep open"}),e.jsx(ms,{className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",onClick:t=>{t.preventDefault(),ia()},disabled:v==="cancel",children:v==="cancel"?e.jsxs(e.Fragment,{children:[e.jsx(Y,{className:"h-3 w-3 animate-spin mr-1"}),"Cancelling…"]}):"Cancel case"})]})]})})]})})}function Pe({label:s,children:n}){return e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-wide text-muted-foreground",children:s}),e.jsx("div",{className:"text-sm font-medium mt-0.5",children:n})]})}function Hs({number:s,title:n,dim:r,done:o,children:h}){return e.jsxs("div",{className:`rounded-md border p-3 transition-opacity ${r?"opacity-50":"opacity-100"} ${o?"border-emerald-500/40 bg-emerald-500/5":"border-border"}`,children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx("div",{className:`h-5 w-5 shrink-0 rounded-full flex items-center justify-center text-[11px] font-semibold ${o?"bg-emerald-500 text-white":"bg-muted text-muted-foreground"}`,children:o?e.jsx(Ae,{className:"h-3 w-3"}):s}),e.jsx("div",{className:"text-xs font-semibold",children:n})]}),e.jsx("div",{className:"pl-7",children:h})]})}export{Ir 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.