import { AdyenCheckout } from "@adyen/adyen-web/auto";
import { useMainStore } from "@/store";
import globalMethods from "@/global-methods";
import endpoints from "@/constants/endpoints";
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
import { paymentMethods } from "@/constants/payment-method-constants";
import applicationConfig from "@/constants/application-config";

export async function getSessionInfo(sessionId, encryptedSessionResult) {
    const order = useMainStore().order;
    const location = getLocationInfo(order);
    const workOrder = getWorkOrderLastSixDigits(order);
    const system = getSourceSystem();

    const request = {
        sessionId: sessionId,
        sessionResult: encryptedSessionResult,
        zipCodeCtu: location.zipCodeCtu,
        workOrderNumber: workOrder,
        sourceSystem: system,
    };

    const response = await globalMethods.callHttpClient({
        method: endpoints.GetAdyenSessionResult.method,
        endpoint: endpoints.GetAdyenSessionResult.url,
        payload: request,
        logApiCall: true
    });

    return response?.data;
}

export async function createAdyenCheckout({
    session: { id, sessionData },
    handlers: { onPaymentCompleted, onPaymentFailed, onError },
    options: { showPayButton = true, amount },
}) {
    const config = {
        session: {
            id: id,
            sessionData: sessionData,
        },
        clientKey: applicationConfig.ADYEN_CLIENT_KEY,
        environment: applicationConfig.ADYEN_ENVIRONMENT,
        locale: "en_US",
        countryCode: "US",
        showPayButton: showPayButton,
        translations: {
            en_US: {
                "creditCard.securityCode.label": "CVV/CVC",
            },
        },
        onPaymentCompleted: onPaymentCompleted,
        onPaymentFailed: onPaymentFailed,
        onError: onError,
    };

    if (amount !== undefined && amount !== null) {
        config.amount = {
            value: amount,
            currency: "USD",
        };
    }

    return await AdyenCheckout(config);
}

export function mapAdyenToIssPaymentMethod(adyenMethod) {
    const paymentMethodMap = {
        ["scheme"]: paymentMethods.CREDIT_CARD,
        ["afterpaytouch_US"]: paymentMethods.AFTERPAY,
        ["afterpaytouch"]: paymentMethods.AFTERPAY,
        ["paypal"]: paymentMethods.PAYPAL,
        ["applepay"]: paymentMethods.APPLEPAY,
    };

    const match = paymentMethodMap[adyenMethod];

    return match ?? paymentMethods.CREDIT_CARD;
}

export function mapIssToAdyenPaymentMethod(issMethod) {
    const paymentMethodMap = {
        [paymentMethods.CREDIT_CARD]: "scheme",
        [paymentMethods.AFTERPAY]: "afterpaytouch_US",
        [paymentMethods.PAYPAL]: "paypal",
        [paymentMethods.APPLEPAY]: "applepay",
        [paymentMethods.PayNow]: null,
        [paymentMethods.PAY_AT_TIME_OF_SERVICE]: null,
    };

    const match = paymentMethodMap[issMethod];

    return match;
}

export function generateCcToken(adyenSessionInfo) {
    const zipCode = useMainStore().order.customer.address.zipCode
                ?? useMainStore().order.serviceLocation.zipCode
                ?? useMainStore().order.serviceLocation.provider.address.zipCode

    const ccToken = {
        subscriptionId: adyenSessionInfo?.storedToken,
        expMonth: adyenSessionInfo?.cardExpiryMonth,
        expYear: adyenSessionInfo?.cardExpiryYear,
        cardType: adyenSessionInfo?.cardType,
        billToPostalCode: zipCode,
        billToFirstName: useMainStore().contactInfo.firstName,
        billToLastName: useMainStore().contactInfo.lastName,
        referenceNumber: adyenSessionInfo?.workOrderNumber,
        authCode: adyenSessionInfo?.authCode,
        transactionId: adyenSessionInfo?.transactionReference,
        transReferenceNumber: adyenSessionInfo?.transactionReference,
        lastFour: adyenSessionInfo?.last4DigitsOfCard,
    };

    return ccToken;
}

function getLocationInfo(order) {
    const serviceLocation = order.serviceLocation;
    const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE ||
        serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
    if (isMobile) {
        return {
            address: serviceLocation.address,
            address2: serviceLocation.address2,
            city: serviceLocation.city,
            state: serviceLocation.state,
            zipCode: serviceLocation.zipCode,
            zipCodeCtu: serviceLocation.zipCodeCtu,
        };
    } else {
        const providerInfo = serviceLocation.provider.address;
        return {
            address: providerInfo.streetAddress,
            address2: "",
            city: providerInfo.city,
            state: providerInfo.state,
            zipCode: providerInfo.zipCode,
            zipCodeCtu: providerInfo.zipCodeCtu,
        };
    }
}

function getWorkOrderLastSixDigits(order) {
    const workOrderNumber = order.workOrderNumber ?? "";
    const tokens = workOrderNumber.split("-");
    const lastSegment = tokens[tokens.length - 1] ?? "";
    const numDigits = lastSegment.length;
    const numZeroes = 6 - numDigits;

    let result = "";
    for (let i = 0; i < numZeroes; i++) {
        result += "0";
    }

    result += lastSegment;

    return result;
}

function getSourceSystem() {
    return "ISS-NextGen";
}
