import { MiniProgramCore, PAGE_TOKEN, MiniProgramRendererFactory, ComponentFinderService } from 'angular-miniprogram/platform/wx';
export { ComponentFinderService, PAGE_TOKEN, propertyChange } from 'angular-miniprogram/platform/wx';
import { HttpResponse, HttpContextToken, HttpHeaderResponse, HttpHeaders, HttpEventType, HttpErrorResponse, provideHttpClient, HttpBackend, withInterceptorsFromDi } from 'angular-miniprogram/common/http';
import { Observable } from 'rxjs';
import * as i0 from '@angular/core';
import { NgModule, InjectionToken, Injector, createNgModuleRef, Injectable, Inject, ErrorHandler, ɵINJECTOR_SCOPE, RendererFactory2, ApplicationModule, createPlatformFactory, platformCore } from '@angular/core';
import { CommonModule } from 'angular-miniprogram/common';

class MiniProgramHttpResponse extends HttpResponse {
    /**
     * 开发者服务器返回的 cookies，格式为字符串数组
     */
    cookies;
    /**
     * 网络请求过程中一些调试信息，[查看详细说明](https://developers.weixin.qq.com/miniprogram/dev/framework/performance/network.html)
     */
    profile;
    /**
     * Construct a new `WxHttpResponse`.
     */
    constructor(init = {}) {
        super(init);
        this.cookies = init.cookies ?? null;
        this.profile = init.profile ?? null;
    }
    clone(update = {}) {
        return new MiniProgramHttpResponse({
            body: update.body !== undefined ? update.body : this.body,
            headers: update.headers || this.headers,
            status: update.status !== undefined ? update.status : this.status,
            statusText: update.statusText || this.statusText,
            url: update.url || this.url || undefined,
            cookies: update.cookies || this.cookies || undefined,
            profile: update.profile || this.profile || undefined,
        });
    }
}
class MiniProgramHttpDownloadResponse extends HttpResponse {
    /** 用户文件路径 (本地路径)。传入 filePath 时会返回，跟传入的 filePath 一致 */
    filePath;
    /** 临时文件路径 (本地路径)。没传入 filePath 指定文件存储路径时会返回，下载后的文件会存储到一个临时文件 */
    tempFilePath;
    /**
     * 网络请求过程中一些调试信息，[查看详细说明](https://developers.weixin.qq.com/miniprogram/dev/framework/performance/network.html)
     */
    profile;
    /**
     * Construct a new `WxHttpDownloadResponse`.
     */
    constructor(init = {}) {
        super(init);
        this.filePath = init.filePath ?? null;
        this.tempFilePath = init.tempFilePath ?? null;
        this.profile = init.profile ?? null;
    }
    clone(update = {}) {
        return new MiniProgramHttpDownloadResponse({
            body: update.body !== undefined ? update.body : this.body,
            headers: update.headers || this.headers,
            status: update.status !== undefined ? update.status : this.status,
            statusText: update.statusText || this.statusText,
            url: update.url || this.url || undefined,
            filePath: update.filePath || this.filePath || undefined,
            tempFilePath: update.tempFilePath || this.tempFilePath || undefined,
            profile: update.profile || this.profile || undefined,
        });
    }
}

/** Use this token to pass additional `wx.uploadFile()` parameter */
const UPLOAD_FILE_TOKEN = new HttpContextToken(() => ({}));
/** Use this token to pass additional `wx.downloadFile()` parameter */
const DOWNLOAD_FILE_TOKEN = new HttpContextToken(() => ({}));
/** Use this token to pass additional `wx.request()` parameter */
const REQUSET_TOKEN = new HttpContextToken(() => ({}));
class MiniprogramHttpBackend {
    handle(request) {
        if (request.method === 'POST' &&
            // TODO angular v13.1 后采用 context.has()
            request.context.get(UPLOAD_FILE_TOKEN)?.filePath) {
            return this.upload(request);
        }
        if (request.method === 'GET' &&
            // TODO angular v13.1 后采用 context.has()
            request.context.get(DOWNLOAD_FILE_TOKEN)?.filePath) {
            return this.download(request);
        }
        return this.request(request);
    }
    /**
     * wx upload file
     * @param request
     */
    upload(request) {
        return new Observable((observer) => {
            let currentZone = Zone.current;
            // The response header event handler
            const onHeadersReceived = ({ header, }) => {
                currentZone.run(() => {
                    observer.next(new HttpHeaderResponse({
                        url: request.url,
                        headers: new HttpHeaders(header),
                    }));
                });
            };
            // The upload progress event handler
            const onUpProgressUpdate = ({ totalBytesSent, totalBytesExpectedToSend }) => {
                currentZone.run(() => {
                    observer.next({
                        type: HttpEventType.UploadProgress,
                        loaded: totalBytesSent,
                        total: totalBytesExpectedToSend,
                    });
                });
            };
            const { filePath, name, timeout } = request.context.get(UPLOAD_FILE_TOKEN);
            const task = MiniProgramCore.MINIPROGRAM_GLOBAL.uploadFile({
                url: request.urlWithParams,
                filePath: filePath,
                name: name,
                header: this.buildHeaders(request),
                formData: request.body,
                timeout: timeout,
                success: ({ data, statusCode: status, errMsg: statusText }) => {
                    currentZone.run(() => {
                        let ok = status >= 200 && status < 300;
                        let body = null;
                        if (request.responseType === 'json' &&
                            typeof data === 'string' &&
                            data !== '') {
                            try {
                                body = JSON.parse(data);
                            }
                            catch (error) {
                                if (ok) {
                                    ok = false;
                                    body = { error, text: body };
                                }
                            }
                        }
                        if (ok) {
                            observer.next(new HttpResponse({
                                url: request.url,
                                body,
                                status,
                                statusText,
                            }));
                            observer.complete();
                        }
                        else {
                            observer.error(new HttpErrorResponse({
                                url: request.url,
                                error: body,
                                status,
                                statusText,
                            }));
                        }
                    });
                },
                fail: ({ errMsg }) => {
                    currentZone.run(() => {
                        observer.error(new HttpErrorResponse({
                            url: request.url,
                            statusText: errMsg,
                        }));
                    });
                },
            });
            observer.next({ type: HttpEventType.Sent });
            if (request.reportProgress) {
                task.onHeadersReceived(onHeadersReceived);
                task.onProgressUpdate(onUpProgressUpdate);
            }
            return () => {
                if (request.reportProgress) {
                    task.offHeadersReceived(onHeadersReceived);
                    task.offProgressUpdate(onUpProgressUpdate);
                }
                task.abort();
            };
        });
    }
    /**
     * wx download file
     * @param request
     */
    download(request) {
        return new Observable((observer) => {
            let currentZone = Zone.current;
            // The response header event handler
            const onHeadersReceived = ({ header, }) => {
                currentZone.run(() => {
                    observer.next(new HttpHeaderResponse({
                        url: request.url,
                        headers: new HttpHeaders(header),
                    }));
                });
            };
            // The download progress event handler
            const onDownProgressUpdate = ({ totalBytesWritten, totalBytesExpectedToWrite }) => {
                currentZone.run(() => {
                    observer.next({
                        type: HttpEventType.DownloadProgress,
                        loaded: totalBytesWritten,
                        total: totalBytesExpectedToWrite,
                    });
                });
            };
            const { filePath, timeout } = request.context.get(DOWNLOAD_FILE_TOKEN);
            const task = MiniProgramCore.MINIPROGRAM_GLOBAL.downloadFile({
                url: request.urlWithParams,
                filePath: filePath,
                header: this.buildHeaders(request),
                timeout: timeout,
                success: ({ statusCode: status, errMsg: statusText, filePath, tempFilePath, profile, }) => {
                    Zone.run(() => {
                        const ok = status >= 200 && status < 300;
                        if (ok) {
                            observer.next(new MiniProgramHttpDownloadResponse({
                                url: request.url,
                                status,
                                statusText,
                                filePath,
                                tempFilePath,
                                profile,
                            }));
                            observer.complete();
                        }
                        else {
                            observer.error(new HttpErrorResponse({
                                url: request.url,
                                status,
                                statusText,
                            }));
                        }
                    });
                },
                fail: ({ errMsg }) => {
                    currentZone.run(() => {
                        observer.error(new HttpErrorResponse({
                            url: request.url,
                            statusText: errMsg,
                        }));
                    });
                },
            });
            observer.next({ type: HttpEventType.Sent });
            if (request.reportProgress) {
                task.onHeadersReceived(onHeadersReceived);
                task.onProgressUpdate(onDownProgressUpdate);
            }
            return () => {
                if (request.reportProgress) {
                    task.offHeadersReceived(onHeadersReceived);
                    task.offProgressUpdate(onDownProgressUpdate);
                }
                task.abort();
            };
        });
    }
    /**
     * wx http request
     * @param request
     */
    request(request) {
        if (['PATCH', 'JSONP'].includes(request.method)) {
            throw Error('WeChat MiniProgram does not support http method as ' + request.method);
        }
        return new Observable((observer) => {
            let currentZone = Zone.current;
            // The response header event handler
            const onHeadersReceived = ({ header, }) => {
                currentZone.run(() => {
                    observer.next(new HttpHeaderResponse({
                        url: request.url,
                        headers: new HttpHeaders(header),
                    }));
                });
            };
            const task = MiniProgramCore.MINIPROGRAM_GLOBAL.request({
                url: request.urlWithParams,
                method: request.method,
                data: request.body,
                header: this.buildHeaders(request),
                // wx 从 responseType 中拆分出 dataType，这里需要处理一下
                responseType: request.responseType === 'arraybuffer'
                    ? request.responseType
                    : 'text',
                dataType: request.responseType === 'json' ? request.responseType : '其他',
                success: ({ data, header, statusCode: status, errMsg: statusText, cookies, profile, }) => {
                    currentZone.run(() => {
                        const ok = status >= 200 && status < 300;
                        const headers = new HttpHeaders(header);
                        if (ok) {
                            observer.next(new MiniProgramHttpResponse({
                                url: request.url,
                                body: data,
                                status,
                                statusText,
                                headers,
                                cookies,
                                profile,
                            }));
                            observer.complete();
                        }
                        else {
                            observer.error(new HttpErrorResponse({
                                url: request.url,
                                error: data,
                                status,
                                statusText,
                                headers,
                            }));
                        }
                    });
                },
                fail: ({ errMsg }) => {
                    currentZone.run(() => {
                        observer.error(new HttpErrorResponse({
                            url: request.url,
                            statusText: errMsg,
                        }));
                    });
                },
                ...request.context.get(REQUSET_TOKEN),
            });
            observer.next({ type: HttpEventType.Sent });
            if (request.reportProgress) {
                task.onHeadersReceived(onHeadersReceived);
            }
            return () => {
                if (request.reportProgress) {
                    task.offHeadersReceived(onHeadersReceived);
                }
                task.abort();
            };
        });
    }
    buildHeaders(request) {
        return request.headers.keys().reduce((headers, name) => {
            headers[name] = request.headers.getAll(name).join(',');
            return headers;
        }, {});
    }
}

class HttpClientModule {
    static ɵfac = function HttpClientModule_Factory(t) { return new (t || HttpClientModule)(); };
    static ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: HttpClientModule });
    static ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ providers: [
            MiniprogramHttpBackend,
            provideHttpClient({
                ɵkind: 2,
                ɵproviders: [
                    { provide: HttpBackend, useExisting: MiniprogramHttpBackend },
                ],
            }, withInterceptorsFromDi()),
        ] });
}
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HttpClientModule, [{
        type: NgModule,
        args: [{
                declarations: [],
                imports: [],
                exports: [],
                providers: [
                    MiniprogramHttpBackend,
                    provideHttpClient({
                        ɵkind: 2,
                        ɵproviders: [
                            { provide: HttpBackend, useExisting: MiniprogramHttpBackend },
                        ],
                    }, withInterceptorsFromDi()),
                ],
            }]
    }], null, null); })();

const APP_TOKEN = new InjectionToken('APP_TOKEN');
const MINIPROGRAM_GLOBAL_TOKEN = new InjectionToken('MINIPROGRAM_GLOBAL_TOKEN');

class PageService {
    injector;
    applicationRef;
    app;
    ngZone;
    constructor(injector, applicationRef, app, ngZone) {
        this.injector = injector;
        this.applicationRef = applicationRef;
        this.app = app;
        this.ngZone = ngZone;
    }
    register() {
        this.app.__ngStartPage = (module, component, miniProgramComponentInstance) => {
            return this.ngZone.run(() => {
                const injector = Injector.create({
                    providers: [
                        { provide: PAGE_TOKEN, useValue: miniProgramComponentInstance },
                    ],
                    parent: this.injector,
                });
                const ngModuleRef = createNgModuleRef(module, injector);
                const componentFactory = ngModuleRef.componentFactoryResolver.resolveComponentFactory(component);
                const componentRef = componentFactory.create(injector);
                this.applicationRef.attachView(componentRef.hostView);
                return { componentRef, ngModuleRef };
            });
        };
        this.app.__ngStartPageResolve();
    }
    static ɵfac = function PageService_Factory(t) { return new (t || PageService)(i0.ɵɵinject(i0.Injector), i0.ɵɵinject(i0.ApplicationRef), i0.ɵɵinject(APP_TOKEN), i0.ɵɵinject(i0.NgZone)); };
    static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: PageService, factory: PageService.ɵfac });
}
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PageService, [{
        type: Injectable
    }], function () { return [{ type: i0.Injector }, { type: i0.ApplicationRef }, { type: undefined, decorators: [{
                type: Inject,
                args: [APP_TOKEN]
            }] }, { type: i0.NgZone }]; }, null); })();

function errorHandler() {
    return new ErrorHandler();
}
class MiniProgramModule {
    constructor(pageService) {
        pageService.register();
    }
    static ɵfac = function MiniProgramModule_Factory(t) { return new (t || MiniProgramModule)(i0.ɵɵinject(PageService)); };
    static ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: MiniProgramModule });
    static ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ providers: [
            { provide: ɵINJECTOR_SCOPE, useValue: 'root' },
            { provide: ErrorHandler, useFactory: errorHandler, deps: [] },
            MiniProgramRendererFactory,
            {
                provide: RendererFactory2,
                useExisting: MiniProgramRendererFactory,
            },
            PageService,
            ComponentFinderService,
        ], imports: [CommonModule, ApplicationModule, CommonModule, ApplicationModule] });
}
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MiniProgramModule, [{
        type: NgModule,
        args: [{
                declarations: [],
                imports: [CommonModule, ApplicationModule],
                providers: [
                    { provide: ɵINJECTOR_SCOPE, useValue: 'root' },
                    { provide: ErrorHandler, useFactory: errorHandler, deps: [] },
                    MiniProgramRendererFactory,
                    {
                        provide: RendererFactory2,
                        useExisting: MiniProgramRendererFactory,
                    },
                    PageService,
                    ComponentFinderService,
                ],
                exports: [CommonModule, ApplicationModule],
            }]
    }], function () { return [{ type: PageService }]; }, null); })();
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MiniProgramModule, { imports: [CommonModule, ApplicationModule], exports: [CommonModule, ApplicationModule] }); })();

function platformMiniProgram(extraProviders = [], app) {
    return createPlatformFactory(platformCore, 'miniProgram', [
        { provide: APP_TOKEN, useValue: MiniProgramCore.loadApp(app || {}) },
        {
            provide: MINIPROGRAM_GLOBAL_TOKEN,
            useValue: MiniProgramCore.MINIPROGRAM_GLOBAL,
        },
    ])(extraProviders);
}

const pageStartup = MiniProgramCore.pageStartup;
const componentRegistry = MiniProgramCore.componentRegistry;

/**
 * Generated bundle index. Do not edit.
 */
;

export { APP_TOKEN, DOWNLOAD_FILE_TOKEN, HttpClientModule, MINIPROGRAM_GLOBAL_TOKEN, MiniProgramHttpDownloadResponse, MiniProgramHttpResponse, MiniProgramModule, MiniprogramHttpBackend, REQUSET_TOKEN, UPLOAD_FILE_TOKEN, componentRegistry, pageStartup, platformMiniProgram };
//# sourceMappingURL=angular-miniprogram.mjs.map
