import { SignJWT, jwtVerify } from 'jose';
import { requireEnv } from './env';

export interface TokenPayload {
  userId: string;
  role: string;
  email: string;
  name: string;
}

const getAccessSecret = () => new TextEncoder().encode(requireEnv('JWT_SECRET'));

const getRefreshSecret = () => new TextEncoder().encode(requireEnv('REFRESH_SECRET'));

const ACCESS_EXPIRES = process.env.JWT_ACCESS_EXPIRES || '15m';
const REFRESH_EXPIRES = process.env.JWT_REFRESH_EXPIRES || '7d';

// ─── ACCESS TOKEN ─────────────────────────────────────────────────────────────

export async function signAccessToken(payload: TokenPayload): Promise<string> {
  return await new SignJWT({ ...payload })
    .setProtectedHeader({ alg: 'HS256' })
    .setIssuedAt()
    .setExpirationTime(ACCESS_EXPIRES)
    .setIssuer('depakingbar-api')
    .setAudience('depakingbar-client')
    .sign(getAccessSecret());
}

export async function verifyAccessToken(token: string): Promise<TokenPayload | null> {
  try {
    const { payload } = await jwtVerify(token, getAccessSecret(), {
      issuer: 'depakingbar-api',
      audience: 'depakingbar-client',
    });
    return payload as unknown as TokenPayload;
  } catch {
    return null;
  }
}

// ─── REFRESH TOKEN ────────────────────────────────────────────────────────────

export async function signRefreshToken(userId: string): Promise<string> {
  return await new SignJWT({ userId, type: 'refresh' })
    .setProtectedHeader({ alg: 'HS256' })
    .setIssuedAt()
    .setExpirationTime(REFRESH_EXPIRES)
    .setIssuer('depakingbar-api')
    .sign(getRefreshSecret());
}

export async function verifyRefreshToken(token: string): Promise<{ userId: string } | null> {
  try {
    const { payload } = await jwtVerify(token, getRefreshSecret(), {
      issuer: 'depakingbar-api',
    });
    if (payload.type !== 'refresh') return null;
    return { userId: payload.userId as string };
  } catch {
    return null;
  }
}
