import { isNull } from "../../helpers/IsNull";
import { validatePermissionsByCompany, validateSessionUser } from "../../helpers/check";
import { TextObjectFilterResult } from "../TextObjectFilter.model";
import { DiscountsAdapterMongoose } from "./Discounts.Adapter.Mongoose";
import {
    IDiscountsManager,
    CreateDiscountParams,
    DeleteDiscountParams,
    IDiscount,
    PaginateDiscountsParams,
    PaginateDiscountsResults,
    FindDiscountsParams,
    DiscountType,
    DeleteDiscountsByCompanyParams,
} from "./Discounts.Interface";

export class DiscountsManager implements IDiscountsManager {
    discounts: DiscountsAdapterMongoose;

    constructor() {
        this.discounts = new DiscountsAdapterMongoose();
    }

    public async deleteDiscountsByCompany(data: DeleteDiscountsByCompanyParams): Promise<void> {
        await this.discounts.discountsList.deleteMany({
            companyId: data.companyId,
        });
    }

    async createDiscount(data: CreateDiscountParams): Promise<IDiscount> {
        await validateSessionUser({
            sessionUser: data.sessionUser,
        });

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

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

        if (checkDiscount) {
            throw new Error("Ya existe un descuento con el mismo código");
        }

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

        if (!discount) {
            throw new Error("Error creating discount");
        }

        return discount;
    }

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

        const discount = await this.discounts.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.discounts.delete(data);
    }

    async paginate(data: PaginateDiscountsParams): Promise<PaginateDiscountsResults> {
        return this.discounts.paginate(data);
    }

    public async textObjectFilter(data: FindDiscountsParams): Promise<TextObjectFilterResult[]> {
        const discounts = await this.discounts.find(data);
        const formattedResult: TextObjectFilterResult[] = [];

        for (const item of discounts) {
            formattedResult.push({
                id: isNull<string>(item.id, ""),
                name: item.name,
                image: "",
            });
        }

        return formattedResult;
    }

    public async getDiscountData(
        discountId: string | undefined,
        companyId: string
    ): Promise<IDiscount> {
        const noDiscount = {
            name: "",
            value: 0,
            type: DiscountType.PERCENTAGE,
            code: "",
            companyId: companyId,
        } as IDiscount;

        if (!discountId) {
            return noDiscount;
        }

        const discount = await this.discounts.discountsList.findOne({
            _id: discountId,
            companyId: companyId,
        });

        if (!discount) {
            return noDiscount;
        }

        return (await discount) as IDiscount;
    }
}

export default new DiscountsManager();
