import {
  type AllowSocialNetworks,
  type IconsStyle,
  type MeInstance,
  type ModulesName,
  type Visibility,
} from 'src/types/instance';
import { type MeUser, type SocialNetworksType } from 'src/types/user';

import { type CommunityFeature } from './communityFeatures';
import { type FeatureFlag } from './featureFlags';

export enum OTPChannels {
  WHATSAPP = 'whatsapp',
  SMS = 'sms',
  EMAIL = 'email',
}

export enum LoginErrors {
  SSO_MORE_THAN_ONE_USER_MATCHING_EMAIL = 'SSO_MORE_THAN_ONE_USER_MATCHING_EMAIL',
  USER_NOT_FOUND = 'USER_NOT_FOUND',
  INVALID_CREDENTIALS = 'INVALID_CREDENTIALS',
}

export enum OTPErrors {
  PHONE_NOT_FOUND = 'PHONE_NUMBER_NOT_FOUND',
  INVALID_PHONE = 'INVALID_PHONE_NUMBER',
  INVALID_CODE = 'INVALID_OTP_CODE',
  MAX_TRIES = 'MAXIMUM_ATTEMPS_REACHED',
}

export type OTPState = {
  instance: LoginInstance;
  employeeInternalId: string;
  init2faToken?: string;
};

export type LoginInstance = {
  id: number;
  name: string;
  color: string;
  logo: string;
  samlURI: string;
  userHasEmail: boolean;
  forceOTP: boolean;
  otpAfterRegularLogin: boolean;
  useJanusForClassicLogin?: boolean;
};

export type OTP = {
  channel: OTPChannels;
  receiver: string | null;
};

export const IDP_PROVIDER_PROTOCOL = {
  SAML: 'SAML',
  OAUTH: 'OAUTH',
} as const;

export type IdpProviderProtocol =
  (typeof IDP_PROVIDER_PROTOCOL)[keyof typeof IDP_PROVIDER_PROTOCOL];

export type SamlNameIdField = 'EMAIL' | 'EMPLOYEE_INTERNAL_ID';

export type IdpProvider = {
  id: number;
  uuid: string;
  name: string;
  appIcon: string;
  protocol: IdpProviderProtocol;
  // SAML only — present for SAML, null for OAUTH
  initUrl: string | null;
  nameIdField: SamlNameIdField | null;
  // OAUTH only — present for OAUTH, null for SAML
  clientId: string | null;
  audienceIdentifier: string | null;
  redirectUri: string | null;
};

export type IdpProvidersResponse = {
  items: IdpProvider[];
  count: number;
  page: number;
  totalPages: number;
};

export type OAuth2IdpInitiatedRequest = {
  clientId?: string;
  audienceIdentifier: string;
  codeChallenge: string;
  codeChallengeMethod: 'S256' | 'plain';
  redirectUri: string;
  scopes?: string[];
};

export type OAuth2IdpInitiatedResponse = {
  code: string;
  redirectUri: string;
};

// Data
export type LoginData = {
  employeeInternalId: string | number;
  instanceId: number;
  password: string;
};

export type AzureLoginData = {
  accessToken: string;
  instanceId: number;
};

export type OktaLoginData = {
  accessToken: string;
  instanceId: number;
};

export type GoogleLoginData = {
  accessToken: string;
  instanceId: number;
};

export type UpdatePasswordWithCodeData = {
  code: string;
  passwordInput: string;
};

export type GetOTPData = {
  instanceId: number;
  employeeInternalId: string;
};

export type SendOTPData = {
  instanceId: number;
  employeeInternalId: string;
  init2faToken?: string;
  channel: OTPChannels;
};

export type LoginOTPData = SendOTPData & {
  code: string;
};

// Response
export type LegacyMeUser = MeUser & {
  permissions?: Record<string, boolean>;
};

export type MeResponse = {
  user: MeUser & { permissions: Record<string, boolean> };
  instance: MeInstance;
  featureFlags: FeatureFlag;
  communityFeatures?: CommunityFeature[];
};

export type AuthResponse = {
  accessToken: string;
  refreshToken: string;
};

export type InitMFAResponse = {
  init2faToken: string;
};

export type LoginResponse = Omit<MeResponse, 'user'> & {
  user: LegacyMeUser;
} & AuthResponse;

export type ReactNativeWebViewType = Window & {
  ReactNativeWebView?: {
    postMessage: (message: string) => void;
  };
};

export type TokenPayload = {
  sessionId: string;
  loginSso: boolean;
};

export interface JanusMeRawUser {
  id: number;
  employeeInternalId: string;
  firstName: string;
  lastName: string;
  email: string | null;
  language: string;
  deleted: boolean;
  profilePicture: string | null;
  phoneNumber: string | null;
  birthdate: string | null;
  hiringDate: string | null;
  hasBeenLogged: boolean;
  hasPasswordChanged: boolean;
  postTranslationLanguage: string | null;
  isAgent: boolean;
  lastTermsAndConditionsAccepted: boolean | null;
  acknowledgementsToGiveLeft: number;
  profileData: Record<string, unknown> | null;
  workdays: string[];
  socialNetworks: SocialNetworksType;
  department: { id: number; name: string } | null;
  jobPosition: { id: number; name: string } | null;
}

export interface JanusMeRawInstance {
  id: number;
  name: string;
  logo: string;
  color: string;
  language: string;
  timezone: string;
  iconsStyle: IconsStyle;
  forceOtp: boolean; // Janus naming — mapped to forceOTP by mapper
  otpAfterRegularLogin: boolean;
  editableName: boolean;
  editableEmail: boolean;
  editableBirthdate: boolean;
  editableProfilePicture: boolean;
  editableCoverPicture: boolean;
  allowNickname: boolean;
  allowHiringDate: boolean;
  allowSocialNetworks: AllowSocialNetworks;
  allowCreateChats: boolean;
  allowChatCall: boolean;
  allowAttachmentsInChats: boolean;
  allowLiveStream: boolean;
  acknowledgmentsCanBeCommented: boolean;
  viewAcknowledgementsRanking: boolean;
  showAcknowledgmentsPoints: boolean;
  hasTermsAndConditions: boolean;
  passwordInDocumentsTimer?: number;
  maxPostSizeInMb: number; // Janus naming — mapped to maxPostSizeInMB by mapper
  hideFileDownload: boolean;
  defaultCurrencyCode: string | null;
  vacationPublicCalendar: boolean;
  userInactivity: number;
  moduleNames?: ModulesName;
  externalBotId: string | null;
  emailInProfileVisibility: Visibility;
}

export interface JanusMeRawResponse {
  user: JanusMeRawUser;
  instance: JanusMeRawInstance;
  permissions: string[];
}
