import { BadRequestException } from '@nestjs/common';
import { UserRole } from '../common/constants/enums';

const CLIENT_TO_ROLE: Record<string, UserRole> = {
  user: UserRole.EMPLOYEE,
  employee: UserRole.EMPLOYEE,
  admin: UserRole.ADMIN,
  manager: UserRole.MANAGER,
  super_admin: UserRole.SUPER_ADMIN,
  hod: UserRole.HOD,
  reporting_manager: UserRole.REPORTING_MANAGER,
};

export function parseClientRole(role?: string): UserRole | undefined {
  if (!role) return undefined;
  const normalized = role.trim();
  const mapped = CLIENT_TO_ROLE[normalized.toLowerCase()];
  if (mapped) return mapped;
  if (Object.values(UserRole).includes(normalized as UserRole)) {
    return normalized as UserRole;
  }
  throw new BadRequestException(`Invalid role: ${role}`);
}

/** Map legacy / client role strings stored in JWT or MongoDB to canonical enum. */
export function resolveStoredRole(role: string): UserRole {
  const normalized = role.trim();
  const mapped = CLIENT_TO_ROLE[normalized.toLowerCase()];
  if (mapped) return mapped;
  if (Object.values(UserRole).includes(normalized as UserRole)) {
    return normalized as UserRole;
  }
  return UserRole.EMPLOYEE;
}

export function toClientRole(role: UserRole): string {
  switch (role) {
    case UserRole.EMPLOYEE:
      return 'user';
    case UserRole.ADMIN:
    case UserRole.SUPER_ADMIN:
      return 'admin';
    case UserRole.MANAGER:
      return 'manager';
    case UserRole.HOD:
      return 'hod';
    case UserRole.REPORTING_MANAGER:
      return 'reporting_manager';
    default:
      return String(role).toLowerCase();
  }
}

export type NormalizedCreateUserInput = {
  email: string;
  password: string;
  fullName: string;
  employeeCode: string;
  role?: UserRole;
  mobileNumber: string;
  sittingLocation?: string;
  reportingManagerRef?: string;
  deviceId?: string;
  profileImage?: string;
};

export function normalizeCreateUserInput(body: Record<string, unknown>): NormalizedCreateUserInput {
  const fullName = String(body.fullName ?? body.name ?? '').trim();
  const mobileNumber = String(body.mobileNumber ?? body.mobile ?? '').trim();
  const sittingLocation = String(
    body.sittingLocation ?? body.sitingLocation ?? '',
  ).trim();
  const reportingManagerRef = String(
    body.reportingManagerUid ?? body.reportingManagerId ?? '',
  ).trim();

  return {
    email: String(body.email ?? ''),
    password: String(body.password ?? ''),
    fullName,
    employeeCode: String(body.employeeCode ?? '').trim(),
    role: parseClientRole(body.role as string | undefined),
    mobileNumber,
    sittingLocation: sittingLocation || undefined,
    reportingManagerRef: reportingManagerRef || undefined,
    deviceId: body.deviceId ? String(body.deviceId) : undefined,
    profileImage: body.profileImage ? String(body.profileImage) : undefined,
  };
}

export type ManagerSummary = {
  id: string;
  uid: string;
  fullName: string;
  name?: string;
  employeeCode: string;
  role: UserRole;
} | null;

type UserNameSource = {
  fullName?: string | null;
  name?: string | null;
};

/** Supports legacy Mongo `name` field and canonical `fullName`. */
export function resolveUserDisplayName(user: UserNameSource): string | null {
  const value = (user.fullName ?? user.name ?? '').trim();
  return value || null;
}

export function toClientUser(
  user: {
    _id?: { toString(): string };
    id?: string;
    uid: string;
    email: string;
    fullName?: string;
    name?: string;
    employeeCode: string;
    role: UserRole;
    mobileNumber?: string;
    sittingLocation?: string;
    reportingManagerId?: string;
    deviceId?: string;
    profileImage?: string;
    status?: string;
    presence?: string;
    createdAt?: Date;
    updatedAt?: Date;
  },
  manager?: ManagerSummary,
) {
  const id = user.id ?? user._id?.toString() ?? '';
  const reportingManagerId = manager?.id ?? user.reportingManagerId ?? null;
  const displayName = resolveUserDisplayName(user);

  return {
    id,
    uid: user.uid,
    email: user.email,
    name: displayName,
    fullName: displayName,
    employeeCode: user.employeeCode,
    role: toClientRole(user.role),
    mobile: user.mobileNumber ?? null,
    mobileNumber: user.mobileNumber ?? null,
    sitingLocation: user.sittingLocation ?? null,
    sittingLocation: user.sittingLocation ?? null,
    reportingManagerId,
    reportingManagerName: manager ? resolveUserDisplayName(manager) : null,
    reportingManager: manager,
    deviceId: user.deviceId ?? null,
    profileImage: user.profileImage ?? null,
    status: user.status ?? null,
    presence: user.presence ?? null,
    createdAt: user.createdAt ?? null,
    updatedAt: user.updatedAt ?? null,
  };
}

/** Populated on travel-request list items (admin/manager view). */
export function toTripCreatorUser(
  clientUser: ReturnType<typeof toClientUser>,
) {
  const name = resolveUserDisplayName(clientUser);

  return {
    uid: clientUser.uid,
    name,
    employeeCode: clientUser.employeeCode ?? null,
    email: clientUser.email ?? null,
    mobile: clientUser.mobile ?? null,
    role: clientUser.role ?? null,
    reportingManagerName: clientUser.reportingManagerName ?? null,
  };
}
