import { Component, OnInit } from '@angular/core';
import { FormBuilder, ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import {
    CircleButtonComponent,
    HasScrollbarDirective,
    IconButtonComponent,
    IqserDenyDirective,
    IqserDialogComponent,
    Toaster,
} from '@iqser/common-ui';
import { Dossier, IAddRedactionRequest, SuperTypes } from '@red/domain';
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { Roles } from '@users/roles';
import { firstValueFrom } from 'rxjs';
import { ManualRedactionService } from '../../services/manual-redaction.service';
import { NgForOf, NgIf } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatFormField } from '@angular/material/form-field';
import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select';
import { MatTooltip } from '@angular/material/tooltip';
import { MatCheckbox } from '@angular/material/checkbox';
import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option';
import {
    LegalBasisOption,
    RectangleDialogData,
    RectangleDialogResult,
    RectangleRedactOption,
    RectangleRedactOptions,
} from '../../utils/dialog-types';
import { getRectangleRedactOptions } from '../../utils/dialog-options';
import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component';
import { SystemDefaults } from '../../../account/utils/dialog-defaults';
import { validatePageRange } from '../../utils/form-validators';

export const NON_READABLE_CONTENT = 'non-readable content';

@Component({
    templateUrl: './rectangle-annotation-dialog.component.html',
    styleUrls: ['./rectangle-annotation-dialog.component.scss'],
    standalone: true,
    imports: [
        ReactiveFormsModule,
        NgIf,
        CircleButtonComponent,
        TranslateModule,
        HasScrollbarDirective,
        MatFormField,
        MatSelectTrigger,
        MatSelect,
        MatOption,
        NgForOf,
        MatTooltip,
        IqserDenyDirective,
        MatCheckbox,
        IconButtonComponent,
        DetailsRadioComponent,
    ],
    providers: [ManualRedactionService],
})
export class RectangleAnnotationDialog
    extends IqserDialogComponent<RectangleAnnotationDialog, RectangleDialogData, RectangleDialogResult>
    implements OnInit
{
    readonly #dossier: Dossier;
    protected readonly roles = Roles;
    protected readonly options: DetailsRadioOption<RectangleRedactOption>[];
    protected legalOptions: LegalBasisOption[] = [];

    readonly form: UntypedFormGroup;

    constructor(
        private readonly activeDossiersService: ActiveDossiersService,
        private readonly _justificationsService: JustificationsService,
        private readonly _formBuilder: FormBuilder,
        private readonly _toaster: Toaster,
    ) {
        super();
        this.#dossier = this.activeDossiersService.find(this.data.dossierId);

        this.options = getRectangleRedactOptions();

        this.form = this.#getForm();
        this.initialFormValue = this.form.getRawValue();
    }

    get #isMultiplePages() {
        return this.form.get('option').value.value === RectangleRedactOptions.MULTIPLE_PAGES;
    }

    extraOptionChanged(option: DetailsRadioOption<RectangleRedactOption>): void {
        if (option.value === RectangleRedactOptions.MULTIPLE_PAGES) {
            setTimeout(() => {
                this.form.get('option')?.updateValueAndValidity();
            }, 0);
        }
    }

    async ngOnInit() {
        const data = await firstValueFrom(this._justificationsService.getForDossierTemplate(this.#dossier.dossierTemplateId));
        this.legalOptions = data.map(lbm => ({
            legalBasis: lbm.reason,
            description: lbm.description,
            label: lbm.name,
        }));

        this.legalOptions.sort((a, b) => a.label.localeCompare(b.label));

        this.#selectReason();
    }

    save() {
        this.#enhanceManualRedaction(this.data.manualRedactionEntryWrapper.manualRedactionEntry);
        try {
            const annotation = (this.#isMultiplePages ? this.#multiplePagesRectangle : this.data.manualRedactionEntryWrapper)
                .manualRedactionEntry;
            super.close({
                annotation,
            });
        } catch (e) {
            this._toaster.error(_('manual-annotation.dialog.error'));
        }
    }

    #getForm() {
        return this._formBuilder.group({
            selectedText: this.data?.manualRedactionEntryWrapper?.manualRedactionEntry?.value,
            section: [null],
            reason: [null, Validators.required],
            comment: [null],
            classification: [NON_READABLE_CONTENT],
            option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange(this.data.file.numberOfPages)],
        });
    }

    #enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) {
        const legalOption: LegalBasisOption = this.form.get('reason').value;
        addRedactionRequest.type = SuperTypes.ManualRedaction;
        if (legalOption) {
            addRedactionRequest.reason = legalOption.description;
            addRedactionRequest.legalBasis = legalOption.legalBasis;
        }

        addRedactionRequest.addToDictionary = false;
        const commentValue = this.form.get('comment').value;
        addRedactionRequest.comment = commentValue ? (this.#isMultiplePages ? commentValue : { text: commentValue }) : null;
        addRedactionRequest.section = this.form.get('section').value;
        addRedactionRequest.value = this.form.get('classification').value;
    }

    #getOption(option: RectangleRedactOption): DetailsRadioOption<RectangleRedactOption> {
        return this.options.find(o => o.value === option);
    }

    get #multiplePagesRectangle() {
        const value: string = this.form.get('option').value.additionalInput.value.replace(/[^0-9-,]/g, '');
        const entry = { ...this.data.manualRedactionEntryWrapper.manualRedactionEntry, pageNumbers: [] };
        const wrapper = {
            ...this.data.manualRedactionEntryWrapper,
            manualRedactionEntry: entry,
        };

        value.split(',').forEach(range => {
            const splitted = range.split('-');
            const startPage = parseInt(splitted[0], 10);
            const endPage = splitted.length > 1 ? parseInt(splitted[1], 10) : startPage;
            if (!startPage || !endPage || startPage > this.data.file.numberOfPages || endPage > this.data.file.numberOfPages) {
                throw new Error();
            }

            for (let page = startPage; page <= endPage; page++) {
                wrapper.manualRedactionEntry.pageNumbers.push(page);
            }
        });

        return wrapper;
    }

    #selectReason() {
        if (this.legalOptions.length === 1) {
            this.form.get('reason').setValue(this.legalOptions[0]);
        }
    }
}
