import { Socket } from 'socket.io';
import type { ExtendedError } from 'socket.io/dist/namespace';
import { verifyPhpAccessToken, type PhpJwtUser } from './phpJwtAuth';

declare module 'socket.io' {
  interface SocketData {
    authUser?: PhpJwtUser;
  }
}

function isStrictSocketAuth(): boolean {
  const flag = (process.env.SOCKET_AUTH_STRICT || '').trim().toLowerCase();
  if (flag === 'false' || flag === '0') return false;
  if (flag === 'true' || flag === '1') return true;
  return process.env.NODE_ENV === 'production';
}

/** ตรวจ JWT ตอน handshake — token ส่งผ่าน socket.handshake.auth.token */
export function socketAuthMiddleware(
  socket: Socket,
  next: (err?: ExtendedError) => void,
): void {
  const token = String(socket.handshake.auth?.token || '').trim();

  if (!token) {
    if (isStrictSocketAuth()) {
      next(new Error('Authentication required'));
      return;
    }
    next();
    return;
  }

  try {
    socket.data.authUser = verifyPhpAccessToken(token);
    next();
  } catch {
    next(new Error('Invalid or expired token'));
  }
}

/** user:join ต้องตรงกับ user_id ใน JWT (ถ้ามี auth) */
export function assertSocketUserMatchesAuth(socket: Socket, claimedUserId: string): boolean {
  const auth = socket.data.authUser;
  if (!auth) return true;
  return String(auth.user_id) === String(claimedUserId);
}
