import dayjs from "dayjs";
import { HeatMapAdapterMongoose } from "./HeatMap.Adapter.Mongoose";
import {
    CreateHeatMapParams,
    UpdateHeatMapParams,
    FindHeatMapParams,
    IHeatMap,
    IHeatMapManager,
    DeleteHeatMapParams,
    DeleteHeatMapByCompanyParams,
    DeleteHeatMapByEmployeeParams,
} from "./HeatMap.Interface";

class HeatMapManager implements IHeatMapManager {
    heatMaps: HeatMapAdapterMongoose;

    constructor() {
        this.heatMaps = new HeatMapAdapterMongoose();
    }

    public async deleteHeatMapByEmployee(data: DeleteHeatMapByEmployeeParams): Promise<void> {
        await this.cleanUpHeatMap();
        await this.heatMaps.heatMapList.deleteMany({ employeeId: data.employeeId });
    }

    public async deleteHeatMapByCompany(data: DeleteHeatMapByCompanyParams): Promise<void> {
        await this.cleanUpHeatMap();
        await this.heatMaps.heatMapList.deleteMany({ companyId: data.companyId });
    }

    public async createHeatMap(data: CreateHeatMapParams): Promise<IHeatMap> {
        await this.cleanUpHeatMap();

        const checkHeatMap = await this.heatMaps.findOne({
            companyId: data.companyId,
            serviceId: data.serviceId,
            employeeId: data.employeeId,
            heatMapDate: data.heatMapDate,
        });

        if (checkHeatMap) {
            throw new Error("El mapa de calor ya existe");
        }

        const newHeatMap = await this.heatMaps.create(data);

        return newHeatMap;
    }

    public async updateHeatMap(data: UpdateHeatMapParams): Promise<void> {
        await this.cleanUpHeatMap();

        const checkHeatMap = await this.heatMaps.findOne({
            companyId: data.companyId,
            serviceId: data.serviceId,
            employeeId: data.employeeId,
            heatMapDate: data.heatMapDate,
        });

        if (!checkHeatMap) {
            throw new Error("El mapa de calor no existe");
        }

        await this.heatMaps.update(data);
    }

    public async findOne(filters: FindHeatMapParams): Promise<IHeatMap | null> {
        await this.cleanUpHeatMap();
        return this.heatMaps.findOne(filters);
    }

    public async find(filters: FindHeatMapParams): Promise<IHeatMap[]> {
        await this.cleanUpHeatMap();
        return this.heatMaps.find(filters);
    }

    public async deleteHeatMapByDate(data: DeleteHeatMapParams): Promise<void> {
        await this.cleanUpHeatMap();
        await this.heatMaps.heatMapList.deleteMany(data);
    }

    public async cleanUpHeatMap(): Promise<void> {
        const today = dayjs();
        const yesterday = today.add(-1, "day");
        await this.heatMaps.heatMapList.deleteMany({ heatMapDate: { $lt: yesterday.toDate() } });
    }
}

const HeatMapList = new HeatMapManager();

export default HeatMapList;
