import { GraphQLError } from 'graphql';
import { CountryCode, Currency, DocumentType } from '../../../shared/enums.js';
import { formatCurrency, hashStringToInt } from '../../../shared/helpers/index.js';
import { CloudinaryProvider } from '../../app-providers/cloudinary.js';
import { GreenInvoiceClientProvider } from '../../app-providers/green-invoice-client.js';
import { ChargesProvider } from '../../charges/providers/charges.provider.js';
import { DocumentsProvider } from '../../documents/providers/documents.provider.js';
import { IssuedDocumentsProvider } from '../../documents/providers/issued-documents.provider.js';
import { validateClientIntegrations } from '../../financial-entities/helpers/clients.helper.js';
import { ClientsProvider } from '../../financial-entities/providers/clients.provider.js';
export function normalizeGreenInvoiceDocumentType(rawType) {
    if (!rawType) {
        return DocumentType.Unprocessed;
    }
    if (typeof rawType === 'string' && rawType.startsWith('_')) {
        const int = parseInt(rawType.replace('_', ''));
        if (Number.isInteger(int)) {
            rawType = int;
        }
    }
    switch (rawType) {
        case 20:
            // חשבון / אישור תשלום
            return DocumentType.Invoice;
        case 300:
            // חשבונית עסקה
            return DocumentType.Proforma;
        case 305:
            // חשבונית מס
            return DocumentType.Invoice;
        case 320:
            // חשבונית מס\קבלה
            return DocumentType.InvoiceReceipt;
        case 330:
            // חשבונית זיכוי
            return DocumentType.CreditInvoice;
        case 400:
            // קבלה
            return DocumentType.Receipt;
        case 405:
            // קבלה על תרומה
            return DocumentType.Unprocessed;
        default:
            console.log(`Got a new document type from Green Invoice: ${rawType}`);
            return DocumentType.Unprocessed;
    }
}
export function getGreenInvoiceDocumentType(documentType) {
    switch (documentType) {
        case DocumentType.Invoice:
            return '_305';
        case DocumentType.Proforma:
            return '_300';
        case DocumentType.InvoiceReceipt:
            return '_320';
        case DocumentType.CreditInvoice:
            return '_330';
        case DocumentType.Receipt:
            return '_400';
        default:
            throw new Error(`Unsupported document type: ${documentType}`);
    }
}
export function getTypeFromGreenInvoiceDocument(documentType) {
    switch (documentType) {
        case '_305':
            return DocumentType.Invoice;
        case '_300':
            return DocumentType.Proforma;
        case '_320':
            return DocumentType.InvoiceReceipt;
        case '_330':
            return DocumentType.CreditInvoice;
        case '_400':
            return DocumentType.Receipt;
        default:
            throw new Error(`Unsupported document type: ${documentType}`);
    }
}
export function getDocumentNameFromGreenInvoiceType(documentType) {
    switch (documentType) {
        case '_305':
            return 'Tax Invoice';
        case '_300':
            return 'Proforma Invoice';
        case '_320':
            return 'Invoice / Receipt';
        case '_330':
            return 'Credit Note';
        case '_400':
            return 'Receipt';
        default:
            throw new Error(`Unsupported document type: ${documentType}`);
    }
}
export function getGreenInvoiceDocumentLanguage(language) {
    switch (language) {
        case 'HEBREW':
            return 'he';
        case 'ENGLISH':
            return 'en';
        default:
            throw new Error(`Unsupported document language: ${language}`);
    }
}
export function getLanguageFromGreenInvoiceDocument(lang) {
    switch (lang) {
        case 'he':
            return 'HEBREW';
        case 'en':
            return 'ENGLISH';
        default:
            throw new Error(`Unsupported document language: ${lang}`);
    }
}
export function getGreenInvoiceDocumentVatType(vatType) {
    switch (vatType) {
        case 'DEFAULT':
            return '_0';
        case 'EXEMPT':
            return '_1';
        case 'MIXED':
            return '_2';
        default:
            throw new Error(`Unsupported VAT type: ${vatType}`);
    }
}
export function getVatTypeFromGreenInvoiceDocument(vatType) {
    switch (vatType) {
        case '_0':
            return 'DEFAULT';
        case '_1':
            return 'EXEMPT';
        case '_2':
            return 'MIXED';
        default:
            throw new Error(`Unsupported VAT type: ${vatType}`);
    }
}
export function getGreenInvoiceDocumentDiscountType(discountType) {
    switch (discountType) {
        case 'PERCENTAGE':
            return 'percentage';
        case 'SUM':
            return 'sum';
        default:
            throw new Error(`Unsupported discount type: ${discountType}`);
    }
}
export function getGreenInvoiceDocumentPaymentType(type) {
    switch (type) {
        case 'TAX_DEDUCTION':
            return 'NEGATIVE_1';
        case 'CASH':
            return '_1';
        case 'CHEQUE':
            return '_2';
        case 'CREDIT_CARD':
            return '_3';
        case 'WIRE_TRANSFER':
            return '_4';
        case 'PAYPAL':
            return '_5';
        case 'OTHER_DEDUCTION':
            return '_9';
        case 'PAYMENT_APP':
            return '_10';
        case 'OTHER':
            return '_11';
        default:
            throw new Error(`Unsupported payment type: ${type}`);
    }
}
export function getTypeFromGreenInvoiceDocumentPayment(type) {
    switch (type) {
        case 'NEGATIVE_1':
            return 'TAX_DEDUCTION';
        case '_1':
            return 'CASH';
        case '_2':
            return 'CHEQUE';
        case '_3':
            return 'CREDIT_CARD';
        case '_4':
            return 'WIRE_TRANSFER';
        case '_5':
            return 'PAYPAL';
        case '_9':
            return 'OTHER_DEDUCTION';
        case '_10':
            return 'PAYMENT_APP';
        case '_11':
            return 'OTHER';
        default:
            throw new Error(`Unsupported payment type: ${type}`);
    }
}
// export function getGreenInvoiceDocumentPaymentSubType(
//   subType: GreenInvoicePaymentSubType,
// ): query_getDocument_payment_items_subType {
//   switch (subType) {
//     case 'BITCOIN':
//       return '_1';
//     case 'BUYME_VOUCHER':
//       return '_7';
//     case 'ETHEREUM':
//       return '_6';
//     case 'GIFT_CARD':
//       return '_4';
//     case 'MONEY_EQUAL':
//       return '_2';
//     case 'NII_EMPLOYEE_DEDUCTION':
//       return '_5';
//     case 'PAYONEER':
//       return '_8';
//     case 'V_CHECK':
//       return '_3';
//     default:
//       throw new Error(`Unsupported payment sub-type: ${subType}`);
//   }
// }
// export function getSubTypeFromGreenInvoiceDocumentPayment(
//   subType: query_getDocument_payment_items_subType,
// ): GreenInvoicePaymentSubType {
//   switch (subType) {
//     case '_1':
//       return 'BITCOIN';
//     case '_7':
//       return 'BUYME_VOUCHER';
//     case '_6':
//       return 'ETHEREUM';
//     case '_4':
//       return 'GIFT_CARD';
//     case '_2':
//       return 'MONEY_EQUAL';
//     case '_5':
//       return 'NII_EMPLOYEE_DEDUCTION';
//     case '_8':
//       return 'PAYONEER';
//     case '_3':
//       return 'V_CHECK';
//     default:
//       throw new Error(`Unsupported payment sub-type: ${subType}`);
//   }
// }
// export function getGreenInvoiceDocumentPaymentAppType(
//   appType: GreenInvoicePaymentAppType,
// ): query_getDocument_payment_items_appType {
//   switch (appType) {
//     case 'APPLE_PAY':
//       return '_6';
//     case 'BIT':
//       return '_1';
//     case 'CULO':
//       return '_4';
//     case 'GOOGLE_PAY':
//       return '_5';
//     case 'PAYBOX':
//       return '_3';
//     case 'PAY_BY_PEPPER':
//       return '_2';
//     default:
//       throw new Error(`Unsupported payment app type: ${appType}`);
//   }
// }
// export function getPaymentAppTypeFromGreenInvoiceDocument(
//   appType: query_getDocument_payment_items_appType,
// ): GreenInvoicePaymentAppType {
//   switch (appType) {
//     case '_6':
//       return 'APPLE_PAY';
//     case '_1':
//       return 'BIT';
//     case '_4':
//       return 'CULO';
//     case '_5':
//       return 'GOOGLE_PAY';
//     case '_3':
//       return 'PAYBOX';
//     case '_2':
//       return 'PAY_BY_PEPPER';
//     default:
//       throw new Error(`Unsupported payment app type: ${appType}`);
//   }
// }
export function getGreenInvoiceDocumentPaymentCardType(cardType) {
    switch (cardType) {
        case 'AMERICAN_EXPRESS':
            return '_4';
        case 'DINERS':
            return '_5';
        case 'ISRACARD':
            return '_1';
        case 'MASTERCARD':
            return '_3';
        // case 'UNKNOWN':
        //   return '_0'; // TODO: why is this not supported?
        case 'VISA':
            return '_2';
        default:
            throw new Error(`Unsupported payment card type: ${cardType}`);
    }
}
export function getCardTypeFromGreenInvoiceDocumentPayment(cardType) {
    switch (cardType) {
        case '_4':
            return 'AMERICAN_EXPRESS';
        case '_5':
            return 'DINERS';
        case '_1':
            return 'ISRACARD';
        case '_3':
            return 'MASTERCARD';
        // case '_0': // TODO: why is this not supported?
        //   return 'UNKNOWN';
        case '_2':
            return 'VISA';
        default:
            throw new Error(`Unsupported payment card type: ${cardType}`);
    }
}
// export function getGreenInvoiceDocumentPaymentDealType(
//   dealType: GreenInvoicePaymentDealType,
// ): query_getDocument_payment_items_dealType {
//   switch (dealType) {
//     case 'CREDIT':
//       return '_3';
//     case 'DEFERRED':
//       return '_4';
//     case 'OTHER':
//       return '_5';
//     case 'PAYMENTS':
//       return '_2';
//     case 'RECURRING':
//       return '_6';
//     case 'STANDARD':
//       return '_1';
//     default:
//       throw new Error(`Unsupported payment deal type: ${dealType}`);
//   }
// }
// export function getDealTypeFromGreenInvoiceDocumentPayment(
//   dealType: query_getDocument_payment_items_dealType,
// ): GreenInvoicePaymentDealType {
//   switch (dealType) {
//     case '_3':
//       return 'CREDIT';
//     case '_4':
//       return 'DEFERRED';
//     case '_5':
//       return 'OTHER';
//     case '_2':
//       return 'PAYMENTS';
//     case '_6':
//       return 'RECURRING';
//     case '_1':
//       return 'STANDARD';
//     default:
//       throw new Error(`Unsupported payment deal type: ${dealType}`);
//   }
// }
export function getGreenInvoiceDocumentLinkType(linkType) {
    switch (linkType) {
        case 'CANCEL':
            return 'CANCEL';
        case 'LINK':
            return 'LINK';
        default:
            throw new Error(`Unsupported link type: ${linkType}`);
    }
}
export function convertCurrencyToGreenInvoice(currency) {
    switch (currency) {
        case Currency.Aud:
            return 'AUD';
        case Currency.Cad:
            return 'CAD';
        case Currency.Eur:
            return 'EUR';
        case Currency.Gbp:
            return 'GBP';
        case Currency.Ils:
            return 'ILS';
        case Currency.Jpy:
            return 'JPY';
        case Currency.Sek:
            return 'SEK';
        case Currency.Usd:
            return 'USD';
        case Currency.Eth:
        case Currency.Grt:
        case Currency.Usdc:
            throw new Error(`Crypto currency (${currency}) is not supported`);
        default:
            throw new Error(`Unsupported currency: ${currency}`);
    }
}
export function greenInvoiceCountryToCountryCode(country) {
    const greenInvoiceToCountryCodeMap = {
        AD: CountryCode.Andorra,
        AE: CountryCode['United Arab Emirates (the)'],
        AF: CountryCode.Afghanistan,
        AG: CountryCode['Antigua and Barbuda'],
        AI: CountryCode.Anguilla,
        AL: CountryCode.Albania,
        AM: CountryCode.Armenia,
        AO: CountryCode.Angola,
        AQ: CountryCode.Antarctica,
        AR: CountryCode.Argentina,
        AS: CountryCode['American Samoa'],
        AT: CountryCode.Austria,
        AU: CountryCode.Australia,
        AW: CountryCode.Aruba,
        AX: CountryCode['Åland Islands'],
        AZ: CountryCode.Azerbaijan,
        BA: CountryCode['Bosnia and Herzegovina'],
        BB: CountryCode.Barbados,
        BD: CountryCode.Bangladesh,
        BE: CountryCode.Belgium,
        BF: CountryCode['Burkina Faso'],
        BG: CountryCode.Bulgaria,
        BH: CountryCode.Bahrain,
        BI: CountryCode.Burundi,
        BJ: CountryCode.Benin,
        BL: CountryCode['Saint Barthélemy'],
        BM: CountryCode.Bermuda,
        BN: CountryCode['Brunei Darussalam'],
        BO: CountryCode['Bolivia (Plurinational State of)'],
        BQ: CountryCode['Bonaire, Sint Eustatius and Saba'],
        BR: CountryCode.Brazil,
        BS: CountryCode['Bahamas (the)'],
        BT: CountryCode.Bhutan,
        BV: CountryCode['Bouvet Island'],
        BW: CountryCode.Botswana,
        BY: CountryCode.Belarus,
        BZ: CountryCode.Belize,
        CA: CountryCode.Canada,
        CC: CountryCode['Cocos (Keeling) Islands (the)'],
        CD: CountryCode['Congo (the Democratic Republic of the)'],
        CF: CountryCode['Central African Republic (the)'],
        CG: CountryCode['Congo (the)'],
        CH: CountryCode.Switzerland,
        CI: CountryCode["Côte d'Ivoire"],
        CK: CountryCode['Cook Islands (the)'],
        CL: CountryCode.Chile,
        CM: CountryCode.Cameroon,
        CN: CountryCode.China,
        CO: CountryCode.Colombia,
        CR: CountryCode['Costa Rica'],
        CU: CountryCode.Cuba,
        CV: CountryCode['Cabo Verde'],
        CW: CountryCode.Curaçao,
        CX: CountryCode['Christmas Island'],
        CY: CountryCode.Cyprus,
        CZ: CountryCode.Czechia,
        DE: CountryCode.Germany,
        DJ: CountryCode.Djibouti,
        DK: CountryCode.Denmark,
        DM: CountryCode.Dominica,
        DO: CountryCode['Dominican Republic (the)'],
        DZ: CountryCode.Algeria,
        EC: CountryCode.Ecuador,
        EE: CountryCode.Estonia,
        EG: CountryCode.Egypt,
        EH: CountryCode['Western Sahara'],
        ER: CountryCode.Eritrea,
        ES: CountryCode.Spain,
        ET: CountryCode.Ethiopia,
        FI: CountryCode.Finland,
        FJ: CountryCode.Fiji,
        FK: CountryCode['Falkland Islands (the) [Malvinas]'],
        FM: CountryCode['Micronesia (Federated States of)'],
        FO: CountryCode['Faroe Islands (the)'],
        FR: CountryCode.France,
        GA: CountryCode.Gabon,
        GB: CountryCode['United Kingdom of Great Britain and Northern Ireland (the)'],
        GD: CountryCode.Grenada,
        GE: CountryCode.Georgia,
        GF: CountryCode['French Guiana'],
        GG: CountryCode.Guernsey,
        GH: CountryCode.Ghana,
        GI: CountryCode.Gibraltar,
        GL: CountryCode.Greenland,
        GM: CountryCode['Gambia (the)'],
        GN: CountryCode.Guinea,
        GP: CountryCode.Guadeloupe,
        GQ: CountryCode['Equatorial Guinea'],
        GR: CountryCode.Greece,
        GS: CountryCode['South Georgia and the South Sandwich Islands'],
        GT: CountryCode.Guatemala,
        GU: CountryCode.Guam,
        GW: CountryCode['Guinea-Bissau'],
        GY: CountryCode.Guyana,
        HK: CountryCode['Hong Kong'],
        HM: CountryCode['Heard Island and McDonald Islands'],
        HN: CountryCode.Honduras,
        HR: CountryCode.Croatia,
        HT: CountryCode.Haiti,
        HU: CountryCode.Hungary,
        ID: CountryCode.Indonesia,
        IE: CountryCode.Ireland,
        IL: CountryCode.Israel,
        IM: CountryCode['Isle of Man'],
        IN: CountryCode.India,
        IO: CountryCode['British Indian Ocean Territory (the)'],
        IQ: CountryCode.Iraq,
        IR: CountryCode['Iran (Islamic Republic of)'],
        IS: CountryCode.Iceland,
        IT: CountryCode.Italy,
        JE: CountryCode.Jersey,
        JM: CountryCode.Jamaica,
        JO: CountryCode.Jordan,
        JP: CountryCode.Japan,
        KE: CountryCode.Kenya,
        KG: CountryCode.Kyrgyzstan,
        KH: CountryCode.Cambodia,
        KI: CountryCode.Kiribati,
        KM: CountryCode['Comoros (the)'],
        KN: CountryCode['Saint Kitts and Nevis'],
        KP: CountryCode["Korea (the Democratic People's Republic of)"],
        KR: CountryCode['Korea (the Republic of)'],
        KW: CountryCode.Kuwait,
        KY: CountryCode['Cayman Islands (the)'],
        KZ: CountryCode.Kazakhstan,
        LA: CountryCode["Lao People's Democratic Republic (the)"],
        LB: CountryCode.Lebanon,
        LC: CountryCode['Saint Lucia'],
        LI: CountryCode.Liechtenstein,
        LK: CountryCode['Sri Lanka'],
        LR: CountryCode.Liberia,
        LS: CountryCode.Lesotho,
        LT: CountryCode.Lithuania,
        LU: CountryCode.Luxembourg,
        LV: CountryCode.Latvia,
        LY: CountryCode.Libya,
        MA: CountryCode.Morocco,
        MC: CountryCode.Monaco,
        MD: CountryCode['Moldova (the Republic of)'],
        ME: CountryCode.Montenegro,
        MF: CountryCode['Saint Martin (French part)'],
        MG: CountryCode.Madagascar,
        MH: CountryCode['Marshall Islands (the)'],
        MK: CountryCode['Republic of North Macedonia'],
        ML: CountryCode.Mali,
        MM: CountryCode.Myanmar,
        MN: CountryCode.Mongolia,
        MO: CountryCode.Macao,
        MP: CountryCode['Northern Mariana Islands (the)'],
        MQ: CountryCode.Martinique,
        MR: CountryCode.Mauritania,
        MS: CountryCode.Montserrat,
        MT: CountryCode.Malta,
        MU: CountryCode.Mauritius,
        MV: CountryCode.Maldives,
        MW: CountryCode.Malawi,
        MX: CountryCode.Mexico,
        MY: CountryCode.Malaysia,
        MZ: CountryCode.Mozambique,
        NA: CountryCode.Namibia,
        NC: CountryCode['New Caledonia'],
        NE: CountryCode['Niger (the)'],
        NF: CountryCode['Norfolk Island'],
        NG: CountryCode.Nigeria,
        NI: CountryCode.Nicaragua,
        NL: CountryCode['Netherlands (the)'],
        NO: CountryCode.Norway,
        NP: CountryCode.Nepal,
        NR: CountryCode.Nauru,
        NU: CountryCode.Niue,
        NZ: CountryCode['New Zealand'],
        OM: CountryCode.Oman,
        PA: CountryCode.Panama,
        PE: CountryCode.Peru,
        PF: CountryCode['French Polynesia'],
        PG: CountryCode['Papua New Guinea'],
        PH: CountryCode['Philippines (the)'],
        PK: CountryCode.Pakistan,
        PL: CountryCode.Poland,
        PM: CountryCode['Saint Pierre and Miquelon'],
        PN: CountryCode.Pitcairn,
        PR: CountryCode['Puerto Rico'],
        PS: CountryCode['Palestine, State of'],
        PT: CountryCode.Portugal,
        PW: CountryCode.Palau,
        PY: CountryCode.Paraguay,
        QA: CountryCode.Qatar,
        RE: CountryCode.Réunion,
        RO: CountryCode.Romania,
        RS: CountryCode.Serbia,
        RU: CountryCode['Russian Federation (the)'],
        RW: CountryCode.Rwanda,
        SA: CountryCode['Saudi Arabia'],
        SB: CountryCode['Solomon Islands'],
        SC: CountryCode.Seychelles,
        SD: CountryCode['Sudan (the)'],
        SE: CountryCode.Sweden,
        SG: CountryCode.Singapore,
        SH: CountryCode['Saint Helena, Ascension and Tristan da Cunha'],
        SI: CountryCode.Slovenia,
        SJ: CountryCode['Svalbard and Jan Mayen'],
        SK: CountryCode.Slovakia,
        SL: CountryCode['Sierra Leone'],
        SM: CountryCode['San Marino'],
        SN: CountryCode.Senegal,
        SO: CountryCode.Somalia,
        SR: CountryCode.Suriname,
        SS: CountryCode['South Sudan'],
        ST: CountryCode['Sao Tome and Principe'],
        SV: CountryCode['El Salvador'],
        SX: CountryCode['Sint Maarten (Dutch part)'],
        SY: CountryCode['Syrian Arab Republic'],
        SZ: CountryCode.Eswatini,
        TC: CountryCode['Turks and Caicos Islands (the)'],
        TD: CountryCode.Chad,
        TF: CountryCode['French Southern Territories (the)'],
        TG: CountryCode.Togo,
        TH: CountryCode.Thailand,
        TJ: CountryCode.Tajikistan,
        TK: CountryCode.Tokelau,
        TL: CountryCode['Timor-Leste'],
        TM: CountryCode.Turkmenistan,
        TN: CountryCode.Tunisia,
        TO: CountryCode.Tonga,
        TR: CountryCode.Turkey,
        TT: CountryCode['Trinidad and Tobago'],
        TV: CountryCode.Tuvalu,
        TW: CountryCode['Taiwan (Province of China)'],
        TZ: CountryCode['Tanzania, United Republic of'],
        UA: CountryCode.Ukraine,
        UG: CountryCode.Uganda,
        UM: CountryCode['United States Minor Outlying Islands (the)'],
        US: CountryCode['United States of America (the)'],
        UY: CountryCode.Uruguay,
        UZ: CountryCode.Uzbekistan,
        VA: CountryCode['Holy See (the)'],
        VC: CountryCode['Saint Vincent and the Grenadines'],
        VE: CountryCode['Venezuela (Bolivarian Republic of)'],
        VG: CountryCode['Virgin Islands (British)'],
        VI: CountryCode['Virgin Islands (U.S.)'],
        VN: CountryCode['Viet Nam'],
        VU: CountryCode.Vanuatu,
        WF: CountryCode['Wallis and Futuna'],
        WS: CountryCode.Samoa,
        YE: CountryCode.Yemen,
        YT: CountryCode.Mayotte,
        ZA: CountryCode['South Africa'],
        ZM: CountryCode.Zambia,
        ZW: CountryCode.Zimbabwe,
    };
    if (country === 'XK') {
        // TODO: remove this once green invoice adds Kosovo to their list
        return CountryCode.Serbia;
    }
    const code = greenInvoiceToCountryCodeMap[country];
    if (code) {
        return code;
    }
    throw new Error(`Unsupported Green Invoice country: ${country}`);
}
export function countryCodeToGreenInvoiceCountry(countryCode) {
    const countryCodeToGreenInvoiceMap = {
        [CountryCode.Afghanistan]: 'AF',
        [CountryCode['Åland Islands']]: 'AX',
        [CountryCode.Albania]: 'AL',
        [CountryCode.Algeria]: 'DZ',
        [CountryCode['American Samoa']]: 'AS',
        [CountryCode.Andorra]: 'AD',
        [CountryCode.Angola]: 'AO',
        [CountryCode.Anguilla]: 'AI',
        [CountryCode.Antarctica]: 'AQ',
        [CountryCode['Antigua and Barbuda']]: 'AG',
        [CountryCode.Argentina]: 'AR',
        [CountryCode.Armenia]: 'AM',
        [CountryCode.Aruba]: 'AW',
        [CountryCode.Australia]: 'AU',
        [CountryCode.Austria]: 'AT',
        [CountryCode.Azerbaijan]: 'AZ',
        [CountryCode['Bahamas (the)']]: 'BS',
        [CountryCode.Bahrain]: 'BH',
        [CountryCode.Bangladesh]: 'BD',
        [CountryCode.Barbados]: 'BB',
        [CountryCode.Belarus]: 'BY',
        [CountryCode.Belgium]: 'BE',
        [CountryCode.Belize]: 'BZ',
        [CountryCode.Benin]: 'BJ',
        [CountryCode.Bermuda]: 'BM',
        [CountryCode.Bhutan]: 'BT',
        [CountryCode['Bolivia (Plurinational State of)']]: 'BO',
        [CountryCode['Bonaire, Sint Eustatius and Saba']]: 'BQ',
        [CountryCode['Bosnia and Herzegovina']]: 'BA',
        [CountryCode.Botswana]: 'BW',
        [CountryCode['Bouvet Island']]: 'BV',
        [CountryCode.Brazil]: 'BR',
        [CountryCode['British Indian Ocean Territory (the)']]: 'IO',
        [CountryCode['Brunei Darussalam']]: 'BN',
        [CountryCode.Bulgaria]: 'BG',
        [CountryCode['Burkina Faso']]: 'BF',
        [CountryCode.Burundi]: 'BI',
        [CountryCode['Cabo Verde']]: 'CV',
        [CountryCode.Cambodia]: 'KH',
        [CountryCode.Cameroon]: 'CM',
        [CountryCode.Canada]: 'CA',
        [CountryCode['Cayman Islands (the)']]: 'KY',
        [CountryCode['Central African Republic (the)']]: 'CF',
        [CountryCode.Chad]: 'TD',
        [CountryCode.Chile]: 'CL',
        [CountryCode.China]: 'CN',
        [CountryCode['Christmas Island']]: 'CX',
        [CountryCode['Cocos (Keeling) Islands (the)']]: 'CC',
        [CountryCode.Colombia]: 'CO',
        [CountryCode['Comoros (the)']]: 'KM',
        [CountryCode['Congo (the Democratic Republic of the)']]: 'CD',
        [CountryCode['Congo (the)']]: 'CG',
        [CountryCode['Cook Islands (the)']]: 'CK',
        [CountryCode['Costa Rica']]: 'CR',
        [CountryCode.Croatia]: 'HR',
        [CountryCode.Cuba]: 'CU',
        [CountryCode.Curaçao]: 'CW',
        [CountryCode.Cyprus]: 'CY',
        [CountryCode.Czechia]: 'CZ',
        [CountryCode["Côte d'Ivoire"]]: 'CI',
        [CountryCode.Denmark]: 'DK',
        [CountryCode.Djibouti]: 'DJ',
        [CountryCode.Dominica]: 'DM',
        [CountryCode['Dominican Republic (the)']]: 'DO',
        [CountryCode.Ecuador]: 'EC',
        [CountryCode.Egypt]: 'EG',
        [CountryCode['El Salvador']]: 'SV',
        [CountryCode['Equatorial Guinea']]: 'GQ',
        [CountryCode.Eritrea]: 'ER',
        [CountryCode.Estonia]: 'EE',
        [CountryCode.Eswatini]: 'SZ',
        [CountryCode.Ethiopia]: 'ET',
        [CountryCode['Falkland Islands (the) [Malvinas]']]: 'FK',
        [CountryCode['Faroe Islands (the)']]: 'FO',
        [CountryCode.Fiji]: 'FJ',
        [CountryCode.Finland]: 'FI',
        [CountryCode.France]: 'FR',
        [CountryCode['French Guiana']]: 'GF',
        [CountryCode['French Polynesia']]: 'PF',
        [CountryCode['French Southern Territories (the)']]: 'TF',
        [CountryCode.Gabon]: 'GA',
        [CountryCode['Gambia (the)']]: 'GM',
        [CountryCode.Georgia]: 'GE',
        [CountryCode.Germany]: 'DE',
        [CountryCode.Ghana]: 'GH',
        [CountryCode.Gibraltar]: 'GI',
        [CountryCode.Greece]: 'GR',
        [CountryCode.Greenland]: 'GL',
        [CountryCode.Grenada]: 'GD',
        [CountryCode.Guadeloupe]: 'GP',
        [CountryCode.Guam]: 'GU',
        [CountryCode.Guatemala]: 'GT',
        [CountryCode.Guernsey]: 'GG',
        [CountryCode.Guinea]: 'GN',
        [CountryCode['Guinea-Bissau']]: 'GW',
        [CountryCode.Guyana]: 'GY',
        [CountryCode.Haiti]: 'HT',
        [CountryCode['Heard Island and McDonald Islands']]: 'HM',
        [CountryCode['Holy See (the)']]: 'VA',
        [CountryCode.Honduras]: 'HN',
        [CountryCode['Hong Kong']]: 'HK',
        [CountryCode.Hungary]: 'HU',
        [CountryCode.Iceland]: 'IS',
        [CountryCode.India]: 'IN',
        [CountryCode.Indonesia]: 'ID',
        [CountryCode['Iran (Islamic Republic of)']]: 'IR',
        [CountryCode.Iraq]: 'IQ',
        [CountryCode.Ireland]: 'IE',
        [CountryCode['Isle of Man']]: 'IM',
        [CountryCode.Israel]: 'IL',
        [CountryCode.Italy]: 'IT',
        [CountryCode.Jamaica]: 'JM',
        [CountryCode.Japan]: 'JP',
        [CountryCode.Jersey]: 'JE',
        [CountryCode.Jordan]: 'JO',
        [CountryCode.Kazakhstan]: 'KZ',
        [CountryCode.Kenya]: 'KE',
        [CountryCode.Kiribati]: 'KI',
        [CountryCode["Korea (the Democratic People's Republic of)"]]: 'KP',
        [CountryCode['Korea (the Republic of)']]: 'KR',
        [CountryCode.Kuwait]: 'KW',
        [CountryCode.Kyrgyzstan]: 'KG',
        [CountryCode["Lao People's Democratic Republic (the)"]]: 'LA',
        [CountryCode.Latvia]: 'LV',
        [CountryCode.Lebanon]: 'LB',
        [CountryCode.Lesotho]: 'LS',
        [CountryCode.Liberia]: 'LR',
        [CountryCode.Libya]: 'LY',
        [CountryCode.Liechtenstein]: 'LI',
        [CountryCode.Lithuania]: 'LT',
        [CountryCode.Luxembourg]: 'LU',
        [CountryCode.Macao]: 'MO',
        [CountryCode.Madagascar]: 'MG',
        [CountryCode.Malawi]: 'MW',
        [CountryCode.Malaysia]: 'MY',
        [CountryCode.Maldives]: 'MV',
        [CountryCode.Mali]: 'ML',
        [CountryCode.Malta]: 'MT',
        [CountryCode['Marshall Islands (the)']]: 'MH',
        [CountryCode.Martinique]: 'MQ',
        [CountryCode.Mauritania]: 'MR',
        [CountryCode.Mauritius]: 'MU',
        [CountryCode.Mayotte]: 'YT',
        [CountryCode.Mexico]: 'MX',
        [CountryCode['Micronesia (Federated States of)']]: 'FM',
        [CountryCode['Moldova (the Republic of)']]: 'MD',
        [CountryCode.Monaco]: 'MC',
        [CountryCode.Mongolia]: 'MN',
        [CountryCode.Montenegro]: 'ME',
        [CountryCode.Montserrat]: 'MS',
        [CountryCode.Morocco]: 'MA',
        [CountryCode.Mozambique]: 'MZ',
        [CountryCode.Myanmar]: 'MM',
        [CountryCode.Namibia]: 'NA',
        [CountryCode.Nauru]: 'NR',
        [CountryCode.Nepal]: 'NP',
        [CountryCode['Netherlands (the)']]: 'NL',
        [CountryCode['New Caledonia']]: 'NC',
        [CountryCode['New Zealand']]: 'NZ',
        [CountryCode.Nicaragua]: 'NI',
        [CountryCode['Niger (the)']]: 'NE',
        [CountryCode.Nigeria]: 'NG',
        [CountryCode.Niue]: 'NU',
        [CountryCode['Norfolk Island']]: 'NF',
        [CountryCode['Northern Mariana Islands (the)']]: 'MP',
        [CountryCode.Norway]: 'NO',
        [CountryCode.Oman]: 'OM',
        [CountryCode.Pakistan]: 'PK',
        [CountryCode.Palau]: 'PW',
        [CountryCode['Palestine, State of']]: 'PS',
        [CountryCode.Panama]: 'PA',
        [CountryCode['Papua New Guinea']]: 'PG',
        [CountryCode.Paraguay]: 'PY',
        [CountryCode.Peru]: 'PE',
        [CountryCode['Philippines (the)']]: 'PH',
        [CountryCode.Pitcairn]: 'PN',
        [CountryCode.Poland]: 'PL',
        [CountryCode.Portugal]: 'PT',
        [CountryCode['Puerto Rico']]: 'PR',
        [CountryCode.Qatar]: 'QA',
        [CountryCode['Republic of North Macedonia']]: 'MK',
        [CountryCode.Romania]: 'RO',
        [CountryCode['Russian Federation (the)']]: 'RU',
        [CountryCode.Rwanda]: 'RW',
        [CountryCode.Réunion]: 'RE',
        [CountryCode['Saint Barthélemy']]: 'BL',
        [CountryCode['Saint Helena, Ascension and Tristan da Cunha']]: 'SH',
        [CountryCode['Saint Kitts and Nevis']]: 'KN',
        [CountryCode['Saint Lucia']]: 'LC',
        [CountryCode['Saint Martin (French part)']]: 'MF',
        [CountryCode['Saint Pierre and Miquelon']]: 'PM',
        [CountryCode['Saint Vincent and the Grenadines']]: 'VC',
        [CountryCode.Samoa]: 'WS',
        [CountryCode['San Marino']]: 'SM',
        [CountryCode['Sao Tome and Principe']]: 'ST',
        [CountryCode['Saudi Arabia']]: 'SA',
        [CountryCode.Senegal]: 'SN',
        [CountryCode.Serbia]: 'RS',
        [CountryCode.Seychelles]: 'SC',
        [CountryCode['Sierra Leone']]: 'SL',
        [CountryCode.Singapore]: 'SG',
        [CountryCode['Sint Maarten (Dutch part)']]: 'SX',
        [CountryCode.Slovakia]: 'SK',
        [CountryCode.Slovenia]: 'SI',
        [CountryCode['Solomon Islands']]: 'SB',
        [CountryCode.Somalia]: 'SO',
        [CountryCode['South Africa']]: 'ZA',
        [CountryCode['South Georgia and the South Sandwich Islands']]: 'GS',
        [CountryCode['South Sudan']]: 'SS',
        [CountryCode.Spain]: 'ES',
        [CountryCode['Sri Lanka']]: 'LK',
        [CountryCode['Sudan (the)']]: 'SD',
        [CountryCode.Suriname]: 'SR',
        [CountryCode['Svalbard and Jan Mayen']]: 'SJ',
        [CountryCode.Sweden]: 'SE',
        [CountryCode.Switzerland]: 'CH',
        [CountryCode['Syrian Arab Republic']]: 'SY',
        [CountryCode['Taiwan (Province of China)']]: 'TW',
        [CountryCode.Tajikistan]: 'TJ',
        [CountryCode['Tanzania, United Republic of']]: 'TZ',
        [CountryCode.Thailand]: 'TH',
        [CountryCode['Timor-Leste']]: 'TL',
        [CountryCode.Togo]: 'TG',
        [CountryCode.Tokelau]: 'TK',
        [CountryCode.Tonga]: 'TO',
        [CountryCode['Trinidad and Tobago']]: 'TT',
        [CountryCode.Tunisia]: 'TN',
        [CountryCode.Turkey]: 'TR',
        [CountryCode.Turkmenistan]: 'TM',
        [CountryCode['Turks and Caicos Islands (the)']]: 'TC',
        [CountryCode.Tuvalu]: 'TV',
        [CountryCode.Uganda]: 'UG',
        [CountryCode.Ukraine]: 'UA',
        [CountryCode['United Arab Emirates (the)']]: 'AE',
        [CountryCode['United Kingdom of Great Britain and Northern Ireland (the)']]: 'GB',
        [CountryCode['United States Minor Outlying Islands (the)']]: 'UM',
        [CountryCode['United States of America (the)']]: 'US',
        [CountryCode.Uruguay]: 'UY',
        [CountryCode.Uzbekistan]: 'UZ',
        [CountryCode.Vanuatu]: 'VU',
        [CountryCode['Venezuela (Bolivarian Republic of)']]: 'VE',
        [CountryCode['Viet Nam']]: 'VN',
        [CountryCode['Virgin Islands (British)']]: 'VG',
        [CountryCode['Virgin Islands (U.S.)']]: 'VI',
        [CountryCode['Wallis and Futuna']]: 'WF',
        [CountryCode['Western Sahara']]: 'EH',
        [CountryCode.Yemen]: 'YE',
        [CountryCode.Zambia]: 'ZM',
        [CountryCode.Zimbabwe]: 'ZW',
    };
    const greenInvoiceCountry = countryCodeToGreenInvoiceMap[countryCode];
    if (greenInvoiceCountry) {
        return greenInvoiceCountry;
    }
    throw new Error(`Unsupported country code: ${countryCode}`);
}
export function greenInvoiceToDocumentStatus(greenInvoiceStatus) {
    switch (greenInvoiceStatus) {
        case 0:
            return 'OPEN';
        case 1:
            return 'CLOSED';
        case 2:
            return 'MANUALLY_CLOSED';
        case 3:
            return 'CANCELLED_BY_OTHER_DOC';
        case 4:
            return 'CANCELLED';
        default:
            throw new Error(`Unsupported Green Invoice document status: ${greenInvoiceStatus}`);
    }
}
export async function getLinkedDocuments(injector, externalDocumentId) {
    const greenInvoiceDocument = await injector
        .get(GreenInvoiceClientProvider)
        .documentLoader.load(externalDocumentId);
    if (!greenInvoiceDocument?.linkedDocuments) {
        return null;
    }
    const linkedDocuments = greenInvoiceDocument.linkedDocuments.filter(Boolean);
    if (!linkedDocuments.length) {
        return null;
    }
    const linkedDocumentsIds = [];
    await Promise.all(linkedDocuments.map(async (linkedDocument) => {
        const issuedDocument = await injector
            .get(IssuedDocumentsProvider)
            .getIssuedDocumentsByExternalIdLoader.load(linkedDocument.id);
        if (!issuedDocument?.id) {
            throw new GraphQLError(`Linked document with ID ${linkedDocument.id} not found in issued documents`);
        }
        linkedDocumentsIds.push(issuedDocument.id);
    }));
    return linkedDocumentsIds;
}
export async function insertNewDocumentFromGreenInvoice(injector, greenInvoiceDoc, ownerId, preDictatedChargeId) {
    const documentType = normalizeGreenInvoiceDocumentType(greenInvoiceDoc.type);
    const isOwnerCreditor = greenInvoiceDoc.amount > 0 && documentType !== DocumentType.CreditInvoice;
    const links = await injector.get(GreenInvoiceClientProvider).getDocumentLinks(greenInvoiceDoc.id);
    if (!links) {
        throw new GraphQLError(`No links found for Green Invoice document ID: ${greenInvoiceDoc.id}`);
    }
    const fileUrl = links.en ?? links.origin;
    try {
        // generate preview image via cloudinary
        const imagePromise = injector.get(CloudinaryProvider).uploadInvoiceToCloudinary(fileUrl);
        // Get matching business
        const clientPromise = greenInvoiceDoc.client.id
            ? injector
                .get(ClientsProvider)
                .getClientByGreenInvoiceIdLoader.load(greenInvoiceDoc.client.id)
            : Promise.resolve(null);
        const linkedDocumentsPromise = getLinkedDocuments(injector, greenInvoiceDoc.id);
        const fileHashPromise = async () => {
            try {
                // Before creating rawDocument
                const fileResponse = await fetch(fileUrl);
                if (!fileResponse.ok) {
                    // Handle error, maybe log and continue with null hash
                    throw new Error(`Failed to fetch file from GreenInvoice: ${fileUrl}`);
                }
                const fileContent = await fileResponse.text();
                const fileHash = hashStringToInt(fileContent).toString();
                return fileHash;
            }
            catch (error) {
                console.error('Error fetching file for hash calculation:', error);
                return null;
            }
        };
        const [{ imageUrl }, client, linkedDocumentIds, fileHash] = await Promise.all([
            imagePromise,
            clientPromise,
            linkedDocumentsPromise,
            fileHashPromise(),
        ]);
        let chargeId = preDictatedChargeId || null;
        // if linked documents exist, use the first one to get the charge ID
        if (!chargeId && linkedDocumentIds?.length) {
            const linkedDocId = linkedDocumentIds[0];
            const document = await injector
                .get(DocumentsProvider)
                .getDocumentsByIdLoader.load(linkedDocId);
            if (document?.charge_id) {
                chargeId = document.charge_id;
            }
        }
        let charge = undefined;
        if (chargeId) {
            charge = await injector.get(ChargesProvider).getChargeByIdLoader.load(chargeId);
            if (!charge) {
                throw new Error(`Charge with ID ${chargeId} not found`);
            }
        }
        else {
            // Generate new parent charge
            let userDescription = 'Green Invoice generated charge';
            const income = greenInvoiceDoc.income;
            if (income && income.length > 0 && income[0].description && income[0].description !== '') {
                userDescription = income
                    .filter(item => item?.description)
                    .map(item => item.description)
                    .join(', ');
            }
            else if (greenInvoiceDoc.description && greenInvoiceDoc.description !== '') {
                userDescription = greenInvoiceDoc.description;
            }
            charge = await injector.get(ChargesProvider).generateCharge({
                ownerId,
                userDescription,
                type: 'COMMON',
            });
            if (!charge) {
                throw new Error('Failed to generate charge');
            }
            chargeId = charge.id;
        }
        const counterpartyId = client?.business_id ?? null;
        // insert document
        const rawDocument = {
            ownerId: charge.owner_id,
            image: imageUrl,
            file: fileUrl,
            documentType,
            serialNumber: greenInvoiceDoc.number,
            date: greenInvoiceDoc.documentDate,
            amount: greenInvoiceDoc.amount,
            currencyCode: formatCurrency(greenInvoiceDoc.currency),
            vat: greenInvoiceDoc.vat,
            chargeId,
            vatReportDateOverride: null,
            noVatAmount: null,
            creditorId: isOwnerCreditor ? ownerId : counterpartyId,
            debtorId: isOwnerCreditor ? counterpartyId : ownerId,
            allocationNumber: null, // TODO: add allocation number from GreenInvoice API
            exchangeRateOverride: null,
            fileHash,
            remarks: greenInvoiceDoc.remarks || null,
            description: greenInvoiceDoc.description || null,
        };
        const newDocumentResponse = await injector
            .get(DocumentsProvider)
            .insertDocuments({ documents: [rawDocument] });
        if (!newDocumentResponse || newDocumentResponse.length === 0) {
            throw new Error('Failed to insert document');
        }
        const newDocument = newDocumentResponse[0];
        // insert issued document
        await injector
            .get(IssuedDocumentsProvider)
            .insertIssuedDocuments({
            issuedDocuments: [
                {
                    ownerId: newDocument.owner_id,
                    externalId: greenInvoiceDoc.id,
                    id: newDocument.id,
                    status: greenInvoiceToDocumentStatus(greenInvoiceDoc.status),
                    linkedDocumentIds,
                },
            ],
        })
            .catch(e => {
            console.error('Failed to insert issued document', e);
            throw new GraphQLError(`Failed to insert issued document for Green Invoice ID: ${greenInvoiceDoc.id}`);
        });
        return newDocument;
    }
    catch (e) {
        throw new GraphQLError(`Error adding Green Invoice document: ${e}\n\n${JSON.stringify(greenInvoiceDoc, null, 2)}`);
    }
}
export async function getGreenInvoiceDocuments(injector, recursive = false) {
    const documents = [];
    async function getDocuments(page = 1) {
        const data = await injector.get(GreenInvoiceClientProvider).searchDocuments({
            input: { pageSize: 100, sort: 'creationDate', page },
        });
        if (!data?.items) {
            if (!recursive) {
                throw new GraphQLError('Failed to fetch documents');
            }
            return;
        }
        documents.push(...data.items.filter(item => item !== null));
        if (data.items.length < 100) {
            return;
        }
        if (recursive) {
            await getDocuments(page + 1);
        }
    }
    await getDocuments();
    return documents;
}
export async function convertDocumentInputIntoGreenInvoiceInput(initialInput, injector) {
    let client = undefined;
    if (initialInput.client) {
        const clientInfo = await injector
            .get(ClientsProvider)
            .getClientByIdLoader.load(initialInput.client.id);
        if (!clientInfo) {
            throw new GraphQLError(`Client with business ID ${initialInput.client.id} not found`);
        }
        let greenInvoiceId;
        try {
            greenInvoiceId =
                validateClientIntegrations(clientInfo.integrations ?? {}).greenInvoiceId ?? null;
        }
        catch (error) {
            console.error('Failed to validate client integrations', error);
            throw new GraphQLError(`Client with business ID ${initialInput.client.id} has invalid integrations`);
        }
        if (!greenInvoiceId) {
            throw new GraphQLError(`Client with business ID ${initialInput.client.id} not found in Green Invoice`);
        }
        const greenInvoiceClient = await injector
            .get(GreenInvoiceClientProvider)
            .clientLoader.load(greenInvoiceId);
        if (!greenInvoiceClient) {
            throw new GraphQLError(`Green Invoice client with ID ${greenInvoiceId} not found`);
        }
        const emails = ['ap@the-guild.dev']; // TODO: remove hardcoded email
        const inputEmails = initialInput.client?.emails?.filter(Boolean) ?? [];
        if (inputEmails.length) {
            emails.push(...inputEmails);
        }
        else {
            emails.push(...(greenInvoiceClient.emails ?? []));
        }
        client = {
            id: greenInvoiceClient.id,
            country: countryCodeToGreenInvoiceCountry(initialInput.client.country),
            name: initialInput.client.name,
            phone: initialInput.client.phone,
            taxId: initialInput.client.taxId,
            self: false,
            address: initialInput.client.address,
            city: initialInput.client.city,
            zip: initialInput.client.zipCode,
            fax: initialInput.client.fax,
            mobile: initialInput.client.mobile,
            emails,
        };
    }
    // clean input by converting to writeable and removing unwanted properties
    const cleanedInput = { ...initialInput };
    delete cleanedInput.language;
    const input = {
        ...cleanedInput,
        currency: convertCurrencyToGreenInvoice(initialInput.currency),
        type: getGreenInvoiceDocumentType(initialInput.type),
        lang: getGreenInvoiceDocumentLanguage(initialInput.language),
        vatType: getGreenInvoiceDocumentVatType(initialInput.vatType ?? 'DEFAULT'),
        discount: initialInput.discount
            ? {
                ...initialInput.discount,
                type: getGreenInvoiceDocumentDiscountType(initialInput.discount.type),
            }
            : undefined,
        client,
        income: initialInput.income?.map(income => ({
            ...income,
            currency: convertCurrencyToGreenInvoice(income.currency),
            vatType: getGreenInvoiceDocumentVatType(income.vatType ?? 'DEFAULT'),
        })) ?? [],
        payment: initialInput.payment?.map(payment => ({
            ...payment,
            type: getGreenInvoiceDocumentPaymentType(payment.type),
            subType: undefined,
            appType: undefined,
            cardType: payment.cardType
                ? getGreenInvoiceDocumentPaymentCardType(payment.cardType)
                : undefined,
            dealType: undefined,
            currency: convertCurrencyToGreenInvoice(payment.currency),
        })),
        linkedDocumentIds: initialInput.linkedDocumentIds?.length
            ? [...initialInput.linkedDocumentIds]
            : undefined,
        linkType: initialInput.linkType
            ? getGreenInvoiceDocumentLinkType(initialInput.linkType)
            : undefined,
    };
    return input;
}
export async function convertGreenInvoiceDocumentToDocumentDraft(greenInvoiceDocument, injector) {
    const client = await (greenInvoiceDocument.client?.id
        ? injector
            .get(ClientsProvider)
            .getClientByGreenInvoiceIdLoader.load(greenInvoiceDocument.client?.id)
        : Promise.resolve(undefined));
    return {
        ...greenInvoiceDocument,
        client,
        currency: greenInvoiceDocument.currency,
        income: greenInvoiceDocument.income?.filter(Boolean).map(income => ({
            ...income,
            currency: income.currency,
            vatType: getVatTypeFromGreenInvoiceDocument(income.vatType),
        })),
        language: getLanguageFromGreenInvoiceDocument(greenInvoiceDocument.lang),
        payment: greenInvoiceDocument.payment?.filter(Boolean).map(payment => ({
            ...payment,
            appType: undefined,
            cardType: payment?.cardType
                ? getCardTypeFromGreenInvoiceDocumentPayment(payment.cardType)
                : undefined,
            currency: payment.currency,
            dealType: undefined,
            subType: undefined,
            type: getTypeFromGreenInvoiceDocumentPayment(payment.type),
        })),
        type: getTypeFromGreenInvoiceDocument(greenInvoiceDocument.type),
        vatType: getVatTypeFromGreenInvoiceDocument(greenInvoiceDocument.vatType),
    };
}
//# sourceMappingURL=green-invoice.helper.js.map