import { type TableCellProps } from '@material-hu/mui/TableCell';

import { type HoursRequestType } from 'src/pages/dashboard/timeOff/hooks/useRequestCreate';
import { type Attachment } from 'src/types/attachments';
import { type Pagination } from 'src/types/services';
import { type MeUser, type User } from 'src/types/user';
import { type iconsPolicyTypes } from 'src/utils/vacations';

import { type InfiniteListProps } from 'src/components/list/InfiniteList';

export enum ExtensionTypeReport {
  XLSX = 'SLSX',
  CSV = 'CSV',
}

export enum VacationRequestSources {
  MY_TIME_OFF = 'MY_TIME_OFF',
  REQUEST_CREATION = 'REQUEST_CREATION',
  REQUEST_DETAIL = 'REQUEST_DETAIL',
  REQUEST_ON_BEHALF = 'REQUEST_ON_BEHALF',
}

export enum VacationActionsSources {
  MANAGEMENT_DETAIL = 'MANAGEMENT_DETAIL',
  MANAGEMENT_LIST = 'MANAGEMENT_LIST',
  COLLABORATOR_DETAIL = 'COLLABORATOR_DETAIL',
  COLLABORATOR_LIST = 'COLLABORATOR_LIST',
  MANAGEMENT_LIST_MASSIVE = 'MANAGEMENT_LIST_MASSIVE',
  MAIL = 'MAIL',
}

export enum ResponseCode {
  VACATION_APPROVER_NOT_AVAILABLE_FOR_USER = 'VACATION_APPROVER_NOT_AVAILABLE_FOR_USER',
  FROM_DATE_BEFORE_TODAY_NOT_ALLOWED = 'FROM_DATE_BEFORE_TODAY_NOT_ALLOWED',
  VACATION_REQUEST_NOT_PENDING = 'VACATION_REQUEST_NOT_PENDING',
  ERROR_MAX_ATTACHMENTS_SIZE_VACATIONS = 'ERROR_MAX_ATTACHMENTS_SIZE_VACATIONS',
  VACATION_REQUEST_ATTACHMENT_REQUIRED = 'VACATION_REQUEST_ATTACHMENT_REQUIRED',
}

export enum Role {
  MANAGER = 'MANAGER',
  COLLABORATOR = 'COLLABORATOR',
}

export enum OperationsBalance {
  ADDITION = 'ADDITION',
  SUBTRACTION = 'SUBTRACTION',
}

export enum UnitVacations {
  DAYS = 'DAYS',
  HOURS = 'HOURS',
}

export enum AllowanceType {
  BASIC_ANNUAL = 'BASIC_ANNUAL',
  UNLIMITED = 'UNLIMITED',
}

export enum CountingMethod {
  CALENDAR_DAYS = 'CALENDAR_DAYS',
  BUSINESS_DAYS = 'BUSINESS_DAYS',
}

export enum StepStatus {
  PENDING = 'PENDING',
  WAITING_OTHER_STEP = 'WAITING_OTHER_STEP',
  REJECTED = 'REJECTED',
  APPROVED = 'APPROVED',
}

export enum VacationStatus {
  IN_PROGRESS = 'IN_PROGRESS',
  APPROVED = 'APPROVED',
  CANCELLED = 'CANCELLED',
  PENDING = 'PENDING',
  REJECTED = 'REJECTED',
}

export enum ReportType {
  BALANCES = 'balances',
  REQUESTS = 'requests',
}

export enum CriteriaSortBy {
  ASC_STATE = 'PENDING_FIRST',
  DESC_CREATED_AT = 'REQUESTED_DATE_RECENT',
  ASC_CREATED_AT = 'REQUESTED_DATE_OLDEST',
  DESC_FROM_DATE = 'START_DATE_FUTURE',
  ASC_FROM_DATE = 'START_DATE_OLDEST',
}

export enum SectionsManager {
  CALENDAR = 'CALENDAR',
  REQUESTS = 'REQUESTS',
  BALANCES = 'BALANCES',
}

export enum TabManagementType {
  MANAGEMENT_TAB_SIMPLE_DOWNLOAD = 'management_tab_simple_download',
  MANAGEMENT_TAB_ADVANCED_DOWNLOAD = 'management_tab_advanced_download',
}

export enum AttachmentRequirement {
  NONE = 'NONE',
  OPTIONAL = 'OPTIONAL',
  REQUIRED = 'REQUIRED',
}

export enum ProrationFrequency {
  EVERY_TWELVE_MONTHS = 'EVERY_TWELVE_MONTHS',
  EVERY_ONE_MONTH = 'EVERY_ONE_MONTH',
}

export enum RequestedDaysErrors {
  TIME_OFF_OVERLAPPING_REQUEST = 'TIME_OFF_OVERLAPPING_REQUEST',
  TIME_OFF_NEW_HIRES_REQUESTS_BAN = 'TIME_OFF_NEW_HIRES_REQUESTS_BAN',
  TIME_OFF_POLICY_MUST_BE_USE_FIRST = 'TIME_OFF_POLICY_MUST_BE_USE_FIRST',
  TIME_OFF_POLICY_PENDING_REQUESTS_AFFECT_BALANCE = 'TIME_OFF_POLICY_PENDING_REQUESTS_AFFECT_BALANCE',
  TIME_OFF_POLICY_INSUFFICIENT_BALANCE = 'TIME_OFF_POLICY_INSUFFICIENT_BALANCE',
  TIME_OFF_ONLY_ADMIN_REQUESTS = 'TIME_OFF_ONLY_ADMIN_REQUESTS',
  TIME_OFF_FUTURE_REQUESTS_BAN = 'TIME_OFF_FUTURE_REQUESTS_BAN',
  TIME_OFF_FUTURE_REQUEST_TOO_ADVANCED = 'TIME_OFF_FUTURE_REQUEST_TOO_ADVANCED',
  TIME_OFF_FUTURE_REQUEST_NOT_ALLOWED = 'TIME_OFF_FUTURE_REQUEST_NOT_ALLOWED',
  TIME_OFF_BALANCE_SALE_TIME_MUST_EXCEED_MONEY = 'TIME_OFF_BALANCE_SALE_TIME_MUST_EXCEED_MONEY',
  TIME_OFF_REQUEST_BLOCKED_DATES = 'TIME_OFF_REQUEST_BLOCKED_DATES',
  TIME_OFF_NEXT_CYCLE_REQUEST = 'TIME_OFF_NEXT_CYCLE_REQUEST',
  TIME_OFF_BRAZIL_MIN_DAYS_PER_PERIOD = 'TIME_OFF_BRAZIL_MIN_DAYS_PER_PERIOD',
  TIME_OFF_BRAZIL_MAX_PERIODS_EXCEEDED = 'TIME_OFF_BRAZIL_MAX_PERIODS_EXCEEDED',
  TIME_OFF_BRAZIL_MIN_MAIN_PERIOD_REQUIRED = 'TIME_OFF_BRAZIL_MIN_MAIN_PERIOD_REQUIRED',
}

export type BlockedDateError = {
  blockedDates: BlockedDate[];
};

type BlockedDate = {
  fromDate: string;
  toDate: string;
  name: string;
};

export enum WarningsRequestedDays {
  TIME_OFF_REQUEST_FROM_NEXT_CYCLE = 'TIME_OFF_NEXT_CYCLE_REQUEST',
}

export type RequiredPolicyTypeErrors = {
  policy: {
    name: string;
    id: number;
  };
};

export type NewHiresRequestsBanErrors = {
  newHiresRequestsBanValue: number;
  newHiresRequestsBanUnit: UnitVacations;
};

export enum ConsumptionType {
  FULL_DAY = 'FULL_DAY',
  HALF_DAY = 'HALF_DAY',
  HOURS = 'HOURS',
}

export enum ActivityType {
  NON_WORK = 'NON_WORK',
  WORK = 'WORK',
}

export type DateToRequest = {
  date: string;
  consumptionType: ConsumptionType;
  time?: string;
};

export type CollaboratorOrManagerData = Partial<InfiniteListProps> & {
  data?: Vacations;
  policyTypes?: PolicyTypes[];
  countRequestManager?: number;
  hasRequests?: boolean;
};

export type ParamsDatesVacationCell = {
  date: string | Date;
  user: MeUser;
  isUtc?: boolean;
  type: string;
};

export type AdjustAvailableTimeForm = {
  operation: string;
  amount: number;
  observations: string;
  cycleId: number;
};

export type AdjustAvailableTimeParams = {
  policyTypeId: number;
  userId: number;
  operation: string;
  amount: number;
  observations: string;
  cycleId?: number;
};

export type PolicyTypes = {
  id: number;
  name: string;
  description: string;
  attachmentInstructions?: string;
  attachmentRequirement?: AttachmentRequirement;
  icon?: keyof typeof iconsPolicyTypes | null;
  allowanceType: AllowanceType;
  amount: number;
  unit: UnitVacations;
  descriptionRequired: boolean;
  activityType: ActivityType;
  allowanceProrationFrequency?: ProrationFrequency;
  minimumAmountPerRequest?: number;
  maximumAmountPerRequest?: number;
  minimumBalance?: number;
  maximumBalance?: number;
  maximumRemnant?: number;
  countingMethod: CountingMethod;
  fromDateCycle: string;
  toDateCycle: string;
  allowHalfDayRequests?: boolean;
  noRetroactiveRequests?: boolean;
  noFutureRequests?: boolean;
  amountRequested: number;
  currentBalance: number;
  minimumAdvanceDays?: number;
  allowBalanceSale: boolean;
  allowanceAmount: number;
  minimumTimeFraction?: number;
  requireMultiplesOfSeven: boolean;
  requireMondayStart: boolean;
  allowBalanceSaleBrazil: boolean;
  immediateFutureDeduction: boolean;
};

export type ResponseDetailPolicyTypes = Pick<
  PolicyTypes,
  | 'id'
  | 'name'
  | 'fromDateCycle'
  | 'toDateCycle'
  | 'unit'
  | 'amountRequested'
  | 'currentBalance'
  | 'allowanceType'
  | 'allowanceProrationFrequency'
  | 'allowHalfDayRequests'
  | 'attachmentInstructions'
  | 'attachmentRequirement'
  | 'icon'
>;

export type PolicyTypesBalance = {
  amount: number;
  eventType: string;
};

export type RequestTimeOff = {
  policyTypeId: number;
  from: DateToRequest | undefined;
  to: DateToRequest | undefined;
  description?: string;
  attachments?: TimeOffAttachment[];
  issuerId: number | null;
  skipApproval?: boolean;
  amountInMoney?: number;
};

export type ResponseRequestTimeOff = {
  id: number;
  policyType: PolicyTypes;
  createdAt: string;
  from: DateToRequest;
  to: DateToRequest;
  resolutionReason?: string;
  state: VacationStatus;
  stepState: StepStatus | null;
  issuer: User;
  edited: boolean;
  approver?: User;
  description?: string;
  amountRequested?: number;
  amountAvailable?: number;
  amountInMoney: number;
  amountInTime: number;
  canReview?: boolean;
  attachments: TimeOffAttachment[];
  creator?: User;
  substituteApprover?: User;
  resolutionDate?: string;
};

export type ApprovalStep = {
  id: number;
  state: string;
  position: number;
  potentialApprovers: User[];
  potentialApproversCount: number;
  approver?: User;
  comment?: string;
};

export type VacationsNotificationsResponse = {
  vacationRequestsAsCollaboratorNotifications: number;
  vacationRequestsAsManagerNotifications: number;
};

export type TimeOffRequestedDaysResponse = {
  amount: number;
  errors: Record<string, unknown>;
  warnings: Record<string, unknown>;
  amountInMoney: number;
  amountInTime: number;
};

export type TimeOffRequestedDaysResponseEdit = TimeOffRequestedDaysResponse & {
  amountDiff: number;
};

export type BalanceReport = {
  amountRequested: number;
  currentBalance?: number;
  policy: Partial<PolicyTypes> & {
    accumulationFrequency: string;
    accumulationMoment: string;
    allowanceAmount: number;
    allowanceStart: string;
    approvalRequired: boolean;
    dismissalApportionmentMethod: string;
    hiringApportionmentMethod: string;
    peopleAmount: number;
    policyType: PolicyTypes;
  };
  user: User;
};

export type ListTitleTableVacations = {
  id: string;
  text: string;
  align?: TableCellProps['align'];
};

export type BalanceConformationCustomData = {
  fromDate: string;
  toDate: string;
  observations: string | null;
  responsibleUserId: number | null;
  fromDateCycle: string;
  toDateCycle: string;
};

export type BalanceConformationType = {
  id: number;
  amount: number;
  fromDate: string;
  toDate: string;
  expirationDate?: string;
  isDefaultForAddition: boolean;
  isDefaultForSubtraction: boolean;
};

export type RegionInfo = {
  createdAt: string;
  id: number;
  body: string;
  title: string;
  updatedAt: string;
};

export type CalendarUser = {
  deleted: boolean;
  email: string | null;
  employeeInternalId: string;
  firstName: string;
  lastName: string;
  profilePicture: string | null;
  workdays: string[];
};

export type CalendarRequests = {
  user: CalendarUser;
  region: RegionInfo;
  requests: ResponseRequestTimeOff[];
  holidays: HolidaysInfo[];
};

export type HolidaysInfo = {
  name: string;
  date: string;
  title: string;
};

export type HolidayByDate = {
  date: string;
  name?: string;
  title?: string;
};

export type HolidaysByDateParams = {
  fromDate: string;
  toDate: string;
  userId?: number;
};

export type ParamsGetWidthToRenderRequestInCalendar = {
  request: ResponseRequestTimeOff;
  differentsMonth?: boolean;
  amountDaysInMonth?: number;
  cellWidth?: number;
};

export type Policy = {
  id: number;
  name: string;
  policyType: PolicyTypes;
};

export type ExtraFieldsReport = {
  fields?: string;
  groupIds?: string;
  userFields?: string;
};

export enum VacationsRequestSort {
  CREATED_AT = 'CREATED_AT',
  FROM_DATE = 'FROM_DATE',
  STATE = 'STATE',
}

export enum Visibility {
  ALL = 'ALL',
  DIRECT_TEAM = 'DIRECT_TEAM',
  INDIRECT_TEAM = 'INDIRECT_TEAM',
}

export type VacationsFilterValues = {
  users: User[];
  fromDate: string | null;
  toDate: string | null;
  policyTypeIds: Record<number, boolean>;
  policyIds: Record<number, boolean>;
  states: Partial<Record<VacationStatus, boolean>>;
  onlyPeopleWithRequests: boolean;
  segmentation: Record<string, any>;
  orderBy?: VacationsRequestSort;
  order?: string;
  visibility: {
    all: boolean;
    directTeam: boolean;
    indirectTeam: boolean;
  };
};

export type TimeoffAdvancedReportValues = {
  requestFields: Record<string, boolean>;
  segmentations: Record<string, boolean>;
  profileFields: Record<string, boolean>;
  extensionType: string;
  customError: string | null;
};

export type TimeOffRequestValues = {
  fromDate: Date;
  toDate: Date;
  consumptionTypeFromDate: ConsumptionType;
  consumptionTypeToDate: ConsumptionType;
  description?: string;
  user: MeUser;
  policyTypeId: { value: number; label: string };
  attachments?: Attachment[];
  issuerId?: number;
  skipApproval?: boolean;
  fromHour: string;
  fromHourTime: string;
  toHour: string;
  toHourTime: string;
  hoursRequestType: HoursRequestType | null;
  hasSellingBalance: boolean;
  amountInMoney: { value: number; label: string } | null;
  substituteApprover?: User | null;
  hasSubstituteApprover?: boolean;
};

export type TimeOffAttachment = Attachment & {
  bytes: number;
};

export type FutureBalanceResponse = {
  cycle: { startDate: string; endDate: string };
  newAllowance: number;
  remnantCarriedOver: number;
  futureRequestsAmount: number;
  totalAvailable: number;
};

export type GetRequestToCalendarParams = {
  page: number;
  limit: number;
  month: string;
  filters: VacationsFilterValues;
};

export type GetVacationsDetailParams = {
  collaboratorCalendarView?: boolean;
};

export type Vacations = ResponseRequestTimeOff[];
export type BalanceConfomationResponse = Pagination<BalanceConformationType[]>;
export type VacationsPaginated = Pagination<Vacations>;
export type PolicyTypesResponse = PolicyTypes[];
export type PoliciesResponse = Policy[];
export type ResponsePolicyTypesBalance = PolicyTypesBalance[];
export type ResponseBalanceReport = Pagination<BalanceReport[]>;
export type ResponseRequestCalendar = Pagination<CalendarRequests[]>;
export type ApprovalStepsType = ApprovalStep[];

export type DownloadReportBalancesResponse = { sendByEmail: boolean } | Blob;
