import { env } from "cloudflare:workers";
const encoder=new TextEncoder();
export const uid=(prefix="")=>prefix+crypto.randomUUID();
export function db(){if(!env.DB)throw new Error("Database is not configured");return env.DB}
export function jsonError(message:string,status=400){return Response.json({error:message},{status})}
export async function sha256(value:string){const out=await crypto.subtle.digest("SHA-256",encoder.encode(value));return [...new Uint8Array(out)].map(x=>x.toString(16).padStart(2,"0")).join("")}
export async function hashPassword(password:string,salt:string){const key=await crypto.subtle.importKey("raw",encoder.encode(password),"PBKDF2",false,["deriveBits"]);const bits=await crypto.subtle.deriveBits({name:"PBKDF2",hash:"SHA-256",salt:encoder.encode(salt),iterations:210000},key,256);return [...new Uint8Array(bits)].map(x=>x.toString(16).padStart(2,"0")).join("")}
export async function requireAdmin(request:Request){const cookie=request.headers.get("cookie")||"";const token=cookie.match(/(?:^|; )ofm_admin=([^;]+)/)?.[1];if(!token)return null;const tokenHash=await sha256(decodeURIComponent(token));return db().prepare("SELECT a.id,a.email,a.name,a.role FROM admin_sessions s JOIN admins a ON a.id=s.admin_id WHERE s.token_hash=? AND s.expires_at>datetime('now') AND a.active=1").bind(tokenHash).first<{id:string,email:string,name:string,role:string}>()}
export async function createStripeCheckout(args:{paymentId:string,amount:number,currency:string,email:string,name:string,purpose:string,registrationId?:string}){const secret=(env as unknown as Record<string,string>).STRIPE_SECRET_KEY;if(!secret)return null;const origin=(env as unknown as Record<string,string>).PUBLIC_APP_URL||"http://localhost:3000";const body=new URLSearchParams({mode:"payment",success_url:`${origin}/payment/success?session_id={CHECKOUT_SESSION_ID}`,cancel_url:`${origin}/${args.purpose==="support"?"support":"register"}?payment=cancelled`,customer_email:args.email,"line_items[0][price_data][currency]":args.currency.toLowerCase(),"line_items[0][price_data][product_data][name]":args.purpose==="support"?"Conference Support":"Conference Registration","line_items[0][price_data][unit_amount]":String(Math.round(args.amount*100)),"line_items[0][quantity]":"1","metadata[payment_id]":args.paymentId,"metadata[purpose]":args.purpose,"metadata[registration_id]":args.registrationId||""});const res=await fetch("https://api.stripe.com/v1/checkout/sessions",{method:"POST",headers:{Authorization:`Bearer ${secret}`,"Content-Type":"application/x-www-form-urlencoded","Idempotency-Key":args.paymentId},body});if(!res.ok)throw new Error("Stripe Checkout could not be created");return res.json() as Promise<{id:string,url:string}>}
export async function sendCommunication(channel:string,recipient:string,subject:string,body:string){const cfg=env as unknown as Record<string,string>;if(channel==="email"&&cfg.RESEND_API_KEY){const r=await fetch("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${cfg.RESEND_API_KEY}`,"Content-Type":"application/json"},body:JSON.stringify({from:cfg.EMAIL_FROM||"Conference <conference@example.org>",to:[recipient],subject,html:`<div style=\"font-family:Arial;max-width:620px;margin:auto\"><div style=\"background:#8f1020;color:white;padding:25px\"><b>OMEGA FIRE MINISTRIES</b></div><div style=\"padding:30px;border:1px solid #eee\">${body.replace(/\n/g,"<br>")}</div></div>`})});return {ok:r.ok,id:r.ok?String((await r.json() as {id?:string}).id||""):"",error:r.ok?"":await r.text()}}
 if(channel==="sms"&&cfg.TWILIO_ACCOUNT_SID){const data=new URLSearchParams({To:recipient,From:cfg.TWILIO_FROM_NUMBER,Body:body});const r=await fetch(`https://api.twilio.com/2010-04-01/Accounts/${cfg.TWILIO_ACCOUNT_SID}/Messages.json`,{method:"POST",headers:{Authorization:`Basic ${btoa(`${cfg.TWILIO_ACCOUNT_SID}:${cfg.TWILIO_AUTH_TOKEN}`)}`},body:data});const out=await r.json() as {sid?:string,message?:string};return {ok:r.ok,id:out.sid||"",error:r.ok?"":out.message||"Provider error"}}
 if(channel==="whatsapp"&&cfg.WHATSAPP_PHONE_NUMBER_ID){const r=await fetch(`https://graph.facebook.com/v21.0/${cfg.WHATSAPP_PHONE_NUMBER_ID}/messages`,{method:"POST",headers:{Authorization:`Bearer ${cfg.WHATSAPP_ACCESS_TOKEN}`,"Content-Type":"application/json"},body:JSON.stringify({messaging_product:"whatsapp",to:recipient,type:"template",template:{name:cfg.WHATSAPP_DEFAULT_TEMPLATE||"conference_update",language:{code:"en_US"}}})});const out=await r.json() as {messages?:{id:string}[]};return {ok:r.ok,id:out.messages?.[0]?.id||"",error:r.ok?"":"WhatsApp provider error"}}
 return {ok:false,id:"",error:`${channel} provider is not configured`}}
