import {Component, Input, OnInit} from '@angular/core';
import {EditorNodeContract} from '../EditorNode.contract';
import {EditorService} from '../../../service/editor.service';
import {ModalController} from '@ionic/angular';
import {FormInputOptionsComponent} from './options/form-input-options.component';
import {DbApiService} from '../../../service/db-api.service';

export interface FormSelectChoiceObject {
    display: string;
    value: string;
}

@Component({
    selector: 'editor-node-form-input',
    templateUrl: './form-input.component.html',
    styleUrls: ['./form-input.component.scss'],
})
export class FormInputComponent extends EditorNodeContract implements OnInit {
    @Input() nodeId: string;
    @Input() editorUUID?: string;
    @Input() isFilloutMode = false;

    public initialValue: any;
    public value: any;
    public forceDirty = false;

    // TODO load this from somewhere
    public selectChoices: FormSelectChoiceObject[] = [];

    constructor(
        public editorService: EditorService,
        public readonly modals: ModalController,
        public readonly dbApi: DbApiService,
    ) {
        super();
    }

    public isDark() {
        return document.body.classList.contains('dark');
    }

    public get isReadonly(): boolean {
        return !this.editorService.canEdit();
    }

    ngOnInit() {
        this.editorService = this.editorService.getEditor(this.editorUUID);
        this.editorService.registerNodeEditor(this.nodeId, this).then(() => {
            console.log('form input node', this.node);
            if ( !this.node.AdditionalData ) {
                this.node.AdditionalData = {};
            }

            this.initialValue = this.value = this.isFilloutMode ? undefined : this.node.Value.Value;

            if ( this.node.type === 'form_input_select' || this.node.type === 'form_input_multiselect' ) {
                if ( this.node.AdditionalData.selectSource === 'local' ) {
                    this.selectChoices = [...this.node.AdditionalData.selectStaticOptions];
                } else if ( this.node.AdditionalData.selectSource === 'database' ) {
                    this.loadSelectOptionsFromDatabase();
                }
            }
        });
    }

    async loadSelectOptionsFromDatabase() {
        try {
            const db = await this.dbApi.getDatabase(this.node.AdditionalData.selectSourceDatabaseId);
            if ( db ) {
                const data = await db.data();
                console.log('loaded db data', data, this.node.AdditionalData);
                this.selectChoices = data.map(x => {
                    return {
                        display: x.data[this.node.AdditionalData.selectDatabaseDisplayColumnId],
                        value: x.data[this.node.AdditionalData.selectDatabaseValueColumnId],
                    };
                });
            }
        } catch (e: unknown) {
            this.selectChoices = [];
        }
    }

    triggerChangeCheck() {
        this.editorService.triggerSave();
    }

    public isDirty(): boolean | Promise<boolean> {
        return this.value !== this.initialValue || this.forceDirty;
    }

    // FIXME this isn't saving properly, write Mode = 'form'
    public writeChangesToNode(): void | Promise<void> {
        this.node.Value.Value = this.value;
        this.initialValue = this.value;
    }

    public async onEditClick() {
        if ( this.isFilloutMode ) {
            return;
        }

        const modal = await this.modals.create({
            component: FormInputOptionsComponent,
            componentProps: {
                node: this.nodeRec,
                editorUUID: this.editorUUID,
            },
        });

        modal.onDidDismiss().then(result => {
            if ( result.data ) {
                this.forceDirty = true;
                this.editorService.triggerSave();

                if (
                    (
                        this.node.type === 'form_input_select'
                        || this.node.type === 'form_input_multiselect'
                    )
                    && this.node.AdditionalData.selectSource === 'database'
                ) {
                    this.loadSelectOptionsFromDatabase();
                }
            }
        });

        const modalState = {
            modal : true,
            desc : 'Form input editor'
        };

        history.pushState(modalState, null);

        await modal.present();
    }
}
