import { ISO_DATE, lodash, OptionalNumbersStringToNumbersArray, OptionalStringToStringsArray } from '@humand-packages/common';
import { Expose, Transform } from 'class-transformer';
import { IsArray, IsDefined, IsEmail, IsIn, IsNumber, IsOptional, IsString, MaxLength } from 'class-validator';
import { BooleanTransform } from '../../../../middlewares/classTransformers/booleanTransform';
import { IsValidDate } from '../../../../middlewares/dateValidator';
import { StaticUserFields } from '../../../profileFields/business/types/profileFields';
import { TimeTrackingEmployeeStatus } from '../../business/types/status';
import { Incidence } from '../../infrastructure/constants/incidences';

export class TimeTrackingDaySummaryFiltersVC {
    @IsDefined()
    @IsValidDate(ISO_DATE)
    @Expose()
    startDate!: string;

    @IsDefined()
    @IsValidDate(ISO_DATE)
    @Expose()
    endDate!: string;

    @IsOptional()
    @IsArray()
    @IsNumber({}, { each: true })
    @Expose()
    @OptionalNumbersStringToNumbersArray()
    departmentIds!: number[];

    @IsOptional()
    @IsArray()
    @IsNumber({}, { each: true })
    @Expose()
    @OptionalNumbersStringToNumbersArray()
    excludeDepartmentIds!: number[];

    @IsOptional()
    @IsArray()
    @IsNumber({}, { each: true })
    @Expose()
    @OptionalNumbersStringToNumbersArray()
    userIds!: number[];

    @IsOptional()
    @IsArray()
    @IsNumber({}, { each: true })
    @Expose()
    @OptionalNumbersStringToNumbersArray()
    itemIds!: number[];

    @IsOptional()
    @IsString()
    @MaxLength(255)
    @Expose()
    search?: string;

    @IsOptional()
    @BooleanTransform(false)
    @Expose()
    hasTimeOff!: boolean;

    @IsOptional()
    @BooleanTransform(false)
    @Expose()
    hasHolidays!: boolean;

    @IsOptional()
    @IsArray()
    @IsIn(Object.values(Incidence), { each: true })
    @Transform(({ value }) => (value ? (value as string).split(',').map((incidence) => incidence as Incidence) : []))
    @Expose()
    incidences!: Incidence[];

    @IsOptional()
    @IsArray()
    @IsIn(Object.values(TimeTrackingEmployeeStatus), { each: true })
    @Transform(({ value }) => (value ? (value as string).split(',').map((status) => status as TimeTrackingEmployeeStatus) : []))
    @Expose()
    status!: TimeTrackingEmployeeStatus[];

    @IsOptional()
    @IsArray()
    @IsNumber({}, { each: true })
    @Expose()
    @OptionalNumbersStringToNumbersArray()
    regionIds!: number[];

    @IsOptional()
    @IsArray()
    @IsNumber({}, { each: true })
    @Expose()
    @OptionalNumbersStringToNumbersArray()
    siteIds!: number[];

    @IsOptional()
    @IsArray()
    @IsNumber({}, { each: true })
    @Expose()
    @OptionalNumbersStringToNumbersArray()
    excludeSiteIds!: number[];

    @IsOptional()
    @BooleanTransform(false)
    @Expose()
    includeDeactivated!: boolean;
}

export class TimeTrackingDaySummaryWithScheduleFiltersVC extends TimeTrackingDaySummaryFiltersVC {
    @IsOptional()
    @BooleanTransform(false)
    @Expose()
    onlyNoSchedule!: boolean;

    @IsOptional()
    @BooleanTransform(false)
    @Expose()
    hasSchedule!: boolean;

    @IsOptional()
    @IsArray()
    @Expose()
    @OptionalStringToStringsArray()
    scheduleCodes!: string[];

    @IsOptional()
    @IsArray()
    @Expose()
    @OptionalStringToStringsArray()
    excludeScheduleCodes!: string[];
}

export enum TimeTrackingReportType {
    CONSOLIDATED = 'consolidated',
    DETAILED = 'detailed',
}

export class TimeTrackingDaySummaryWithReportFiltersVC extends TimeTrackingDaySummaryFiltersVC {
    @IsOptional()
    @Expose()
    @IsIn(Object.values(TimeTrackingReportType))
    type?: TimeTrackingReportType;

    @IsOptional()
    @IsIn(Object.values(StaticUserFields), { each: true })
    @OptionalStringToStringsArray([StaticUserFields.EMPLOYEE_INTERNAL_ID, StaticUserFields.COMPLETE_NAME])
    @Expose()
    userFields!: string[];

    @IsOptional()
    @IsArray()
    @IsNumber({}, { each: true })
    @Expose()
    @Transform(({ value }) => (value ? (value as string).split(',').map((groupId) => lodash.toNumber(groupId)) : undefined))
    groupIds?: number[];

    @IsOptional()
    @IsArray()
    @IsString({ each: true })
    @Expose()
    @Transform(({ value }) => (value ? (value as string).split(',') : undefined))
    userCustomFields?: string[];

    @IsOptional()
    @IsArray()
    @IsNumber({}, { each: true })
    @Expose()
    @OptionalNumbersStringToNumbersArray()
    hourCategoryIds?: number[];

    @IsOptional()
    @BooleanTransform(false)
    @Expose()
    includeScheduledTime!: boolean;

    @IsOptional()
    @BooleanTransform(false)
    @Expose()
    includeClockInOut!: boolean;

    @IsOptional()
    @BooleanTransform(false)
    @Expose()
    includeAutoCloseIncidence!: boolean;

    @IsOptional()
    @BooleanTransform(false)
    @Expose()
    includeKiosk!: boolean;

    @IsOptional()
    @IsEmail()
    @Expose()
    email?: string;
}
