import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';

export interface PhpJwtUser {
  user_id: string;
  userid: string;
  typeuser: string;
  jti?: string;
}

declare global {
  namespace Express {
    interface Request {
      authUser?: PhpJwtUser;
    }
  }
}

interface PhpJwtPayload {
  user_id?: string;
  userid?: string;
  typeuser?: string;
  jti?: string;
  token_type?: string;
  exp?: number;
}

function getPhpJwtSecret(): string {
  return (
    process.env.PHP_JWT_SECRET ||
    process.env.JWT_SECRET ||
    'ApiIue'
  );
}

export function verifyPhpAccessToken(token: string): PhpJwtUser {
  const decoded = jwt.verify(token, getPhpJwtSecret(), {
    algorithms: ['HS256'],
  }) as PhpJwtPayload;

  if (decoded.token_type === 'refresh') {
    throw new Error('Refresh token not allowed');
  }

  const user_id = String(decoded.user_id || '').trim();
  if (!user_id) {
    throw new Error('Invalid token: missing user_id');
  }

  return {
    user_id,
    userid: String(decoded.userid || user_id),
    typeuser: String(decoded.typeuser || 'student'),
    jti: decoded.jti,
  };
}

export function requirePhpAuth(req: Request, res: Response, next: NextFunction): void {
  const header = req.headers.authorization;
  if (!header?.startsWith('Bearer ')) {
    res.status(401).json({ success: false, message: 'ต้องส่ง Authorization: Bearer <token>' });
    return;
  }

  try {
    req.authUser = verifyPhpAccessToken(header.slice(7).trim());
    next();
  } catch (err) {
    const hint =
      process.env.NODE_ENV !== 'production' &&
      (err instanceof jwt.JsonWebTokenError || err instanceof jwt.TokenExpiredError)
        ? err.message
        : undefined;
    res.status(401).json({
      success: false,
      message: 'Token ไม่ถูกต้องหรือหมดอายุ',
      ...(hint ? { hint: 'ตรวจ PHP_JWT_SECRET ให้ตรงกับ JWT_SECRET ใน api_iue/.env แล้ว login ใหม่', detail: hint } : {}),
    });
  }
}

/** กรรมการ/แอดมิน — ไม่ใช่ typeuser แบบนักเรียน */
export function canJoinAsProctor(typeuser: string): boolean {
  const t = typeuser.toLowerCase().trim();
  return t !== 'student' && t !== '0' && t !== '';
}

export function resolveParticipantRole(
  requested: string | undefined,
  typeuser: string,
): 'student' | 'proctor' {
  const role = (requested || 'student').toLowerCase().trim();
  if (role === 'proctor') {
    if (!canJoinAsProctor(typeuser)) {
      throw new Error('ไม่มีสิทธิ์เข้าในฐานะกรรมการ');
    }
    return 'proctor';
  }
  return 'student';
}
