import {IFileInputBus} from '../../interfaces/bus/IFileInputBus';
import {TImageObject} from '../../types/TImageObject';
import {IImageInput} from '../../interfaces/components/file-input/IImageInput';

export class ImageInput implements IImageInput {

    protected html:string = `
        <div class="object-field">
            <label class="form-label js-label"></label>
            <div class="input-group">
                <input type="text" class="form-control js-input">
                <div class="input-group-append">
                    <a href="#" class="input-group-text btn-info js-browser-btn">
                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-arrow-down" viewBox="0 0 16 16">
                            <path d="M8.5 6.5a.5.5 0 0 0-1 0v3.793L6.354 9.146a.5.5 0 1 0-.708.708l2 2a.5.5 0 0 0 .708 0l2-2a.5.5 0 0 0-.708-.708L8.5 10.293V6.5z"/>
                            <path d="M14 14V4.5L9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2zM9.5 3A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5v2z"/>
                        </svg>
                    </a>
                </div>
            </div>
            <div class="invalid-feedback js-error-message"></div>
            <div class="prev-container">
                <canvas class="img-prev js-canvas"></canvas>
                <div class="preloader js-preloader">
                    <div class="lds-dual-ring"></div>
                </div>
            </div>
        </div>
    `;

    protected _template:HTMLElement;

    protected label:HTMLElement;

    protected input:HTMLInputElement;

    protected browserBtn:HTMLElement;

    protected errorMessage:HTMLElement;

    protected prevImg:HTMLElement;

    protected preloader:HTMLElement;

    protected data:TImageObject;

    protected bus:IFileInputBus;

    protected formKey:string;

    protected canvasContext:any;

    public setFormKey(key:string)
    {
        this.formKey = key;
    }

    public setBus(bus:IFileInputBus)
    {
        this.bus = bus;
    }

    public constructor()
    {
        let div = document.createElement('div');
        div.innerHTML = this.html.trim();
        this._template = <HTMLElement>div.firstChild;
        this.label = this._template.querySelector('.js-label');
        this.input = this._template.querySelector('.js-input');
        this.browserBtn = this._template.querySelector('.js-browser-btn');
        this.errorMessage = this._template.querySelector('.js-error-message');
        this.preloader = this._template.querySelector('.js-preloader');
        this.prevImg = this._template.querySelector('.js-canvas');
        this.canvasContext = (<any>this.prevImg).getContext('2d');
    }

    public get template():HTMLElement
    {
        return this._template;
    }

    public loadData(data:TImageObject)
    {
        this.data = data;
        this.label.innerText = data.description;
        this.input.value = data.value;
    }

    public showErrors()
    {
        if(this.data.errors.length){
            this.input.classList.add('is-invalid');
            this.errorMessage.innerText = this.data.errors[0];
            this.errorMessage.style.display = 'block';
        }
    }

    public clearErrors()
    {
        this.input.classList.remove('is-invalid');
        this.errorMessage.innerText = '';
        this.errorMessage.style.display = 'none';
    }

    public serialize():TImageObject
    {
        return this.data;
    }

    public eventsListen()
    {
        let w = this._template.clientWidth || 300;
        this.prevImg.setAttribute('width', w.toString());
        if(this.data.ar){
            let h = w / this.data.ar;
            this.prevImg.setAttribute('height', h.toString());
        }else{
            this.prevImg.setAttribute('height', w.toString());
        }
        if(this.data.value){
            this.previewImg(this.data.value);
        }
        
        this.input.oninput = (e:Event)=>{
            let val = this.input.value;
            this.data.value = val;
            this.previewImg(val);
        };
        this.browserBtn.onclick = (e:Event)=>{
            e.preventDefault();
            this.bus.execBrowserModal()
                .then((fileName:string)=>{
                    this.data.value = fileName;
                    this.input.value = fileName;
                    this.previewImg(fileName);
                });
        };
    }

    protected previewImg(fileName:string)
    {
        let canvasWidth = this.prevImg.getAttribute('width');
        let canvasHeight = this.prevImg.getAttribute('height');
        let img = new Image();
        this.preloader.style.display = 'none';
        img.onload = ()=>{
            this.canvasContext.clearRect(0, 0, canvasWidth, canvasHeight);
            let imgH = img.height;
            let imgW = img.width;
            if(this.data.ar == 0){
                this.canvasContext.drawImage(img, 0, 0, imgW, imgH, 0, 0, canvasWidth, canvasHeight);
                this.preloader.style.display = 'none';
                return;
            }
            let dx = 0; let dy = 0;
            if(imgW / imgH > this.data.ar){
                // изображение вытянуто по ширине
                let scale = imgH / +canvasHeight;
                dx = (imgW - +canvasWidth * scale) / 2;
            }else{
                // изображение вытянуто по высоте
                let scale = imgW / +canvasWidth;
                dy = (imgH - +canvasHeight * scale) / 2;
            }
            this.canvasContext.drawImage(img, dx, dy, imgW - 2*dx, imgH - 2*dy, 0, 0, canvasWidth, canvasHeight);
            this.preloader.style.display = 'none';
        }
        img.src = this.data.path + fileName;
    }

}