import ApiRequest from "@services/Api.Service";
import {
    ApplyAppointmentDiscountParams,
    AppointmentAdminByClientView,
    AppointmentEventByClient,
    DeleteAppointmentDiscountParams,
    DeleteAppointmentParams,
    FindAppointmentsParams,
    GetAppointmentEventParams,
    SendAppointmentNotificationParams,
    UpdateAppointmentParams,
} from "@models/Appointments.model";
import { ApiVoidResult } from "@core/Models/Api.VoidResult.type";
import * as Yup from "yup";
import { ChangeServiceParams } from "@models/Appointments.model";
import { ApiError } from "@core/Models/Server.Error.model";

export const getAppointmentEvent = async (
    data: GetAppointmentEventParams
): Promise<AppointmentEventByClient> => {
    return ApiRequest.post<AppointmentEventByClient>("appointments/get-event", data);
};

export const findAppointmentsAdminByClient = async (
    data: FindAppointmentsParams
): Promise<AppointmentAdminByClientView> => {
    return ApiRequest.post<AppointmentAdminByClientView>("appointments/find-admin-by-client", data);
};

export const deleteAppointment = async (data: DeleteAppointmentParams): Promise<ApiVoidResult> => {
    return ApiRequest.post<ApiVoidResult>("appointments/delete", data);
};

const schemaAppointmentUpdate = Yup.object().shape({
    id: Yup.string().required("Debe seleccionar un turno."),
    start: Yup.string().required("Debe seleccionar una fecha."),
    price: Yup.number().positive().required("Debe introducir un precio valido."),
    length: Yup.number().positive().required("Debe introducir una duración."),
    comments: Yup.string().required("Debe introducir un comentario."),
    sessionUser: Yup.string().required("Para crear un turno debe iniciar sesión."),
});

export const updateAppointment = async (data: UpdateAppointmentParams): Promise<ApiVoidResult> => {
    return new Promise<ApiVoidResult>((resolve, reject) => {
        schemaAppointmentUpdate
            .validate(data, { abortEarly: true })
            .then(() => {
                resolve(ApiRequest.post<ApiVoidResult>("appointments/update", data));
            })
            .catch((error) => {
                reject(new ApiError(500, error.message));
            });
    });
};

const schemaSendWapNotification = Yup.object().shape({
    appointmentId: Yup.string().required("Debe seleccionar un turno."),
    type: Yup.string().required("Ha ocurrido un error al determinar el tipo de mensaje."),
    sessionUser: Yup.string().required("Para crear un turno debe iniciar sesión."),
});

export const sendWapNotification = async (
    data: SendAppointmentNotificationParams
): Promise<ApiVoidResult> => {
    return new Promise<ApiVoidResult>((resolve, reject) => {
        schemaSendWapNotification
            .validate(data, { abortEarly: true })
            .then(() => {
                resolve(ApiRequest.post<ApiVoidResult>("appointments/send-wap-notification", data));
            })
            .catch((error) => {
                reject(new ApiError(500, error.message));
            });
    });
};

export const sendEmailNotification = async (
    data: SendAppointmentNotificationParams
): Promise<ApiVoidResult> => {
    return new Promise<ApiVoidResult>((resolve, reject) => {
        schemaSendWapNotification
            .validate(data, { abortEarly: true })
            .then(() => {
                resolve(
                    ApiRequest.post<ApiVoidResult>("appointments/send-email-notification", data)
                );
            })
            .catch((error) => {
                reject(new ApiError(500, error.message));
            });
    });
};

const schemaApplyDiscount = Yup.object().shape({
    appointmentId: Yup.string().required("Debe seleccionar un turno."),
    companyId: Yup.string().required("Organización no seleccionada."),
    discountId: Yup.string().required("Debe seleccionar un descuento para aplicar."),
    sessionUser: Yup.string().required("Para aplicar el descuento debe iniciar sesión."),
});

const schemaDeleteDiscount = Yup.object().shape({
    appointmentId: Yup.string().required("Debe seleccionar un turno."),
    companyId: Yup.string().required("Organización no seleccionada."),
    sessionUser: Yup.string().required("Para aplicar el descuento debe iniciar sesión."),
});

export const applyAppointmentDiscount = async (
    data: ApplyAppointmentDiscountParams
): Promise<ApiVoidResult> => {
    return new Promise<ApiVoidResult>((resolve, reject) => {
        schemaApplyDiscount
            .validate(data, { abortEarly: true })
            .then(() => {
                resolve(ApiRequest.post<ApiVoidResult>("appointments/apply-discount", data));
            })
            .catch((error) => {
                reject(new ApiError(500, error.message));
            });
    });
};

export const deleteAppointmentDiscount = async (
    data: DeleteAppointmentDiscountParams
): Promise<ApiVoidResult> => {
    return new Promise<ApiVoidResult>((resolve, reject) => {
        schemaDeleteDiscount
            .validate(data, { abortEarly: true })
            .then(() => {
                resolve(ApiRequest.post<ApiVoidResult>("appointments/delete-discount", data));
            })
            .catch((error) => {
                reject(new ApiError(500, error.message));
            });
    });
};

export const changeAppointmentServiceForce = async (
    data: ChangeServiceParams
): Promise<ApiVoidResult> => {
    return new Promise<ApiVoidResult>((resolve, reject) => {
        ApiRequest.post<ApiVoidResult>("appointments/change-service-force", data)
            .then((res) => resolve(res))
            .catch((error: unknown) => {
                reject(new ApiError((error as any)?.response?.status || 500, ((error as any)?.response?.data as string) || "Ha ocurrido un error"));
            });
    });
};
