import { CdkDrag, CdkDragDrop, CdkDragHandle, CdkDropList, moveItemInArray } from '@angular/cdk/drag-drop';
import { KeyValuePipe, NgClass, NgForOf, NgIf } from '@angular/common';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatIcon } from '@angular/material/icon';
import { FilterService } from '@common-ui/filtering';
import { CircleButtonComponent, IconButtonComponent, IconButtonTypes, IqserDialog } from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core';
import { IComponentLogEntry } from '@red/domain';
import { RevertValueDialogComponent } from '../../dialogs/docu-mine/revert-value-dialog/revert-value-dialog.component';

@Component({
    selector: 'redaction-editable-structured-component-value [entry] [canEdit]',
    templateUrl: './editable-structured-component-value.component.html',
    styleUrls: ['./editable-structured-component-value.component.scss'],
    standalone: true,
    imports: [
        CircleButtonComponent,
        NgClass,
        TranslateModule,
        KeyValuePipe,
        CdkDropList,
        MatIcon,
        IconButtonComponent,
        CdkDrag,
        NgIf,
        NgForOf,
        CdkDragHandle,
        FormsModule,
    ],
})
export class EditableStructuredComponentValueComponent implements OnInit {
    protected entryLabel: string;
    protected editing = false;
    protected hasUpdatedValues = false;
    protected initialEntry: IComponentLogEntry;
    protected readonly iconButtonTypes = IconButtonTypes;
    @Input() entry: IComponentLogEntry;
    @Input() canEdit: boolean;
    @Output() readonly deselectLast = new EventEmitter();
    @Output() readonly overrideValue = new EventEmitter<IComponentLogEntry>();
    @Output() readonly revertOverride = new EventEmitter<string>();
    selected = false;

    constructor(
        private readonly _filtersService: FilterService,
        private readonly _iqserDialog: IqserDialog,
    ) {}

    get disabled() {
        for (let i = 0; i < this.entry.componentValues.length; i++) {
            if (this.entry.componentValues[i].value !== this.initialEntry.componentValues[i]?.value) {
                return false;
            }
        }
        return this.entry.componentValues.length === this.initialEntry.componentValues.length;
    }

    get #hasUpdatedValues() {
        for (const value of this.entry.componentValues) {
            if (value.originalValue === null && value.value === '') {
                continue;
            }
            if (value.originalValue !== value.value) {
                return true;
            }
        }
        return false;
    }

    get #initialEntry() {
        return JSON.parse(JSON.stringify(this.entry));
    }

    ngOnInit() {
        this.reset();
    }

    reset() {
        this.initialEntry = this.#initialEntry;
        this.hasUpdatedValues = this.#hasUpdatedValues;
        this.entryLabel = this.parseName(this.entry.name);
        this.deselect();
    }

    select() {
        if (!this.editing) {
            if (this.selected) {
                this.deselect();
                return;
            }
            this.deselectLast.emit();
            this.selected = true;
            this.#setWorkloadFilters();
        }
    }

    edit() {
        this.deselectLast.emit();
        this.selected = true;
        this.editing = true;
        this.#updateTextAreaHeight();
    }

    deselect($event?: MouseEvent) {
        $event?.stopImmediatePropagation();
        this.selected = false;
        this.editing = false;
        this._filtersService.deactivateFilters({ primaryFiltersSlug: 'primaryFilters' });
    }

    removeValue(index: number) {
        this.entry.componentValues.splice(index, 1);
    }

    save() {
        this.entry.overridden = true;
        this.overrideValue.emit(this.entry);
        this.reset();
    }

    async undo() {
        const dialog = this._iqserDialog.openDefault(RevertValueDialogComponent, { data: { entry: this.entry }, width: '800px' });
        const result = await dialog.result();
        if (result) {
            this.revertOverride.emit(this.entry.name);
            this.reset();
        }
    }

    add() {
        this.entry.componentValues.push({
            componentRuleId: null,
            entityReferences: [],
            originalValue: null,
            value: '',
            valueDescription: '',
        });
    }

    drop(event: CdkDragDrop<string>) {
        moveItemInArray(this.entry.componentValues, event.previousIndex, event.currentIndex);
    }

    parseName(name: string) {
        return name.replaceAll('_', ' ');
    }

    transformNewLines(value: string) {
        return value.replace(/\n/g, '<br>');
    }

    #setWorkloadFilters() {
        this._filtersService.deactivateFilters({ primaryFiltersSlug: 'primaryFilters' });
        const filterSet = this.#setFilter(this.entryLabel);
        if (!filterSet) {
            this.#setFilter('no-annotations-filter');
        }
    }

    #setFilter(label: string) {
        const filterGroup = this._filtersService.getGroup('primaryFilters');
        for (const filter of filterGroup.filters) {
            const nestedFilter = filter.children.find(f => f.label === label);
            if (nestedFilter) {
                this._filtersService.filterCheckboxClicked({ nestedFilter, filterGroup, primaryFiltersSlug: 'primaryFilters' });
                return true;
            }
        }
    }

    #updateTextAreaHeight() {
        setTimeout(() => {
            for (let i = 0; i < this.entry.componentValues.length; i++) {
                const textArea = document.getElementById(`value-input-${i}`);
                textArea.style.height = 'auto';
                textArea.style.height = `${textArea.scrollHeight}px`;
            }
        }, 10);
    }
}
