import { cookies } from 'next/headers';

export interface User {
  id: string;
  email: string;
  firstName: string | null;
  lastName: string | null;
  profilePictureUrl: string | null;
}

export interface Session {
  user: User;
  accessToken: string;
  refreshToken: string;
  stayLoggedIn: boolean;
}

const SESSION_COOKIE_NAME = 'quit_smoking_session';
const SESSION_SECRET = process.env.SESSION_SECRET || 'fallback-secret-for-dev-only';

// Helper to sign the session
async function sign(data: string, secret: string): Promise<string> {
  const encoder = new TextEncoder();
  const keyData = encoder.encode(secret);
  const dataData = encoder.encode(data);

  const key = await crypto.subtle.importKey(
    'raw',
    keyData,
    { name: 'HMAC', hash: 'SHA-256' },
    false,
    ['sign']
  );

  const signature = await crypto.subtle.sign('HMAC', key, dataData);
  return btoa(String.fromCharCode(...new Uint8Array(signature)));
}

// Helper to verify the session
async function verify(data: string, signature: string, secret: string): Promise<boolean> {
  const encoder = new TextEncoder();
  const keyData = encoder.encode(secret);
  const dataData = encoder.encode(data);

  const key = await crypto.subtle.importKey(
    'raw',
    keyData,
    { name: 'HMAC', hash: 'SHA-256' },
    false,
    ['verify']
  );

  const sigBytes = Uint8Array.from(atob(signature), (c) => c.charCodeAt(0));
  return await crypto.subtle.verify('HMAC', key, sigBytes, dataData);
}

export async function getSession(): Promise<Session | null> {
  const cookieStore = await cookies();
  const sessionCookie = cookieStore.get(SESSION_COOKIE_NAME);

  if (!sessionCookie) {
    return null;
  }

  try {
    const [payloadBase64, signature] = sessionCookie.value.split('.');
    if (!payloadBase64 || !signature) return null;

    const payload = atob(payloadBase64);
    const isValid = await verify(payload, signature, SESSION_SECRET);

    if (!isValid) {
      console.warn('Invalid session signature detected');
      return null;
    }

    return JSON.parse(payload);
  } catch (error) {
    console.error('Error parsing session:', error);
    return null;
  }
}

export async function setSession(session: Session): Promise<void> {
  const cookieStore = await cookies();
  const maxAge = session.stayLoggedIn ? 60 * 60 * 24 * 30 : 60 * 60 * 24; // 30 days if stay logged in, else 1 day

  const payload = JSON.stringify(session);
  const payloadBase64 = btoa(payload);
  const signature = await sign(payload, SESSION_SECRET);

  cookieStore.set(SESSION_COOKIE_NAME, `${payloadBase64}.${signature}`, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'lax',
    maxAge,
    path: '/',
  });
}

export async function clearSession(): Promise<void> {
  const cookieStore = await cookies();
  cookieStore.delete(SESSION_COOKIE_NAME);
}

export async function getUser(): Promise<User | null> {
  const session = await getSession();
  return session?.user ?? null;
}
