/**
 * Logic dùng chung giữa Phiếu sự cố (Operations) và Công việc (Work Orders):
 * lọc hợp đồng O&M cho dropdown, quy tắc vai trò O&M staff, hiển thị người được gán.
 */
import type { IContract, IContractType, IUser, IRole } from '../types';

const INVALID_OM_PICKER_CONTRACT_STATUSES = new Set([
  'expired',
  'terminated',
  'completed',
]);

function findOmContractType(types: IContractType[]): IContractType | undefined {
  return types.find(
    (t) =>
      t.code.toUpperCase() === 'O&M' ||
      t.code.toUpperCase() === 'OM' ||
      t.name.toUpperCase().includes('O&M') ||
      t.name.toUpperCase().includes('OM'),
  );
}

function contractRowIsOmType(contractTypeRaw: string, omType?: IContractType): boolean {
  const contractType = (contractTypeRaw || '').trim();
  const contractTypeUpper = contractType.toUpperCase();
  const contractTypeNormalized = contractTypeUpper.replace(/[&-\s]/g, '');

  let isOM = false;
  if (omType) {
    isOM =
      contractType === omType.code ||
      contractTypeNormalized === omType.code.toUpperCase().replace(/[&-\s]/g, '');
  }
  if (!isOM) {
    isOM =
      contractTypeUpper === 'O&M' ||
      contractTypeUpper === 'OM' ||
      contractTypeNormalized === 'OM';
  }
  return isOM;
}

/** Hợp đồng O&M đang hiệu lực (loại O&M, không expired/terminated/completed) — dùng cho dropdown phiếu & WO */
export function filterActiveOmContractsForPickers(
  contracts: IContract[],
  contractTypes: IContractType[],
): IContract[] {
  const omContractType = findOmContractType(contractTypes);
  return contracts.filter((c) => {
    if (INVALID_OM_PICKER_CONTRACT_STATUSES.has(c.status)) return false;
    return contractRowIsOmType(c.contractType || '', omContractType);
  });
}

export function getRoleCodeByName(roles: IRole[], roleName: string): string | null {
  const role = roles.find((r) => r.name === roleName && r.isActive);
  return role?.code ?? null;
}

export function userHasRoleCode(user: IUser, roles: IRole[], roleCode: string): boolean {
  if (user.roleCode === roleCode) return true;
  if (!user.role) return false;
  return getRoleCodeByName(roles, user.role) === roleCode;
}

export function isActiveOmAssignableUser(user: IUser, roles: IRole[]): boolean {
  const isActive = user.status === 'Active' || user.active === true;
  if (!isActive) return false;
  return (
    userHasRoleCode(user, roles, 'TECHNICIAN') || userHasRoleCode(user, roles, 'OM_MANAGER')
  );
}

/**
 * Gán mặc định khi tạo phiếu: ưu tiên Technician, sau đó OM Manager, cuối cùng bất kỳ user active.
 */
export function pickDefaultOmTechnicianAssignee(
  users: IUser[],
  roles: IRole[],
): string | undefined {
  const technicians = users.filter(
    (u) =>
      userHasRoleCode(u, roles, 'TECHNICIAN') &&
      (u.status === 'Active' || u.active === true),
  );
  if (technicians.length > 0) return technicians[0]._id;

  const omManagers = users.filter(
    (u) =>
      userHasRoleCode(u, roles, 'OM_MANAGER') &&
      (u.status === 'Active' || u.active === true),
  );
  if (omManagers.length > 0) return omManagers[0]._id;

  const activeUsers = users.filter((u) => u.status === 'Active' || u.active === true);
  return activeUsers[0]?._id;
}

export type AssigneeRef =
  | string
  | string[]
  | { name?: string; email?: string; _id?: string }
  | undefined
  | null;

/** Chuẩn hóa hiển thị người được gán (ID, CSV, mảng ID, hoặc object populate từ API) */
export function resolveUserAssigneeDisplay(
  ref: AssigneeRef,
  users: IUser[],
  emptyLabel = 'Chưa được gán',
): string {
  if (ref === undefined || ref === null || ref === '') return emptyLabel;

  if (typeof ref === 'object' && !Array.isArray(ref)) {
    return ref.name || ref.email || 'Unknown';
  }

  if (Array.isArray(ref)) {
    if (ref.length === 0) return emptyLabel;
    return ref
      .map((userId) => {
        const user = users.find((u) => u._id === userId || u._id === String(userId));
        return user ? user.name : String(userId);
      })
      .join(', ');
  }

  if (typeof ref === 'string' && ref.includes(',')) {
    const ids = ref.split(',').map((s) => s.trim()).filter(Boolean);
    return ids
      .map((userId) => {
        const user = users.find((u) => u._id === userId || u._id === String(userId));
        return user ? user.name : userId;
      })
      .join(', ');
  }

  const user = users.find((u) => u._id === ref || u._id === String(ref));
  return user ? user.name : ref;
}

export function resolveContractNumber(contracts: IContract[], id?: string): string {
  if (!id) return 'N/A';
  return contracts.find((c) => c._id === id)?.contractNumber ?? 'N/A';
}
