import { Dropdown, Grid, OptionBase, createCheckbox, createElement, createIcon } from "../ui";

export default class AssetSelector extends OptionBase {
    _var = {
        /**
         * @private
         * @type {HTMLElement}
         */
        container: null,
        el: {
            /**
             * @private
             * @type {HTMLInputElement}
             */
            inputSearch: null,
            /**
             * @private
             * @type {HTMLLabelElement}
             */
            checkHidden: null,
            /**
             * @private
             * @type {Dropdown}
             */
            dropAssetGroup: null,
            /**
             * @private
             * @type {Dropdown}
             */
            dropJobsite: null,
            /**
             * @private
             * @type {Dropdown}
             */
            dropJobsiteCode: null,
            /**
             * @private
             * @type {Grid}
             */
            grid: null
        }
    }

    onSelected;

    constructor(opt = {
        assetFullcontrol: false,
        ignoreHidden: false,
        /**
         * @private
         * @type {(flag: boolean) => void}
         */
        loading: null,
        /**
         * @private
         * @type {() => void}
         */
        close: null,
        /**
         * @private
         * @type {(hidden: boolean, search?: string, groups?: string[], jobsites?: number[], codes?: string[]) => Promise<any[]>}
         */
        requestAssets: null,
        /**
         * @private
         * @type {() => Promise<any>}
         */
        requestAddAsset: null,
        /**
         * @private
         * @type {() => Promise<{AssetGroups: any[], Codes: any[], Jobsites: any[]}>}
         */
        requestAssetParams: null,
        dataSource: {
            AssetGroups: [],
            Codes: [],
            Jobsites: []
        }
    }) {
        super(opt);
    }

    get title() { return this.r('FLTL_02645', 'Select Asset') }

    get currentAsset() { return this._var.el.grid.currentItem }

    loading(flag) {
        if (typeof this._option.loading === 'function') {
            this._option.loading(flag);
        }
    }

    refresh() {
        const requestAssets = this._option.requestAssets;
        if (typeof requestAssets !== 'function') {
            return;
        }
        const el = this._var.el;
        this.loading(true);
        requestAssets(
            el.checkHidden.querySelector('input[type="checkbox"]')?.checked,
            el.inputSearch.value,
            el.dropAssetGroup.selected?.Key,
            el.dropJobsite.selected?.ID,
            el.dropJobsiteCode.selected?.value
        ).then(data => {
            el.grid.source = data;
        }).finally(() => this.loading(false));
    }

    select(item) {
        if (typeof this.onSelected !== 'function') {
            return false;
        }
        if (item == null) {
            item = this._var.el.grid.currentItem;
        }
        if (item == null) {
            return false;
        }
        this.onSelected(item);
    }

    create() {
        const option = this._option;
        const tabIndex = Math.max.apply(null, [...document.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0)) + 3;
        const inputSearch = createElement('input', input => {
            input.type = 'text';
            input.placeholder = this.r('FLTL_02606', 'Search');
            input.tabIndex = tabIndex + 2;
            input.className = 'ui-input';
            input.addEventListener('keypress', e => {
                if (e.key === 'Enter') {
                    this.refresh();
                }
            })
        });
        const checkHidden = createCheckbox({
            tabIndex: tabIndex + 3,
            label: this.r('FLTL_02768', 'Show Hidden'),
            onchange: () => this.refresh()
        });
        if (option.ignoreHidden) {
            checkHidden.style.display = 'none';
        }
        const dropAssetGroup = new Dropdown({
            tabIndex: tabIndex + 4,
            search: true,
            valueKey: 'Key',
            textKey: 'Value'
        });
        dropAssetGroup.onSelected = () => this.refresh();
        const dropJobsite = new Dropdown({
            tabIndex: tabIndex + 5,
            search: true,
            valueKey: 'ID',
            textKey: 'Name'
        });
        dropJobsite.onSelected = () => this.refresh();
        const dropJobsiteCode = new Dropdown({
            tabIndex: tabIndex + 6,
            search: true
        });
        dropJobsiteCode.onSelected = () => this.refresh();
        const gridContent = createElement('div', div => {
            div.className = 'popup-selector-content';
            div.style.height = '400px';
        });
        const grid = new Grid(gridContent, this.r);
        grid.columns = [
            { key: 'VIN', caption: this.r('FLTL_03260', 'VIN'), width: 170 },
            { key: 'DisplayName', caption: this.r('FLTL_01966', 'Name'), width: 190 },
            { key: 'MakeName', caption: this.r('FLTL_01832', 'Make'), width: 110, allowFilter: true },
            { key: 'ModelName', caption: this.r('FLTL_01933', 'Model'), width: 110, allowFilter: true },
            { key: 'TypeName', caption: this.r('FLTL_03112', 'Type'), width: 110, allowFilter: true },
            { key: 'AcquisitionType', caption: this.r('FLTL_00072', 'Acquisition Type'), width: 130, allowFilter: true },
            { key: 'AssetGroups', caption: this.r('FLTL_00318', 'Asset Group'), width: 150 },
            { key: 'Jobsites', caption: this.r('FLTL_01666', 'Jobsite'), width: 180, filter: it => it.Jobsites?.map(s => s.Key) }
        ];
        grid.onRowDblClicked = index => {
            const item = grid.source[index];
            this.select(item);
            if (typeof this._option.close === 'function') {
                this._option.close();
            }
        };
        grid.init();
        grid.element.tabIndex = tabIndex + 7;
        this._var.el = {
            inputSearch,
            checkHidden,
            dropAssetGroup,
            dropJobsite,
            dropJobsiteCode,
            grid
        }

        const container = createElement('div', 'popup-selector',
            createElement('div', 'popup-selector-header',
                createElement('img', img => img.src = '../img/modules/devices.png'),
                createElement('h3', h3 => h3.innerText = this.title),
                option.assetFullcontrol ? createElement('button', button => {
                    button.className = 'ui-popup-button';
                    button.tabIndex = tabIndex + 1;
                    button.innerText = this.r('FLTL_00091', 'Add Asset');
                    button.addEventListener('click', async () => {
                        if (typeof option.requestAddAsset === 'function') {
                            this.loading(true);
                            const asset = await option.requestAddAsset();
                            this.loading(false);
                            if (asset != null) {
                                this.select(asset);
                                if (typeof this._option.close === 'function') {
                                    this._option.close();
                                }
                            }
                        }
                    });
                }) : ''
            ),
            createElement('div', 'popup-selector-function',
                createElement('div', 'search-box',
                    inputSearch,
                    createElement('span', span => {
                        span.addEventListener('click', () => this.refresh());
                    },
                        createIcon('fa-light', 'search')
                    )
                ),
                checkHidden,
                createElement('span', span => span.innerText = this.r('FLTL_00318', 'Asset Group')),
                dropAssetGroup.create(),
                createElement('span', span => span.innerText = this.r('FLTL_01666', 'Jobsite')),
                dropJobsite.create(),
                createElement('span', span => span.innerText = this.r('FLTL_01669', 'Jobsite Code')),
                dropJobsiteCode.create()
            ),
            gridContent
        );
        this._var.container = container;
        return container;
    }

    async init() {
        const option = this._option;
        if (option.dataSource == null) {
            if (typeof option.requestAssetParams === 'function') {
                this.loading(true);
                const data = await option.requestAssetParams();
                option.dataSource = data;
            } else {
                option.dataSource = { AssetGroups: [], Jobsites: [], Codes: [] };
            }
        }
        this._var.el.dropAssetGroup.source = [{ Key: '-1', Value: '' }, ...option.dataSource.AssetGroups];
        this._var.el.dropJobsite.source = [{ ID: '-1', Name: '' }, ...option.dataSource.Jobsites];
        this._var.el.dropJobsiteCode.source = [{ value: '-1', text: '' }, ...option.dataSource.Codes.map(c => ({ value: c, text: c }))];
        this.refresh();
    }
}