import {
    FindEmployeesParams,
    IEmployeesAdapter,
    IEmployee,
    CreateEmployeeParams,
    PaginateEmployeesParams,
    PaginateEmployeesResults,
} from "./Employees.Interface";
import { Document, Model, Schema, model } from "mongoose";

export interface IEmployeeDocument extends Omit<IEmployee, "id">, Document {}

export class EmployeesAdapterMongoose implements IEmployeesAdapter {
    schema: Schema;
    employeeList: Model<IEmployeeDocument>;

    constructor() {
        this.schema = new Schema({
            userId: { type: Schema.Types.ObjectId, required: true, ref: "User" },
            companyId: { type: Schema.Types.ObjectId, required: true, ref: "Companie" },
            roles: { type: Array, required: true },
            calendarColor: { type: String, required: false },
            limit: { type: Number, required: true, default: -1 },
            hostOk: { type: Boolean, required: true, default: false },
            guestOk: { type: Boolean, required: true, default: false },
            creationDate: { type: Date, required: true, default: Date.now },
        });

        this.employeeList = model<IEmployeeDocument>("Employee", this.schema);
    }

    public async create(data: CreateEmployeeParams): Promise<IEmployee> {
        return await this.employeeList.create(data);
    }

    public async delete(id: string): Promise<void> {
        console.log("delete employee", id);
    }

    public async find(filters: FindEmployeesParams): Promise<IEmployee[]> {
        return this.employeeList.find(filters).exec();
    }

    public async findOne(filters: FindEmployeesParams): Promise<IEmployeeDocument | null> {
        return this.employeeList.findOne(filters).exec();
    }

    public async paginate(filters: PaginateEmployeesParams): Promise<PaginateEmployeesResults> {
        const { page, limit, ...findFilters } = filters; //Extract page and limit from filters
        const count = await this.employeeList.countDocuments(findFilters).exec();
        const skip = (page - 1) * limit;

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

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