import {
    CreateServiceParams,
    UpdateServiceParams,
    IService,
    CompanyServiceView,
    SetPublishedStatusParams,
    ApplyDiscountParams,
    DeleteDiscountParams,
} from "@models/Service.model";
import ApiRequest from "@services/Api.Service";
import { ApiVoidResult } from "@models/Api.VoidResult.type";
import * as Yup from "yup";

const schema = Yup.object().shape({
    name: Yup.string().required("Debe introducir el nombre del servicio."),
    description: Yup.string().required("Debe introducir la descripción del servicio."),
    originalPrice: Yup.number()
        .required("Debe introducir el precio del servicio.")
        .typeError("El precio debe ser un número.")
        .positive("El precio debe ser un número positivo."),
    limit: Yup.number()
        .required("Debe introducir el limite del servicio.")
        .typeError("El limite debe ser un número.")
        .positive("El limite debe ser un número positivo."),
    length: Yup.number()
        .required("Debe introducir la duración del servicio.")
        .typeError("La duración debe ser un número expresado en minutos.")
        .positive("El La duración debe ser un número positivo expresado en minutos."),
    sessionUser: Yup.string().required("Para crear una organización debe iniciar sesión."),
});

const schemaApplyDiscount = Yup.object().shape({
    discountId: Yup.string().required("No se ha seleccionado un descuento para aplicar."),
    companyId: Yup.string().required(
        "Para aplicar el descuento debe seleccionar una organización."
    ),
    serviceId: Yup.string().required("Para aplicar el descuento debe seleccionar un servicio."),
    sessionUser: Yup.string().required("Para crear una organización debe iniciar sesión."),
});

const schemaDeleteDiscount = Yup.object().shape({
    companyId: Yup.string().required(
        "Para aplicar el descuento debe seleccionar una organización."
    ),
    serviceId: Yup.string().required("Para aplicar el descuento debe seleccionar un servicio."),
    sessionUser: Yup.string().required("Para crear una organización debe iniciar sesión."),
});

export const savePublishedStatus = async (
    data: SetPublishedStatusParams
): Promise<ApiVoidResult> => {
    return ApiRequest.post<ApiVoidResult>("services/set-published-status", data);
};

export const loadServicesByCompany = async (companyId: string): Promise<CompanyServiceView[]> => {
    return ApiRequest.post<CompanyServiceView[]>("services/get-by-company", {
        companyId: companyId,
    });
};

export const loadServicesById = async (serviceId: string): Promise<CompanyServiceView> => {
    return ApiRequest.post<CompanyServiceView>("services/get-by-id", {
        serviceId: serviceId,
    });
};

export const createService = async (data: CreateServiceParams): Promise<IService> => {
    let yupErrors: Yup.ValidationError = new Yup.ValidationError("");

    const validateData = async () => {
        try {
            await schema.validate(data, { abortEarly: true });
            return true;
        } catch (error) {
            if (error instanceof Yup.ValidationError) {
                yupErrors = error as Yup.ValidationError;
            }
            return false;
        }
    };

    if ((await validateData()) == false) {
        throw new Error(yupErrors.message);
    }

    return ApiRequest.post<IService>("services/create", data);
};

export const updateService = async (data: UpdateServiceParams): Promise<ApiVoidResult> => {
    let yupErrors: Yup.ValidationError = new Yup.ValidationError("");

    const validateData = async () => {
        try {
            await schema.validate(data, { abortEarly: true });

            if (!data.id || data.id == "") {
                throw new Yup.ValidationError("Servicio desconocido. No es posible actualizar");
            }
            return true;
        } catch (error) {
            if (error instanceof Yup.ValidationError) {
                yupErrors = error as Yup.ValidationError;
            }
            return false;
        }
    };

    if ((await validateData()) == false) {
        throw new Error(yupErrors.message);
    }

    return ApiRequest.post<ApiVoidResult>("services/update", data);
};

export const uploadImage = async (data: FormData): Promise<ApiVoidResult> => {
    return ApiRequest.postFile<ApiVoidResult>("services/upload-image", data);
};

export const applyDiscount = async (data: ApplyDiscountParams): Promise<ApiVoidResult> => {
    let yupErrors: Yup.ValidationError = new Yup.ValidationError("");

    const validateData = async () => {
        try {
            await schemaApplyDiscount.validate(data, { abortEarly: true });
            return true;
        } catch (error) {
            if (error instanceof Yup.ValidationError) {
                yupErrors = error as Yup.ValidationError;
            }
            return false;
        }
    };

    if ((await validateData()) == false) {
        throw new Error(yupErrors.message);
    }

    return ApiRequest.post<ApiVoidResult>("services/apply-discount", data);
};

export const deleteDiscount = async (data: DeleteDiscountParams): Promise<ApiVoidResult> => {
    let yupErrors: Yup.ValidationError = new Yup.ValidationError("");

    const validateData = async () => {
        try {
            await schemaDeleteDiscount.validate(data, { abortEarly: true });
            return true;
        } catch (error) {
            if (error instanceof Yup.ValidationError) {
                yupErrors = error as Yup.ValidationError;
            }
            return false;
        }
    };

    if ((await validateData()) == false) {
        throw new Error(yupErrors.message);
    }

    return ApiRequest.post<ApiVoidResult>("services/delete-discount", data);
};
