import {
    FindSchedulesOverridesParams,
    ISchedulesOverridesAdapter,
    ISchedulesOverrides,
    CreateSchedulesOverridesParams,
    UpdateSchedulesOverridesParams,
    PaginateSchedulesOverridesParams,
    PaginateSchedulesOverridesResults,
} from "./SchedulesOverrides.Interface";
import { Document, Model, Schema, model } from "mongoose";

export interface ISchedulesOverridesDocument extends Omit<ISchedulesOverrides, "id">, Document {}

export class SchedulesOverridesAdapterMongoose implements ISchedulesOverridesAdapter {
    schema: Schema;
    schedulesOverridesList: Model<ISchedulesOverridesDocument>;

    constructor() {
        this.schema = new Schema({
            employeeId: { type: Schema.Types.ObjectId, required: true, ref: "Employee" },
            companyId: { type: Schema.Types.ObjectId, required: true, ref: "Companie" },
            schedules: { type: Array, required: true },
            date: { type: Date, required: true },
            creationDate: { type: Date, required: true, default: Date.now },
        });

        this.schedulesOverridesList = model<ISchedulesOverridesDocument>("ScheduleOverride", this.schema);
    }

    public async create(data: CreateSchedulesOverridesParams): Promise<ISchedulesOverrides> {
        return await this.schedulesOverridesList.create({
            employeeId: data.employeeId,
            companyId: data.companyId,
            schedules: data.schedules,
            date: data.date,
        });
    }

    public async update(data: UpdateSchedulesOverridesParams): Promise<void> {
        const updateSchedule = await this.schedulesOverridesList.findOne({
            companyId: data.companyId,
            employeeId: data.employeeId,
            date: data.date,
        });

        if (!updateSchedule) {
            throw new Error("ScheduleOverride not found");
        }

        if (data.schedules) {
            updateSchedule.schedules = data.schedules;
        }

        await updateSchedule.save();
    }

    public async delete(id: string): Promise<void> {
        await this.schedulesOverridesList.deleteOne({ _id: id }).exec();
    }

    public async find(filters: FindSchedulesOverridesParams): Promise<ISchedulesOverridesDocument[]> {
        return this.schedulesOverridesList.find(filters).exec();
    }

    public async findOne(filters: FindSchedulesOverridesParams): Promise<ISchedulesOverridesDocument | null> {
        return this.schedulesOverridesList.findOne(filters).exec();
    }

    public async paginate(filters: PaginateSchedulesOverridesParams): Promise<PaginateSchedulesOverridesResults> {
        const { page, limit, ...findFilters } = filters;
        const count = await this.schedulesOverridesList.countDocuments(findFilters).exec();
        const skip = (page - 1) * limit;

        const results = await this.schedulesOverridesList
            .find(findFilters)
            .skip(skip)
            .limit(limit)
            .exec();

        return {
            data: results,
            page: filters.page,
            pages: Math.ceil(count / limit) || 1,
        };
    }
}
