import { MapAddresse } from "./infrastructure";

interface BaseEntity {
    id?: number;
    createdAt?: string;
    updatedAt?: string;
}

export interface Address extends BaseEntity {
    street?: string;
    zipCode?: string;
    city?: string;
    country?: string;
    additionalAddress?: string;
    latitude: number;
    longitude: number;
    addressType?: AddressType;
}

export enum AddressType {
    COLLABORATOR = 'COLLABORATOR',
    CLIENT = 'CLIENT',
    ESTABLISHMENT = 'ESTABLISHMENT',
    REPRESENTATIVE = 'REPRESENTATIVE',
    BANQUE = 'BANQUE',
    DRIVER = 'DRIVER',
    PICKUP = 'PICKUP_ADDRESS'
}

export enum EstablishmentSector {
    PRIVATE = "PRIVATE",
    PUBLIC = "PUBLIC"
}

export const establishmentSectorLabelsFr: Record<EstablishmentSector, string> = {
    [EstablishmentSector.PRIVATE]: "Privé",
    [EstablishmentSector.PUBLIC]: "Public"
}

export enum EstablishmentType {
    PRIMARY_SCHOOL = "PRIMARY_SCHOOL",
    MIDDLE_SCHOOL = "MIDDLE_SCHOOL",
    HIGH_SCHOOL = "HIGH_SCHOOL"
}

export const establishmentTypeLabelsFr: Record<EstablishmentType, string> = {
    [EstablishmentType.PRIMARY_SCHOOL]: "École primaire",
    [EstablishmentType.MIDDLE_SCHOOL]: "Collège",
    [EstablishmentType.HIGH_SCHOOL]: "Lycée"
}

export enum DayOfWeek {
    MONDAY = "MONDAY",
    TUESDAY = "TUESDAY",
    WEDNESDAY = "WEDNESDAY",
    THURSDAY = "THURSDAY",
    FRIDAY = "FRIDAY",
    SATURDAY = "SATURDAY",
    SUNDAY = "SUNDAY"
}

export const dayOfWeekLabelsFr: Record<DayOfWeek, string> = {
    [DayOfWeek.MONDAY]: "Lundi",
    [DayOfWeek.TUESDAY]: "Mardi",
    [DayOfWeek.WEDNESDAY]: "Mercredi",
    [DayOfWeek.THURSDAY]: "Jeudi",
    [DayOfWeek.FRIDAY]: "Vendredi",
    [DayOfWeek.SATURDAY]: "Samedi",
    [DayOfWeek.SUNDAY]: "Dimanche"
}

export interface EstablishmentPageFilterParams {
    id?: number;
    establishmentCode?: string;
    establishmentName?: string;
    addressId?: number;
    establishmentSector?: EstablishmentSector;
    establishmentType?: EstablishmentType;
    page?: number;
    size?: number;
    sortBy?: string;
    sortDirection?: 'asc' | 'desc';
}

export interface EstablishmentTableItem {
    id: string;
    establishmentName: string;
    address: Address;
    establishmentSector: EstablishmentSector;
    uaiCode: string;
    hours: EstablishmentHoursResponse[];
    phoneNumber: string;
    establishmentType: EstablishmentType;
    departmentName: string;
    active: boolean;
}

export const ESTABLISHMENT_SECTOR_OPTIONS = [
    { value: EstablishmentSector.PRIVATE, label: "Privé" },
    { value: EstablishmentSector.PUBLIC, label: "Public" },
]

export const ESTABLISHMENT_TYPE_OPTIONS = [
    { value: EstablishmentType.PRIMARY_SCHOOL, label: "Primaire" },
    { value: EstablishmentType.MIDDLE_SCHOOL, label: "Collège" },
    { value: EstablishmentType.HIGH_SCHOOL, label: "Lycée" },
]

export interface EstablishmentRequest {
    id: string;
    establishmentCode: string;
    establishmentName: string;
    mapAddress: MapAddresse;
    establishmentSector: EstablishmentSector;
    uaiCode: string;
    phoneNumber: string;
    establishmentType: EstablishmentType;
    establishmentManager: EstablishmentManager;
    mondayMorningOpeningTime: string;
    mondayEveningClosingTime: string;
    tuesdayMorningOpeningTime: string;
    tuesdayEveningClosingTime: string;
    wednesdayMorningOpeningTime: string;
    wednesdayEveningClosingTime: string;
    thursdayMorningOpeningTime: string;
    thursdayEveningClosingTime: string;
    fridayMorningOpeningTime: string;
    fridayEveningClosingTime: string;
    saturdayMorningOpeningTime: string;
    saturdayEveningClosingTime: string;
    sundayMorningOpeningTime: string;
    sundayEveningClosingTime: string;
    responsibleCivility: CIVILITY;
    responsibleFirstName: string;
    responsibleLastName: string;
    responsiblePhoneNumber: string;
    responsibleEmail: string;
    colorCode: string;
    fax: string;
    email: string;
    website: string;
    doId: string;
    doCode: string;
    documentsIds?: number[];
    active: boolean;
    archived: boolean;
    departmentId: number;
    departmentName: string;
    zoneId: number;
    zoneName: string;
    observation?: string;
    academy: string;
}

export const mapEstablishmentToEstablishmentRequest = (establishment: Establishment): EstablishmentRequest => {
    return {
        ...establishment,
        mapAddress: mapAddressToMapAddresse(establishment.address),
        responsibleCivility: (establishment.establishmentManager !== null && establishment.establishmentManager.civility !== null) ? establishment.establishmentManager.civility : CIVILITY.MR,
        responsibleFirstName: (establishment.establishmentManager !== null && establishment.establishmentManager.firstName !== null) ? establishment.establishmentManager.firstName : "",
        responsibleLastName: (establishment.establishmentManager !== null && establishment.establishmentManager.lastName !== null) ? establishment.establishmentManager.lastName : "",
        responsiblePhoneNumber: (establishment.establishmentManager !== null && establishment.establishmentManager.phoneNumber !== null) ? establishment.establishmentManager.phoneNumber : "",
        responsibleEmail: (establishment.establishmentManager !== null && establishment.establishmentManager.personalEmail !== null) ? establishment.establishmentManager.personalEmail : "",
        mondayMorningOpeningTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.MONDAY)?.morningOpeningTime || "",
        mondayEveningClosingTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.MONDAY)?.eveningClosingTime || "",
        tuesdayMorningOpeningTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.TUESDAY)?.morningOpeningTime || "",
        tuesdayEveningClosingTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.TUESDAY)?.eveningClosingTime || "",
        wednesdayMorningOpeningTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.WEDNESDAY)?.morningOpeningTime || "",
        wednesdayEveningClosingTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.WEDNESDAY)?.eveningClosingTime || "",
        thursdayMorningOpeningTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.THURSDAY)?.morningOpeningTime || "",
        thursdayEveningClosingTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.THURSDAY)?.eveningClosingTime || "",
        fridayMorningOpeningTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.FRIDAY)?.morningOpeningTime || "",
        fridayEveningClosingTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.FRIDAY)?.eveningClosingTime || "",
        saturdayMorningOpeningTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.SATURDAY)?.morningOpeningTime || "",
        saturdayEveningClosingTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.SATURDAY)?.eveningClosingTime || "",
        sundayMorningOpeningTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.SUNDAY)?.morningOpeningTime || "",
        sundayEveningClosingTime: establishment.hours.find(h => h.dayOfWeek === DayOfWeek.SUNDAY)?.eveningClosingTime || "",
        academy: establishment.academy,
    }
}

export enum CIVILITY {
    MR = "MR",
    MME = "MME"
}

export const CIVILITY_OPTIONS = [
    { value: CIVILITY.MR, label: "M." },
    { value: CIVILITY.MME, label: "Mme." },
];

export interface EstablishmentHoursResponse extends BaseEntity {
    dayOfWeek: DayOfWeek;
    morningOpeningTime: string;
    eveningClosingTime: string;
    establishmentId: number;
}

export interface UpdateEstablishmentHoursRequest {
    mondayMorningOpeningTime: string;
    mondayEveningClosingTime: string;
    tuesdayMorningOpeningTime: string;
    tuesdayEveningClosingTime: string;
    wednesdayMorningOpeningTime: string;
    wednesdayEveningClosingTime: string;
    thursdayMorningOpeningTime: string;
    thursdayEveningClosingTime: string;
    fridayMorningOpeningTime: string;
    fridayEveningClosingTime: string;
    saturdayMorningOpeningTime: string;
    saturdayEveningClosingTime: string;
    sundayMorningOpeningTime: string;
    sundayEveningClosingTime: string;
}

export interface EstablishmentManager {
    id: number;
    civility: CIVILITY;
    firstName: string;
    lastName: string;
    personalEmail: string;
    phoneNumber: string;
}

export interface Establishment {
    id: string;
    createdAt: string;
    updatedAt: string;
    establishmentCode: string;
    establishmentName: string;
    address: Address;
    establishmentSector: EstablishmentSector;
    uaiCode: string;
    phoneNumber: string;
    establishmentType: EstablishmentType;
    colorCode: string;
    fax: string;
    email: string;
    website: string;
    doId: string;
    doCode: string;
    documentsIds?: number[];
    observation?: string;
    establishmentManager: EstablishmentManager;
    hours: EstablishmentHoursResponse[];
    departmentId: number;
    departmentName: string;
    zoneId: number;
    zoneName: string;
    academy: string;
    active: boolean;
    archived: boolean;
}

export interface EstablishmentNameAndId {
    id: string;
    name: string;
}

/************  GENERAL HOLIDAY ************/
export interface IHolidayGeneral {
    id: string
    name: string;
    startDate: Date;
    endDate: Date;
    population: string;
    academy: string;
    zoneName: string;
    type: CalendarDayType;
}

export enum CalendarDayType {
    PUBLIC_HOLIDAY = "PUBLIC_HOLIDAY",
    SCHOOL_HOLIDAY = "SCHOOL_HOLIDAY",
}

export interface IHolidayCalendarFilterParams {
    year?: number;
    month?: number;
    userId?: string;
}

export interface IFileHolidayFilterParams {
    page?: number;
    size?: number;
    sortBy?: string;
    sortDirection?: string;
    name?: string;
    uploadedBy?: string;
    uploadedAt?: string;
}

export interface BulkZoneHolidayImport {
    holidayImportName: string;
    importDate: string;
    importedBy: string;
}

export interface BulkZoneHolidayChildren {
    name: string;
    startDate: string;
    endDate: string;
    holidayType: HolidayType;
    population: string;
    academy: string;
    zoneName: string;
}

export enum HolidayType {
    PUBLIC_HOLIDAY = "PUBLIC_HOLIDAY",
    SCHOOL_HOLIDAY = "SCHOOL_HOLIDAY"
}

export const HOLIDAY_TYPE_OPTIONS = [
    { value: HolidayType.PUBLIC_HOLIDAY, label: "Jour férié" },
    { value: HolidayType.SCHOOL_HOLIDAY, label: "Vacance scolaire" },
]


/************  HOLIDAY IMPORT ZONE FORM ************/
export interface IHolidayImport {
    id: string
    holidayImportName: string
    createdAt: string
    importedBy: string
    zones: IHolidayZoneImport[]
}

export interface IHolidayZoneImport {
    zoneName: string
    holidays: IHolidayImportChildren[]
}

export interface IHolidayImportChildren {
    id: string
    name: string
    startDate: string
    endDate: string
    type: string
    academy: string
    population: string
    zoneName: string
}

export interface IHolidayImportFilterParams {
    page?: number;
    size?: number;
    sortBy?: string;
    sortDirection?: string;
    holidayImportName?: string;
    createdAt?: string;
    importedByName?: string;
    year?: number;
    month?: number;
    userId?: string;
}

export const mapAddressToMapAddresse = (address: Address): MapAddresse => {
    const { street, zipCode, city, country } = address;

    const addressParts = [
        street && `${street}`,
        zipCode && `${zipCode}`,
        city && `${city}`,
        country && `${country}`
    ].filter(Boolean).join(", ");

    return {
        address: addressParts,
        lat: address.latitude,
        lng: address.longitude,
        city: city || '',
        postalCode: zipCode || '',
        country: country || '',
        formattedAddress: addressParts,
        placeId: ''
    };
};