import { validatePermissionsByCompany, validateSessionUser } from "../../helpers/check";
import {
    CreateDiscountEmailParams,
    DeleteDiscountEmailParams,
    DeleteDiscountsEmailByCompanyParams,
    DiscountEmailView,
    IDiscountEmail,
    IDiscountsEmailManager,
    PaginateDiscountsEmailParams,
    PaginateDiscountsEmailViewResults,
} from "./DiscountsEmail.Interface";
import { DiscountsEmailAdapterMongoose } from "./DiscountsEmail.Adapter.Mongoose";
import Discounts from "../Discounts/Discounts";
import { isNull } from "../../helpers/IsNull";

export class DiscountsEmailManager implements IDiscountsEmailManager {
    discountsEmail: DiscountsEmailAdapterMongoose;

    constructor() {
        this.discountsEmail = new DiscountsEmailAdapterMongoose();
    }

    public async deleteDiscountsEmailByCompany(data: DeleteDiscountsEmailByCompanyParams): Promise<void> {
        await this.discountsEmail.deleteMany({
            companyId: data.companyId,
        });
    }

    async createDiscountEmail(data: CreateDiscountEmailParams): Promise<IDiscountEmail> {
        await validateSessionUser({
            sessionUser: data.sessionUser,
        });

        await validatePermissionsByCompany({
            companyId: data.companyId,
            sessionUser: data.sessionUser,
        });

        const checkDiscount = await this.discountsEmail.findOne({
            companyId: data.companyId,
            email: data.email,
        });

        if (checkDiscount) {
            throw new Error(
                "Ya existe un descuento registrado para el correo electrónico. Si el mismo no esta vigente, debe ser eliminado para crear uno nuevo."
            );
        }

        // La lógica de negocio se implementará aquí
        const discount = this.discountsEmail.create(data);

        if (!discount) {
            throw new Error("No se ha podido crear el descuento.");
        }

        return discount;
    }

    async deleteDiscountEmail(data: DeleteDiscountEmailParams): Promise<void> {
        await validateSessionUser({
            sessionUser: data.sessionUser,
        });

        const discount = await this.discountsEmail.findOne({ id: data.id, companyId: data.companyId });

        if (!discount) {
            throw new Error("El descuento que intenta eliminar no existe");
        }

        await validatePermissionsByCompany({
            companyId: String(discount.companyId),
            sessionUser: data.sessionUser,
        });

        await this.discountsEmail.delete(data);
    }

    async paginate(data: PaginateDiscountsEmailParams): Promise<PaginateDiscountsEmailViewResults> {
        const paginationData = await this.discountsEmail.paginate(data);
        const returnData: PaginateDiscountsEmailViewResults = {
            data: [],
            page: paginationData.page,
            pages: paginationData.pages,
        };

        let items: DiscountEmailView[] = [];

        for (const item of paginationData.data) {
            const discount = await Discounts.discounts.discountsList.findOne({ _id: item.discountId });

            if (!discount) continue;

            const returnItem: DiscountEmailView = {
                id: isNull<string>(item.id, ""),
                email: item.email,
                companyId: item.companyId,
                discountId: item.discountId,
                discountName: discount.name,
                discountType: discount.type,
                discountValue: discount.value,
                discountCode: discount.code,
                startDate: item.startDate,
                endDate: item.endDate,
            };
            items.push(returnItem);
        }

        returnData.data = items;

        return returnData;
    }
}

export default new DiscountsEmailManager();
