export type AuthUser={id:string;email?:string;phone?:string;phone_confirmed_at?:string;email_confirmed_at?:string;user_metadata?:Record<string,unknown>};
export type AuthSession={access_token:string;refresh_token:string;expires_in:number;user:AuthUser};
export function isAuthUser(value:unknown):value is AuthUser{
 const user=value as Partial<AuthUser>|null;
 return !!user&&typeof user.id==='string'&&(!user.email||typeof user.email==='string')&&(!user.phone||typeof user.phone==='string');
}
const REMEMBER_SECONDS=30*24*60*60;
export function cookieValue(request:Request,name:string){
 const value=request.headers.get('cookie')?.split(';').map(v=>v.trim()).find(v=>v.startsWith(name+'='))?.slice(name.length+1)||'';
 return /^[A-Za-z0-9._~-]*$/.test(value)?value:'';
}
export function setAuthCookie(response:Response,request:Request,name:string,value:string,maxAge?:number,path='/',sameSite='Strict'){
 if(!/^[A-Za-z0-9._~-]*$/.test(value))throw new Error('Invalid cookie');
 response.headers.append('Set-Cookie',`${name}=${value}; HttpOnly; Path=${path}; SameSite=${sameSite}${maxAge===undefined?'':`; Max-Age=${Math.floor(maxAge)}`}${process.env.NODE_ENV==='production'||new URL(request.url).protocol==='https:'?'; Secure':''}`);
}
export function setSession(response:Response,request:Request,session:AuthSession,remember:boolean){
 setAuthCookie(response,request,'planck_session',session.access_token,remember?Math.max(1,Math.min(session.expires_in,3600)):undefined);
 setAuthCookie(response,request,'planck_refresh',session.refresh_token,remember?REMEMBER_SECONDS:undefined,'/api/auth');
 setAuthCookie(response,request,'planck_remember',remember?'1':'0',remember?REMEMBER_SECONDS:undefined,'/api/auth');
}
export function clearSession(response:Response,request:Request){
 setAuthCookie(response,request,'planck_session','',0);
 for(const key of ['planck_refresh','planck_remember'])setAuthCookie(response,request,key,'',0,'/api/auth');
}
export function isAuthSession(value:unknown):value is AuthSession{
 const s=value as Partial<AuthSession>|null;
 return !!s&&typeof s.access_token==='string'&&typeof s.refresh_token==='string'&&Number.isFinite(s.expires_in)&&isAuthUser(s.user);
}
