import {trialDuration,trialBillingDate,trialBillingTime} from '@/lib/membership';
import {headers} from 'next/headers';
import {identityFromHeaders} from '@/lib/identity';
import {database} from '@/db/store';
import {paymentConfig,paymentOwner,paymentResponse} from '@/lib/payment-config';
import {paymentPlans,paymentOrigin,signature,nextMonth,sameOrigin,type Plan} from '@/lib/payfast';
export async function POST(request:Request){const user=await identityFromHeaders(await headers());if(!user)return paymentResponse({error:'Please sign in before subscribing.'},401);if(!sameOrigin(request))return paymentResponse({error:'Please start checkout from Sovereign.'},403);try{const data:any=await request.json();if(!Object.hasOwn(paymentPlans,data.plan)||data.consent!==true)return paymentResponse({error:'Choose a plan and agree to the monthly subscription.'},400);const plan=data.plan as Plan,c=await paymentConfig();if(!c?.enabled||c.mode==='sandbox'&&user.email!==paymentOwner)return paymentResponse({error:'Payfast checkout is being connected. Please try again later.'},503);const db=database();if(plan==='affiliate'){const approved=await db.prepare("SELECT id FROM enrolments WHERE user_email=? AND kind='affiliate' AND status='approved'").bind(user.email).first();if(!approved)return paymentResponse({error:'Submit your business application and wait for approval before subscribing.'},403);}const existing=await db.prepare("SELECT id,status,token,created_at FROM payment_subscriptions WHERE user_email=? AND plan=? AND mode=? AND status IN ('active','pending') ORDER BY created_at DESC LIMIT 1").bind(user.email,plan,c.mode).first<{id:string;status:string;token:string|null;created_at:number}>();if(existing?.status==='active'||existing?.token)return paymentResponse({error:'You already have this subscription. Manage it below before subscribing again.'},409);if(existing?.status==='pending'&&Date.now()-existing.created_at<30*60*1000)return paymentResponse({error:'A checkout is already pending. Wait for confirmation, or try again after 30 minutes.'},409);const id=crypto.randomUUID(),now=new Date();let trialEnd:number|null=null;if(plan==='personal'){const trial=await db.prepare('SELECT ends_at FROM membership_trials WHERE user_email=?').bind(user.email).first<{ends_at:number}>();trialEnd=trial?.ends_at||now.getTime()+trialDuration;}const priorTrialCard=plan==='personal'?await db.prepare("SELECT id FROM payment_subscriptions WHERE user_email=? AND plan='personal' AND mode=? AND amount_cents=0 LIMIT 1").bind(user.email,c.mode).first():null;const freeSetup=trialEnd!==null&&(trialEnd>now.getTime()||priorTrialCard&&trialBillingTime(trialEnd)>now.getTime());const initialCents=freeSetup?0:paymentPlans[plan].cents;if(existing)await db.prepare("UPDATE payment_subscriptions SET status='expired' WHERE id=? AND status='pending'").bind(existing.id).run();const insert=db.prepare('INSERT INTO payment_subscriptions(id,user_email,plan,mode,amount_cents,created_at) VALUES(?,?,?,?,?,?)').bind(id,user.email,plan,c.mode,initialCents,now.getTime());if(plan==='personal')await db.batch([db.prepare('INSERT OR IGNORE INTO membership_trials(user_email,started_at,ends_at) VALUES(?,?,?)').bind(user.email,now.getTime(),trialEnd),insert]);else await insert.run();const fields:Record<string,string>={merchant_id:c.merchantId,merchant_key:c.merchantKey,return_url:paymentOrigin+'/?payment=return',cancel_url:paymentOrigin+'/?payment=cancel',notify_url:paymentOrigin+'/api/payments/notify',email_address:user.email,m_payment_id:id,amount:(initialCents/100).toFixed(2),item_name:paymentPlans[plan].name,item_description:freeSetup?'30-day free trial. R99.99 monthly afterwards unless cancelled.':'Monthly subscription. Renews until cancelled.',subscription_type:'1',billing_date:freeSetup?trialBillingDate(trialEnd!):nextMonth(now).toISOString().slice(0,10),recurring_amount:(paymentPlans[plan].cents/100).toFixed(2),frequency:'3',cycles:'0',subscription_notify_buyer:'true'};fields.signature=signature(Object.entries(fields),c.passphrase);return paymentResponse({action:`https://${c.mode==='sandbox'?'sandbox':'www'}.payfast.co.za/eng/process`,fields});}catch{return paymentResponse({error:'Checkout could not be started. Please retry.'},503);}}
