import { Component, OnInit } from '@angular/core';
import { PageRoute, RouterExtensions } from '@nativescript/angular';
import { File, ImageSource, isAndroid, knownFolders, path } from '@nativescript/core';
import { getFile } from '@nativescript/core/http';
import { Select, Store } from '@ngxs/store';
import { Feedback, FeedbackType } from 'nativescript-feedback';
import * as permissions from 'nativescript-permissions';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { PickerProvider } from '~/core/entities/picker-provider';
import { EnrollInvoiceAllPersonOutput } from '~/pages/sts/entities/output/enrollInvoiceAllPersonOutput';
import { EnrollInvoiceDetailOutput } from '~/pages/sts/entities/output/enrollInvoiceDetailOutput';
import { EnrollInvoiceItemAllOutput } from '~/pages/sts/entities/output/enrollInvoiceItemAllOutput';
import { EnrollInvoiceServiceAllOutput } from '~/pages/sts/entities/output/enrollInvoiceServiceAllOutput';
import { PaymentAllEnrollInvoiceOutput } from '~/pages/sts/entities/output/paymentAllEnrollInvoiceOutput';
import {
    ClearQrCodeImageSource,
    LoadEnrollInvoiceAllPayment,
    LoadEnrollInvoiceDetail,
    LoadEnrollInvoiceItemForPhoneNumber,
    LoadEnrollInvoices,
    LoadQrCodeImageSource,
    StartQrCodeDownloading,
    StopQrCodeDownloading
} from '~/pages/sts/state-mgmt/sts-detail-bill.actions';
import { StsDetailBillState } from '~/pages/sts/state-mgmt/sts-detail-bill.state';
import { Item } from '~/shared/components/item-picker/item';
import { DateTimePipe } from '~/shared/pipes/date-time.pipe';

declare var android;

@Component({
    selector: 'StsDetailBill',
    moduleId: module.id,
    templateUrl: './sts-detail-bill.component.html',
    styleUrls: ['./_sts-detail-bill.component.scss']
})
export class StsDetailBillComponent implements OnInit {
    @Select(StsDetailBillState.getEnrollInvoices) enrollInvoices$: Observable<EnrollInvoiceAllPersonOutput[]>;
    @Select(StsDetailBillState.getEnrollInvoiceDetail) enrollInvoiceDetail$: Observable<EnrollInvoiceDetailOutput>;
    @Select(StsDetailBillState.getEnrollInvoiceItemForPhoneNumber) enrollInvoiceItemForPhoneNumber$: Observable<EnrollInvoiceItemAllOutput>;
    @Select(StsDetailBillState.getEnrollInvoiceItemServices) enrollInvoiceItemServices$: Observable<EnrollInvoiceServiceAllOutput[]>;
    @Select(StsDetailBillState.getEnrollInvoiceAllPayments) enrollInvoiceAllPayments$: Observable<PaymentAllEnrollInvoiceOutput[]>;
    @Select(StsDetailBillState.getQrCodeImageSource) qrCodeImageSource$: Observable<ImageSource>;
    @Select(StsDetailBillState.isLoading) isLoading$: Observable<boolean>;
    enrollInvoiceItemForPhoneNumber: EnrollInvoiceItemAllOutput;
    enrollInvoicePayment: PaymentAllEnrollInvoiceOutput;
    enrollInvoiceDetail: EnrollInvoiceDetailOutput;
    qrCodeImageSource: ImageSource;
    invoice: Item;
    invoiceLabel: string;
    enrollInvoicesProvider: PickerProvider[];

    phoneNumber: string;
    feedback: Feedback;

    constructor(
        private routerExtensions: RouterExtensions,
        private pageRoute: PageRoute,
        private store: Store,
        private dateTimePipe: DateTimePipe
    ) {
    }

    ngOnInit() {
        this.feedback = new Feedback();
        this.invoice = new Item(0);
        this.pageRoute.activatedRoute
            .pipe(
                switchMap(activatedRoute => activatedRoute.params)
            )
            .forEach((params) => {
                this.phoneNumber = params['number'];

                if (this.phoneNumber) {
                    this.store.dispatch(new LoadEnrollInvoices());
                }
            });

        this.setEnrollInvoiceInfo();
        this.enrollInvoices$.subscribe(enrollInvoices => {
            if (enrollInvoices && enrollInvoices.length > 0) {
                this.enrollInvoicesProvider = enrollInvoices.map(invoice => {
                    return new PickerProvider(
                        invoice.ID,
                        `${invoice.DisplayName} (${this.dateTimePipe.transform(invoice.DateFrom, false)} - ${this.dateTimePipe.transform(invoice.DateTo, false)})`
                    );
                });

            }
        });

        this.enrollInvoiceItemForPhoneNumber$.subscribe(
            eiItemForPhoneNumber => {
                this.enrollInvoiceItemForPhoneNumber = eiItemForPhoneNumber;
            }
        );

        this.enrollInvoiceDetail$.subscribe(
            enrollInvoiceDetail => {
                this.enrollInvoiceDetail = enrollInvoiceDetail;
            }
        );

        this.enrollInvoiceAllPayments$.subscribe(
            enrollInvoiceAllPayments => {
                this.enrollInvoicePayment = enrollInvoiceAllPayments.length > 0 ? enrollInvoiceAllPayments[0] : null;

                if (this.enrollInvoicePayment) {
                    this.store.dispatch(
                        new LoadQrCodeImageSource(this.enrollInvoicePayment.Account, this.enrollInvoicePayment.Amount, this.enrollInvoicePayment.VS)
                    );
                }
            }
        );

        this.qrCodeImageSource$.subscribe(
            qrCodeImageSource => {
                this.qrCodeImageSource = qrCodeImageSource;
            }
        );
    }

    onDownloadInvoice() {
        // https://blog.jscrambler.com/create-a-file-storage-mobile-app-with-nativescript-5/
        // https://github.com/NickIliev/NS-Issues-2017/blob/master/NativeScript/issue_4486_ng/app/item/items.component.ts
        // https://github.com/NativeScript/NativeScript/issues/4486
        // https://github.com/NativeScript/NativeScript/issues/4506
        // https://discourse.nativescript.org/t/decode-base64-string-to-pdf/1116/4
        // https://stackoverflow.com/questions/36469642/how-do-i-open-a-file-with-the-default-application
        // https://discourse.nativescript.org/t/show-pdf-in-view/6139
        // https://github.com/NativeScript/NativeScript/issues/4874
        // https://stackoverflow.com/questions/43842644/base64-encode-decode-in-nativescript-with-angular-2
        // https://docs.nativescript.org/ns-framework-modules/image-source
        // https://docs.nativescript.org/angular/ui/ng-ui-widgets/image
        // https://docs.nativescript.org/ns-framework-modules/file-system#read

        // https://stackoverflow.com/questions/38309378/displaying-a-pdf-from-a-url-in-nativescript
        let filePath;
        if (isAndroid) {
            permissions.requestPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, 'We need permissions for storage invoice.');
            filePath = path.join(
                android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(),
                this.enrollInvoiceDetail.DisplayName + 'bad.pdf'
            );
        } else {
            filePath = path.join(knownFolders.ios.downloads().path, this.enrollInvoiceDetail.DisplayName + 'bad.pdf');
        }

        const url = 'https://test-is.skaut.cz/Junak/Document/Download.ashx?ID=' + this.enrollInvoiceDetail.ID_Document;
        // https://docs.nativescript.org/ns-framework-modules/http
        getFile(url, filePath).then(file => {
                this.feedback.show({
                    title: 'SUCCESS',
                    type: FeedbackType.Success,
                    message: 'Faktura byla stažena do zařízení.'
                });
            },
            e => {
                console.log(e);
                this.feedback.show({
                    title: 'ERROR',
                    type: FeedbackType.Error,
                    message: e
                });
            }
        );
    }

    onDownloadQrCode() {
        this.store.dispatch(new StartQrCodeDownloading());
        let filePath;
        if (isAndroid) {
            permissions.requestPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, 'We need permissions for storage qr code image.');
            filePath = path.join(
                android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(),
                this.enrollInvoicePayment.VS + '_qr_code.png'
            );
        } else {
            filePath = path.join(knownFolders.ios.downloads().path, this.enrollInvoicePayment.VS + '_qr_code.png');
        }
        const mySavedFile = File.fromPath(filePath);

        const saved = this.qrCodeImageSource.saveToFile(mySavedFile.path, 'png', 100);
        if (saved) {
            this.feedback.show({
                title: 'SUCCESS',
                type: FeedbackType.Success,
                message: 'QR kód pro zaplacení faktury byl uložen do zařízení.'
            });
        }
        this.store.dispatch(new StopQrCodeDownloading());
    }

    /**
     * Callback called if invoice picker was select / change,
     * then set property and dispatch action for load EnrolInvoiceInfo
     *
     * @param {number|string} invoiceId
     */
    onSelectedInvoice(invoiceId: number | string) {
        if (!this.invoice || this.invoice.id !== invoiceId) {
            this.invoice = new Item(invoiceId);
            const enrollInvoice = this.enrollInvoicesProvider.find((x: PickerProvider) => this.invoice && x.key === this.invoice.id);
            if (enrollInvoice) {
                this.invoiceLabel = enrollInvoice.label;
            }
            this.setEnrollInvoiceInfo();
        }
    }

    onBackButton(): void {
        this.routerExtensions.back();
    }

    /**
     * It dispatch action for load invoice item for selected number invoice
     */
    private setEnrollInvoiceInfo() {
        this.store.dispatch(new ClearQrCodeImageSource());
        if (this.invoice.id !== 0) {
            this.store.dispatch(new LoadEnrollInvoiceItemForPhoneNumber(+this.invoice.id, this.phoneNumber));
            this.store.dispatch(new LoadEnrollInvoiceDetail(+this.invoice.id));
            this.store.dispatch(new LoadEnrollInvoiceAllPayment(+this.invoice.id));
        }
    }
}
