import {Component, Input, OnInit} from '@angular/core';
import {EditorService} from '../../../../service/editor.service';
import {ModalController} from '@ionic/angular';
import HostRecord from '../../../../structures/HostRecord';
import {debug} from '../../../../utility';
import {DbApiService} from '../../../../service/db-api.service';
import {Database, DatabaseColumn} from '../../../../structures/db-api';
import {NodeTypeIcons} from '../../../../structures/node-types';

@Component({
    selector: 'noded-node-form-input-options',
    template: `
        <ion-header>
            <ion-toolbar>
                <ion-title>Edit Form Input</ion-title>
                <ion-buttons slot="end">
                    <ion-button (click)="dismissModal(true)">
                        <ion-icon name="save"></ion-icon>
                    </ion-button>
                    <ion-button (click)="dismissModal(false)">
                        <ion-icon name="close"></ion-icon>
                    </ion-button>
                </ion-buttons>
            </ion-toolbar>
        </ion-header>

        <ion-content class="ion-padding">
            <ion-grid>
                <ion-row>
                    <ion-col size="12">
                        <ion-item>
                            <ion-label [position]="'floating'">Label Text</ion-label>
                            <ion-input [(ngModel)]="label"></ion-input>
                        </ion-item>
                    </ion-col>
                </ion-row>
                <ion-row>
                    <ion-col size="12">
                        <ion-item>
                            <ion-label [position]="'floating'">Placeholder Text</ion-label>
                            <ion-input [(ngModel)]="placeholder"></ion-input>
                        </ion-item>
                    </ion-col>
                </ion-row>
                <ion-row>
                    <ion-col size="12">
                        <ion-item>
                            <ion-checkbox slot="start" [(ngModel)]="required">
                            </ion-checkbox>
                            Required
                        </ion-item>
                    </ion-col>
                </ion-row>
                <ion-row *ngIf="node.type === 'form_input_select' || node.type === 'form_input_multiselect'">
                    <ion-col size="12" [title]="'Defines where the options for the select field should come from'">
                        <ion-item>
                            <ion-label [position]="'floating'">Select Options Source</ion-label>
                            <ion-select
                                    [(ngModel)]="selectSource"
                                    style="width: 100%;"
                            >
                                <ion-select-option value="local">Static Options</ion-select-option>
                                <ion-select-option value="database">Database Values</ion-select-option>
                            </ion-select>
                        </ion-item>
                    </ion-col>
                </ion-row>
                <ion-row
                        *ngIf="
                        (node.type === 'form_input_select' || node.type === 'form_input_multiselect')
                        && this.selectSource === 'database'"
                >
                    <ion-col size="12">
                        <ion-item>
                            <ion-label position="floating">Source Database</ion-label>
                            <ionic-selectable
                                    [items]="databases"
                                    itemTextField="name"
                                    itemValueField="uuid"
                                    [canSearch]="true"
                                    [title]="'Select a source database'"
                                    [(ngModel)]="selectedDatabase"
                                    (onChange)="onSelectDatabaseChange()"
                            >
                                <ng-template ionicSelectableItemTemplate let-port="item" let-isPortSelected="itemIsSelected">
                                    <div><i [ngClass]="typeIcons.db" style="margin-right: 15px;"></i>{{ port.name }}</div>
                                </ng-template>
                            </ionic-selectable>
                        </ion-item>
                    </ion-col>
                </ion-row>
                <ion-row
                        *ngIf="
                        (node.type === 'form_input_select' || node.type === 'form_input_multiselect')
                        && this.selectSource === 'database' && this.selectedDatabase"
                >
                    <ion-col size="6">
                        <ion-item>
                            <ion-label position="floating">Display Column</ion-label>
                            <ionic-selectable
                                    [items]="selectedDatabaseColumns"
                                    itemTextField="name"
                                    itemValueField="uuid"
                                    [canSearch]="true"
                                    [title]="'Select the column to be used as the display value'"
                                    [(ngModel)]="selectDatabaseDisplayColumn"
                            ></ionic-selectable>
                        </ion-item>
                    </ion-col>
                    <ion-col size="6">
                        <ion-item>
                            <ion-label position="floating">Value Column</ion-label>
                            <ionic-selectable
                                    [items]="selectedDatabaseColumns"
                                    itemTextField="name"
                                    itemValueField="uuid"
                                    [canSearch]="true"
                                    [title]="'Select the column to be used as the record value'"
                                    [(ngModel)]="selectDatabaseValueColumn"
                            ></ionic-selectable>
                        </ion-item>
                    </ion-col>
                </ion-row>
                <ion-row
                    *ngIf="
                    (node.type === 'form_input_select' || node.type === 'form_input_multiselect')
                    && this.selectSource === 'local'"
                >
                    <ion-header style="display: flex; padding-top: 20px;">
                        <h5 style="flex: 1;">Options</h5>
                        <button [title]="'Add new option'" (click)="onAddSelectOption()">
                            <i class="fa fa-plus"></i>
                        </button>
                    </ion-header>
                    <ion-grid>
                        <ion-row *ngFor="let option of selectStaticOptions">
                            <ion-col size="5">
                                <ion-item>
                                    <ion-label position="floating">Display</ion-label>
                                    <ion-input [(ngModel)]="option.display"></ion-input>
                                </ion-item>
                            </ion-col>
                            <ion-col size="5">
                                <ion-item>
                                    <ion-label position="floating">Value</ion-label>
                                    <ion-input [(ngModel)]="option.value"></ion-input>
                                </ion-item>
                            </ion-col>
                            <ion-col size="2">
                                <button [title]="'Remove this option'" style="height: 100px; padding: 10px; color: red;" (click)="onRemoveSelectOption(option)">
                                    <i class="fa fa-trash"></i>
                                </button>
                            </ion-col>
                        </ion-row>
                    </ion-grid>
                </ion-row>
                <ion-row *ngIf="node.type === 'form_input_password' || node.type === 'form_input_text'">
                    <ion-col size="6">
                        <ion-item>
                            <ion-label [position]="'floating'">Min Length</ion-label>
                            <ion-input type="'number'" [(ngModel)]="minLength"></ion-input>
                        </ion-item>
                    </ion-col>
                    <ion-col size="6">
                        <ion-item>
                            <ion-label [position]="'floating'">Max Length</ion-label>
                            <ion-input type="'number'" [(ngModel)]="maxLength"></ion-input>
                        </ion-item>
                    </ion-col>
                </ion-row>
                <ion-row *ngIf="node.type === 'form_input_number'">
                    <ion-col size="6">
                        <ion-item>
                            <ion-label [position]="'floating'">Min</ion-label>
                            <ion-input type="'number'" [(ngModel)]="min"></ion-input>
                        </ion-item>
                    </ion-col>
                    <ion-col size="6">
                        <ion-item>
                            <ion-label [position]="'floating'">Max</ion-label>
                            <ion-input type="'number'" [(ngModel)]="max"></ion-input>
                        </ion-item>
                    </ion-col>
                </ion-row>
            </ion-grid>
        </ion-content>
    `,
})
export class FormInputOptionsComponent implements OnInit {
    @Input() node: HostRecord;
    @Input() editorUUID: string;

    public typeIcons = NodeTypeIcons;

    public label = '';
    public placeholder = '';
    public required = false;

    public minLength?: number;
    public maxLength?: number;

    public min?: number;
    public max?: number;

    public selectSource?: 'local'|'database';
    public selectDatabaseDisplayColumn?: DatabaseColumn;
    public selectDatabaseValueColumn?: DatabaseColumn;
    public selectStaticOptions: { display: string, value: string }[] = [];

    public databases: Database[] = [];
    public selectedDatabase?: Database;
    public selectedDatabaseColumns: DatabaseColumn[] = [];

    constructor(
        public editorService: EditorService,
        public readonly dbApi: DbApiService,
        public readonly modal: ModalController,
    ) { }

    async ngOnInit() {
        debug('Form input options', this);
        this.editorService = this.editorService.getEditor(this.editorUUID);

        this.label = this.node.AdditionalData.label;
        this.placeholder = this.node.AdditionalData.placeholder;
        this.required = this.node.AdditionalData.required;

        if ( this.node.type === 'form_input_password' || this.node.type === 'form_input_text' ) {
            this.minLength = this.node.AdditionalData.minLength;
            this.maxLength = this.node.AdditionalData.maxLength;
        }

        if ( this.node.type === 'form_input_number' ) {
            this.min = this.node.AdditionalData.min;
            this.max = this.node.AdditionalData.max;
        }

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

            this.databases = await this.dbApi.getDatabases();

            if ( this.selectSource === 'database' ) {
                this.selectedDatabase = this.databases.find(x => x.uuid === this.node.AdditionalData.selectSourceDatabaseId);
                await this.onSelectDatabaseChange();

                this.selectDatabaseValueColumn = this.selectedDatabaseColumns.find(x => {
                    return x.field === this.node.AdditionalData.selectDatabaseValueColumnId;
                });

                this.selectDatabaseDisplayColumn = this.selectedDatabaseColumns.find(x => {
                    return x.field === this.node.AdditionalData.selectDatabaseDisplayColumnId;
                });
            } else if ( this.selectSource === 'local' ) {
                this.selectStaticOptions = this.node.AdditionalData.selectStaticOptions || [];
            }
        }
    }

    dismissModal(success = true) {
        if ( success ) {
            this.node.AdditionalData.label = this.label;
            this.node.AdditionalData.placeholder = this.placeholder;
            this.node.AdditionalData.required = !!this.required;
        }

        if ( this.node.type === 'form_input_password' || this.node.type === 'form_input_text' ) {
            this.node.AdditionalData.minLength = this.minLength;
            this.node.AdditionalData.maxLength = this.maxLength;
        }

        if ( this.node.type === 'form_input_number' ) {
            this.node.AdditionalData.min = this.min;
            this.node.AdditionalData.max = this.max;
        }

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

            if ( this.selectSource === 'database' ) {
                this.node.AdditionalData.selectSourceDatabaseId = this.selectedDatabase?.uuid;
                this.node.AdditionalData.selectDatabaseValueColumnId = this.selectDatabaseValueColumn?.field;
                this.node.AdditionalData.selectDatabaseDisplayColumnId = this.selectDatabaseDisplayColumn?.field;
            } else if ( this.selectSource === 'local' ) {
                this.node.AdditionalData.selectStaticOptions = this.selectStaticOptions;
            }
        }

        this.modal.dismiss(success);
    }

    async onSelectDatabaseChange() {
        if ( this.selectedDatabase ) {
            this.selectedDatabaseColumns = await this.selectedDatabase.columns();
        } else {
            this.selectedDatabaseColumns = [];
        }

        this.selectDatabaseDisplayColumn = undefined;
        this.selectDatabaseValueColumn = undefined;
    }

    onAddSelectOption() {
        this.selectStaticOptions.push({
            display: '',
            value: '',
        });
    }

    onRemoveSelectOption(option: any) {
        this.selectStaticOptions = this.selectStaticOptions.filter(x => x !== option);
    }
}
