import type { TicketCollaborator } from '@/features/tickets/types/collaborator.types';
import type { TicketUserRef } from '@/features/tickets/types/ticket.types';
import {
  getAgentColor,
  getCollaboratorColor,
  getCompanyAdminColor,
  getDepartmentHeadColor,
  getParticipantColor,
  getRequesterColor,
  getSystemColor,
  type ParticipantColor,
  type ThemeMode,
} from '@/features/tickets/utils/participantColors';

export type TicketParticipantKind =
  | 'requester'
  | 'assignee'
  | 'agent'
  | 'collaborator'
  | 'department_head'
  | 'company_admin'
  | 'system';

export interface TicketParticipantContext {
  requesterId: string;
  assigneeId?: string | null;
  collaboratorUserIds?: string[];
  collaboratorRolesByUserId?: Record<string, string[]>;
  systemUserIds?: string[];
}

export function buildTicketParticipantContext(ticket: {
  requester: TicketUserRef;
  assignee?: TicketUserRef | null;
  collaborators?: TicketCollaborator[];
}): TicketParticipantContext {
  const collaborators = ticket.collaborators ?? [];

  return {
    requesterId: ticket.requester.id,
    assigneeId: ticket.assignee?.id ?? null,
    collaboratorUserIds: collaborators.map((collaborator) => collaborator.user_id),
    collaboratorRolesByUserId: Object.fromEntries(
      collaborators.map((collaborator) => [collaborator.user_id, collaborator.role_names]),
    ),
  };
}

function normalizedRoleNames(roleNames: string[] | undefined): string[] {
  return (roleNames ?? []).map((role) => role.toLowerCase());
}

function hasCompanyAdminRole(roleNames: string[]): boolean {
  return roleNames.some(
    (role) =>
      role.includes('super_admin') ||
      role.includes('company_admin') ||
      role.startsWith('company_admin_'),
  );
}

function hasDepartmentHeadRole(roleNames: string[]): boolean {
  return roleNames.some(
    (role) => role.includes('department_head') || role.includes('manager'),
  );
}

export function resolveTicketParticipantKind(
  userId: string,
  context: TicketParticipantContext,
): TicketParticipantKind {
  const normalizedId = userId?.trim();

  if (!normalizedId || context.systemUserIds?.includes(normalizedId)) {
    return 'system';
  }

  if (normalizedId === context.requesterId) {
    return 'requester';
  }

  if (context.assigneeId && normalizedId === context.assigneeId) {
    return 'assignee';
  }

  const roleNames = normalizedRoleNames(context.collaboratorRolesByUserId?.[normalizedId]);

  if (hasCompanyAdminRole(roleNames)) {
    return 'company_admin';
  }

  if (hasDepartmentHeadRole(roleNames)) {
    return 'department_head';
  }

  if (context.collaboratorUserIds?.includes(normalizedId)) {
    return 'collaborator';
  }

  return 'agent';
}

export function resolveTicketParticipantColor(
  userId: string,
  context: TicketParticipantContext,
  mode: ThemeMode = 'light',
): ParticipantColor {
  const kind = resolveTicketParticipantKind(userId, context);

  switch (kind) {
    case 'requester':
      return getRequesterColor(mode);
    case 'assignee':
      return getAgentColor(mode);
    case 'agent':
      return getParticipantColor(userId, undefined, mode);
    case 'collaborator':
      return getCollaboratorColor(userId, mode);
    case 'department_head':
      return getDepartmentHeadColor(mode);
    case 'company_admin':
      return getCompanyAdminColor(mode);
    case 'system':
      return getSystemColor(mode);
    default:
      return getAgentColor(mode);
  }
}

export function ticketParticipantRoleLabelKey(kind: TicketParticipantKind): string {
  switch (kind) {
    case 'requester':
      return 'tickets:detail.roleRequester';
    case 'assignee':
      return 'tickets:detail.roleAssignee';
    case 'collaborator':
      return 'tickets:detail.roleCollaborator';
    case 'department_head':
      return 'tickets:detail.roleDepartmentHead';
    case 'company_admin':
      return 'tickets:detail.roleCompanyAdmin';
    case 'system':
      return 'tickets:detail.roleSystem';
    case 'agent':
    default:
      return 'tickets:detail.roleAgent';
  }
}
