import { SignJWT, jwtVerify } from 'jose'
import type { ContractorSessionPayload } from '@zync/types'

/** Contractor portal session JWT TTL, in seconds (30 days). */
export const CONTRACTOR_SESSION_TTL_SECONDS = 60 * 60 * 24 * 30

/** Re-issue the cookie when remaining TTL falls below this threshold (7 days). */
export const CONTRACTOR_RENEW_THRESHOLD_SECONDS = 60 * 60 * 24 * 7

/** Name of the contractor portal session cookie. */
export const CONTRACTOR_COOKIE_NAME = 'zync_contractor'

/**
 * Cookie attributes for the `zync_contractor` session cookie.
 * HttpOnly + Secure + SameSite=Strict + domain=.zync.is; scoped to /contractor-portal.
 */
export const CONTRACTOR_COOKIE_OPTS = {
  name: CONTRACTOR_COOKIE_NAME,
  httpOnly: true,
  secure: true,
  sameSite: 'Strict' as const,
  domain: '.zync.is',
  path: '/contractor-portal',
} as const

/**
 * Sign a contractor portal session (HS256, 30-day TTL). `exp`/`iat` are set by jose;
 * `role` is always `'contractor'`.
 */
export async function signContractorSession(
  payload: Omit<ContractorSessionPayload, 'iat' | 'exp' | 'role'>,
  secret: string,
): Promise<string> {
  const secretKey = new TextEncoder().encode(secret)
  return new SignJWT({ ...payload, role: 'contractor' })
    .setProtectedHeader({ alg: 'HS256' })
    .setIssuedAt()
    .setExpirationTime(`${CONTRACTOR_SESSION_TTL_SECONDS}s`)
    .sign(secretKey)
}

/** Verify a contractor portal session JWT. Throws on invalid/expired/tampered token. */
export async function verifyContractorSession(
  token: string,
  secret: string,
): Promise<ContractorSessionPayload> {
  const secretKey = new TextEncoder().encode(secret)
  const { payload } = await jwtVerify(token, secretKey)
  return payload as unknown as ContractorSessionPayload
}

/**
 * Extract the raw `zync_contractor` token from a Cookie header.
 * Returns null when the header is absent or the cookie is missing.
 */
export function parseContractorCookie(cookieHeader: string | null | undefined): string | null {
  if (!cookieHeader) return null
  for (const part of cookieHeader.split(';')) {
    const eq = part.indexOf('=')
    if (eq === -1) continue
    const name = part.slice(0, eq).trim()
    if (name === CONTRACTOR_COOKIE_NAME) {
      return decodeURIComponent(part.slice(eq + 1).trim())
    }
  }
  return null
}
