"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Modal_1 = require("../../Modal");
const EUSignCPFrontend_1 = __importDefault(require("./EUSignCPFrontend"));
const PROCESS_STATUS_READ_PRIVATE_KEY = 'Зчитування особистого ключа';
const PROCESS_STATUS_SIGN_FILE = 'Накладання підпису на файл';
const PROCESS_STATUS_INSTALL_LIBRARY = 'Ініціалізація криптографічної бібліотеки';
const ERROR_KM_UPDATE_LIST = 'Виникла помилка при оновленні списку носіїв ключової інформації';
const ERROR_GET_JKS_PRIVATE_KEY_INFO = 'Виникла помилка при отриманні інформації про особистий ключ';
const ERROR_NO_KEYMEDIA = 'Не обрано носій';
const ERROR_SOME = 'Помилка';
const ERROR_URL_INIT = 'Помилка запиту при ініціалізації';
const ERROR_URL_SAVE = 'Помилка запиту при відправці';
const ERROR_NO_SIGNATURES = 'Помилка зчитування ЕЦП';
const ERROR_NOT_SIGN_KEY = 'Обрано ключ Печатки, замість Особистого підпису!';
class SignAccessModal extends Modal_1.ProcessModal {
    static create(props) {
        return new SignAccessModal(props);
    }
    constructor(props) {
        super({
            title: props.modalTitle || 'Авторизація за КЕП',
            actionText: props.actionText || 'Зчитати ключ',
            actionCallback: () => this._handleActionClick()
        });
        this.m_library = new EUSignCPFrontend_1.default();
        this.privateKey = null;
        this.m_readedPKey = null;
        this.m_updatingKM = false;
        this.m_updateKM = false;
        this.m_KM = null;
        this.isLoading = false;
        this.isLoaded = false;
        this.userTaxCode = null;
        // private userCode: string = 'aGVsbG8=';
        this.data2Sign = null;
        this.signedData = null;
        this.props = props;
        this._makeModal();
        this._makeHandle();
        this._LoadLibrary();
    }
    _makeModal() {
        this.modalBodyForm.append('<div class="alert alert-warning text-center"><h5>Для доступу до документів необхідно авторизуватись за допомогою КЕП</h5></div>');
        this.modalBodyForm.append('<div class="form-group row mb-2 keyFileBlock">' + '<label class="col-form-label col-sm-3 text-right">Файл ключа</label><div class="col-sm-9">' + '<input id="pkReadFileSelectField" type="file" class="form-control h-auto"/>' + '</div></div>');
        this.modalBodyForm.append('<div class="form-group row mb-2">' + '<label class="col-form-label col-sm-3 text-right">Пароль ключа</label><div class="col-sm-9">' + '<input id="kmPassword" type="password" class="form-control">' + '</div></div>');
    }
    _makeHandle() {
        this.StopUpdateKMs();
        this.modalBody.find('#pkReadFileSelectField').on('change', (e) => {
            this.handleFileChosen(e, 'sign');
        });
        this.modalBody.find('#stReadFileSelectField').on('change', (e) => {
            this.handleFileChosen(e, 'stamp');
        });
    }
    handleFileChosen(e, fileType) {
        if (e.target.files && e.target.files[0]) {
            const file = e.target.files[0];
            const fileReader = new FileReader();
            fileReader.onloadend = () => {
                let content = fileReader.result;
                // eslint-disable-next-line no-magic-numbers
                content = content.substring(content.indexOf(';base64,') + 8);
                this.m_library.BASE64Decode(content).then((data) => {
                    this.privateKey = data;
                });
            };
            fileReader.readAsDataURL(file);
        }
    }
    _handleActionClick() {
        var _a;
        // console.log('qwerty');
        this.showLoader(PROCESS_STATUS_READ_PRIVATE_KEY);
        this.setError('');
        const issuerCN = ((_a = this.GetSelectedCA()) === null || _a === void 0 ? void 0 : _a.issuerCNs[0]) || null;
        // console.log('issuerCn', issuerCN);
        this._saveIssuerCN(issuerCN);
        Promise.resolve()
            .then(() => {
            if (this.privateKey !== null) {
                const password = this.GetKMPasswordTextField('sign').val();
                return this.m_library.ReadPrivateKeyBinary(this.privateKey, password, null, issuerCN);
            }
            return Promise.reject(ERROR_NO_KEYMEDIA);
        })
            .then(() => {
            this.m_readedPKey = {};
            if (this.privateKey !== null) {
                this.m_readedPKey.privateKey = this.privateKey;
            }
            this.StopUpdateKMs();
        })
            .then(() => this.m_library.GetKeyInfoBinary(this.m_readedPKey.privateKey, this.GetKMPasswordTextField('sign').val()))
            .then(() => this.m_library.GetPrivateKeyOwnerInfo())
            .then((endUserPrivateKeyInfo) => {
            let taxCode = endUserPrivateKeyInfo.GetSubjEDRPOUCode();
            // console.log(`taxCodeEdrpou:${taxCode};`);
            if (!taxCode) {
                taxCode = endUserPrivateKeyInfo.GetSubjDRFOCode();
            }
            // console.log(`taxCodeDrfo:${taxCode};`);
            this.userTaxCode = taxCode;
        })
            .then(() => {
            return new Promise((resolve, reject) => {
                let bytes = new Uint8Array(new ArrayBuffer(this.userTaxCode.length));
                for (let i = 0; i < this.userTaxCode.length; i++) {
                    bytes[i] = this.userTaxCode.charCodeAt(i);
                }
                this.data2Sign = bytes;
                resolve();
            });
        })
            .then(() => this.m_library.GetOwnCertificates())
            .then((certArray) => {
            return new Promise((resolve, reject) => {
                // console.log(`certArray.length:${certArray.length}`);
                for (let i = 0; i < certArray.length; i++) {
                    const infoEx = certArray[0].infoEx;
                    //infoEx.
                    // console.log(infoEx);
                    // console.log(`i:${i};`);
                    // console.log(`taxCodeEdrpou:${infoEx.GetSubjEDRPOUCode()};`);
                    // console.log(`taxCodeDrfo:${infoEx.GetSubjDRFOCode()};`);
                    // console.log(`GetKeyUsage:${infoEx.GetKeyUsage()};`);
                    // console.log(`GetKeyUsageType:${infoEx.GetKeyUsageType()};`);
                    // console.log(`GetExtKeyUsages:${infoEx.GetExtKeyUsages()};`);
                    if (infoEx.GetExtKeyUsages() === 'Цифрова печатка') {
                        reject(ERROR_NOT_SIGN_KEY);
                    }
                }
                resolve(certArray);
            });
        })
            .then((certArray) => this.m_library.GetSupportedSignAlgos(certArray))
            .then(() => this.m_library.SignData(this.data2Sign, true, true))
            .then((signature) => {
            // console.log(signature);
            this.signedData = signature;
        })
            .then(() => {
            return new Promise((resolve, reject) => {
                let charsLength = this.signedData.length;
                if (charsLength === undefined) {
                    reject(ERROR_NO_SIGNATURES);
                }
                else {
                    let fData = new FormData();
                    fData.append('taxCode', this.userTaxCode);
                    fData.append('docNum', this.props.docNum);
                    for (let i = 0; i < charsLength; i += 10000) {
                        fData.append('signedData', this.signedData.substring(i, i + 10000));
                    }
                    fetch('/ua/invoice.main.docsAuth', {
                        method: 'POST',
                        body: fData
                    })
                        .then((res) => {
                        if (res.ok) {
                            return res.json();
                        }
                        reject(ERROR_URL_SAVE);
                    })
                        .then((data) => {
                        if (data.ok) {
                            if (data.url) {
                                this.props.onSuccess(`${data.url}&i_docNum=${this.props.docNum}`);
                            }
                            else {
                                reject(data.msg);
                            }
                        }
                        else {
                            reject(data.message);
                        }
                    })
                        .catch((error) => {
                        reject(ERROR_URL_SAVE);
                    });
                }
            });
        })
            .catch((error) => {
            this.hideLoader();
            this.setError(error ? error.toString() : ERROR_SOME);
        });
    }
    _LoadLibrary() {
        if (this.isLoading || this.isLoaded) {
            return;
        }
        this.isLoading = true;
        this.showLoader(PROCESS_STATUS_INSTALL_LIBRARY);
        this.hideAction();
        this.m_library
            .loadLib()
            .then(() => this.m_library.initLib())
            .then(() => {
            this.showAction();
            this.hideLoader();
            this.isLoading = false;
            this.isLoaded = true;
        })
            .catch((error) => {
            this.hideLoader();
            this.setError(error.toString().replace('http://iit.com.ua', 'https://iit.com.ua'));
            this.modalBodyForm.hide();
            this.isLoading = false;
        });
    }
    open() {
        this._LoadLibrary();
        super.openModal();
    }
    //  =======================================================
    _saveIssuerCN(issuerCN) {
        if (issuerCN) {
            sessionStorage.setItem('CAServerIndex', issuerCN);
        }
        else {
            sessionStorage.removeItem('CAServerIndex');
        }
    }
    _getIssuerCN() {
        return sessionStorage.getItem('CAServerIndex');
    }
    //  cert
    GetSelectedCA() {
        if (this.m_library.m_CAs === null || this.m_library.m_CAs.length === 0) {
            return null;
        }
        if (this.m_library.m_CAs.length === 1) {
            return this.m_library.m_CAs[0];
        }
    }
    //  keyMedia
    StopUpdateKMs() {
        this.m_updateKM = false;
    }
    //  pass
    GetKMPasswordTextField(type) {
        return this.modalBody.find('#kmPassword');
    }
    // base64 to unit8Arrau
    base64ToBuffer(base64) {
        let binaryString = window.atob(base64);
        let bytes = new Uint8Array(new ArrayBuffer(binaryString.length));
        for (let i = 0; i < binaryString.length; i++) {
            bytes[i] = binaryString.charCodeAt(i);
        }
        return bytes;
    }
}
exports.default = SignAccessModal;
