export type AppRole = "director" | "manager";
export type AppSession = { username: string; role: AppRole; name: string; exp: number };
const encoder=new TextEncoder(),cookieName="jlbb_session";
const fallback={AUTH_DIRECTOR_USER:"andika0001",AUTH_DIRECTOR_PASSWORD_HASH:"c0a9fe33e185cb245bfef84766a3899710d61fb26bcc90e4095e7a81a9a22562",AUTH_MANAGER_USER:"manager0001",AUTH_MANAGER_PASSWORD_HASH:"612bc5d30158f2db58317f740d85f0a35822334b04626bf58d9c784f0f802414",AUTH_SESSION_SECRET:"jlbb-change-this-session-secret"};
function setting(key:keyof typeof fallback){return process.env[key]||fallback[key]}function hex(bytes:ArrayBuffer){return[...new Uint8Array(bytes)].map(x=>x.toString(16).padStart(2,"0")).join("")}async function sha(v:string){return hex(await crypto.subtle.digest("SHA-256",encoder.encode(v)))}function b64(v:string){return Buffer.from(v,"utf8").toString("base64url")}function unb64(v:string){return Buffer.from(v,"base64url").toString("utf8")}async function sign(v:string){const key=await crypto.subtle.importKey("raw",encoder.encode(setting("AUTH_SESSION_SECRET")),{name:"HMAC",hash:"SHA-256"},false,["sign"]);return hex(await crypto.subtle.sign("HMAC",key,encoder.encode(v)))}
export async function authenticate(username:string,password:string):Promise<AppSession|null>{const users=[{username:setting("AUTH_DIRECTOR_USER"),hash:setting("AUTH_DIRECTOR_PASSWORD_HASH"),role:"director" as const,name:"Andika Pratama"},{username:setting("AUTH_MANAGER_USER"),hash:setting("AUTH_MANAGER_PASSWORD_HASH"),role:"manager" as const,name:"Manager Keuangan"}],user=users.find(x=>x.username===username);if(!user||await sha(`${username}:${password}`)!==user.hash)return null;return{username,role:user.role,name:user.name,exp:Date.now()+28800000}}
export async function sessionCookie(s:AppSession){const p=b64(JSON.stringify(s));return`${cookieName}=${p}.${await sign(p)}; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=28800`}export function clearSessionCookie(){return`${cookieName}=; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=0`}export async function getSession(request:Request):Promise<AppSession|null>{const raw=request.headers.get("cookie")?.split(";").map(x=>x.trim()).find(x=>x.startsWith(`${cookieName}=`))?.slice(cookieName.length+1);if(!raw)return null;const i=raw.lastIndexOf(".");if(i<0)return null;const p=raw.slice(0,i);if(await sign(p)!==raw.slice(i+1))return null;try{const s=JSON.parse(unb64(p)) as AppSession;return s.exp>Date.now()?s:null}catch{return null}}export async function requireSession(request:Request,role?:AppRole){const session=await getSession(request);if(!session)return{response:Response.json({error:"Sesi berakhir. Silakan masuk kembali."},{status:401})};if(role&&session.role!==role)return{response:Response.json({error:"Akun ini tidak memiliki wewenang untuk tindakan tersebut."},{status:403})};return{session}}
