import { Component, ContentChild, Inject, Input, OnChanges, TemplateRef, ViewChild } from '@angular/core';
import { HypermediaField, HypermediaFieldOption, HypermediaValue } from 'first-npm-package-nicule/core';
import { PARENT_FORM } from './parent-form';
import { AfterFieldDirective, BeforeFieldDirective, FieldDirective } from '../directives/form';

@Component({
    selector: 'hm-form-field',
    template: `
    <ng-template #output>
        <ng-container *ngTemplateOutlet="beforeField?.templateRef"></ng-container>
        <ng-container *ngIf="fieldReplace && fieldReplace.templateRef; else defaultField">
            <ng-container *ngTemplateOutlet="fieldReplace.templateRef"></ng-container>
        </ng-container>
        <ng-template #defaultField>
            <input *hmInputOf="baseField; settings: fieldInputs"/>
        </ng-template>
        <ng-container *ngTemplateOutlet="afterField?.templateRef"></ng-container>
    </ng-template>
`
})
export class FormFieldComponent implements OnChanges {
    @Input() named: string;

    @ViewChild('output', { read: TemplateRef, static: false }) output: TemplateRef<any>;

    @ContentChild(BeforeFieldDirective, { static: false }) beforeField: BeforeFieldDirective;
    @ContentChild(AfterFieldDirective, { static: false }) afterField: AfterFieldDirective;
    @ContentChild(FieldDirective, { static: false }) fieldReplace: FieldDirective;

    /* HypermediaField */
    @Input() name: string;
    @Input() type: string;
    @Input() value?: HypermediaValue;
    @Input() options?: Array<HypermediaFieldOption>;
    @Input() required?: boolean;
    @Input() maxlength?: number;
    @Input() minlength?: number;
    @Input() pattern?: string;
    @Input() max?: number;
    @Input() min?: number;
    @Input() disabled?: boolean;
    @Input() readonly?: boolean;
    /* HypermediaField */

    @Input() errors: any;

    _fieldInputs: any;
    get fieldInputs(): any {
        return {
            ...this._fieldInputs,
            disabled: this.form.disabled,
            mode: this.form.mode,
            errors: this.errors
        };
    }

    // Temporary
    @Input() set fieldInputs(newFieldInputs: any) {
        this._fieldInputs = newFieldInputs;
    }

    baseField: HypermediaField;

    constructor(@Inject(PARENT_FORM) private form) { }

    ngOnChanges(): void {
        // Copy all the inputs from this to the field
        const {
            named,
            output,
            fields,
            form,
            _fieldInputs,
            fieldInputs,
            disabled,
            fieldReplace,
            afterField,
            beforeField,
            baseField,
            field,
            formOwner, ...inputs } = this as any;
        const imutableBaseField = this.named && this.form.getField(this.named);

        if (!this.form || !this.form.action) {
            return;
        }

        if (!imutableBaseField && this.named) {
            console.warn(`Field named ${this.named} was not found within the form, make sure the field you try to override exists! Action name: ${this.form.action.name}`);

            return;
        }

        this.baseField = {
            ...imutableBaseField,
            ...inputs,
            isDisabled: this.disabled,
            name: inputs.name || this.named
        };
    }
}
