import { Injectable } from '@angular/core';
import { GenericService } from '@iqser/common-ui';
import { ILicense, ILicenseReport, ILicenseReportRequest, ILicenses } from '@red/domain';
import { BehaviorSubject, firstValueFrom, Observable, of } from 'rxjs';
import { catchError, filter, tap } from 'rxjs/operators';
import dayjs from 'dayjs';
import { NGXLogger } from 'ngx-logger';

const defaultOnError: ILicenses = {
    activeLicense: 'err',
    licenses: [
        {
            id: 'err',
            name: 'Error',
            product: 'Error',
            licensedTo: 'Error',
            licensedToEmail: 'Error',
            validFrom: '01-01-2022',
            validUntil: '01-01-2023',
            features: [
                {
                    name: 'processingPages',
                    type: 'NUMBER',
                    value: '2000000',
                },
                {
                    name: 'pdftron',
                    type: 'STRING',
                    value:
                        'S25lY29uIEFHKGVuLmtuZWNvbi5zd2lzcyk6T0VNOkREQS1SOjpCKzpBTVMoMj' +
                        'AyMjEwMjkpOkZGQ0M0RDMzMDdEQUI0RjM4QjMxM0JDOUIyNDMzODJDNEU2RjZGQ0I4M0NEOEFDNTc0MzU4QTk1OTczMEI2MjJGQUJFRjVDNw==',
                },
            ],
        },
    ],
};

@Injectable({
    providedIn: 'root',
})
export class LicenseService extends GenericService<ILicenseReport> {
    readonly licenseData$: Observable<ILicenses>;
    readonly selectedLicense$: Observable<ILicense>;
    activeLicenseId: string;
    totalLicensedNumberOfPages = 0;
    currentLicenseReport: ILicenseReport = {};
    allLicensesReport: ILicenseReport = {};
    unlicensedPages = 0;
    analyzedPagesInCurrentLicensingPeriod = 0;
    uploadedBytesCapacity = 0;
    protected readonly _defaultModelPath = 'report';
    readonly #licenseData$ = new BehaviorSubject<ILicenses | undefined>(undefined);
    readonly #selectedLicense$ = new BehaviorSubject<ILicense | undefined>(undefined);

    get selectedLicense() {
        return this.#selectedLicense$.value;
    }

    get activeLicense() {
        if (!this.#licenseData$.value) {
            return undefined;
        }

        const { licenses, activeLicense: activeLicenseId } = this.#licenseData$.value;
        return licenses.find(license => license.id === activeLicenseId);
    }

    get activeLicenseKey(): string {
        return this.activeLicense.features.find(f => f.name === 'pdftron').value;
    }

    constructor(private readonly _logger: NGXLogger) {
        super();
        this.selectedLicense$ = this.#selectedLicense$.pipe(filter(license => !!license));
        this.licenseData$ = this.#licenseData$.pipe(
            filter(licenses => !!licenses),
            tap(data => (this.activeLicenseId = data.activeLicense)),
            tap(() => {
                const uploadedBytesCapacity = this.activeLicense.features.find(f => f.name === 'uploadedBytesCapacity')?.value;
                this.uploadedBytesCapacity = uploadedBytesCapacity ? parseInt(uploadedBytesCapacity, 10) : 0;
            }),
        );
    }

    async loadLicenseData(license: ILicense = this.selectedLicense) {
        this.totalLicensedNumberOfPages = this.getTotalLicensedNumberOfPages(license);

        const startDate = dayjs(license.validFrom);
        const endDate = dayjs(license.validUntil);

        const currentLicenseConfig = {
            startDate: startDate.toDate(),
            endDate: endDate.toDate(),
        };

        const allLicensesConfig = {
            startDate: '2020-01-01T00:00:00.000Z',
            endDate: '2023-12-31T00:00:00.000Z',
        };

        const configs = [currentLicenseConfig, allLicensesConfig];
        const reports = configs.map(config => this.getReport(config));

        [this.currentLicenseReport, this.allLicensesReport] = await Promise.all(reports);

        if (this.currentLicenseReport.numberOfAnalyzedPages > this.totalLicensedNumberOfPages) {
            this.unlicensedPages = this.currentLicenseReport.numberOfAnalyzedPages - this.totalLicensedNumberOfPages;
        } else {
            this.unlicensedPages = 0;
        }
        this.analyzedPagesInCurrentLicensingPeriod = this.currentLicenseReport.numberOfAnalyzedPages;
    }

    getTotalLicensedNumberOfPages(license: ILicense) {
        const processingPagesFeature = license.features?.find(f => f.name === 'processingPages');
        return Number(processingPagesFeature?.value ?? '0');
    }

    setDefaultSelectedLicense() {
        this.setSelectedLicense(this.activeLicense);
    }

    getReport(body: ILicenseReportRequest) {
        return firstValueFrom(this._post(body, `${this._defaultModelPath}/license`));
    }

    async loadLicenses() {
        const licenses$ = this._http.get<ILicenses>(`/${this._serviceName}/license`).pipe(catchError(() => of(defaultOnError)));
        const licenses = await firstValueFrom(licenses$);
        this.#licenseData$.next(licenses);
        this.setDefaultSelectedLicense();
    }

    setSelectedLicense($event: ILicense) {
        this.#selectedLicense$.next($event);
    }
}
