import { AxiosInstance } from "axios";
import { TextBoxFactory } from "../ComponentFactory/TextBoxFactory";
import { MainStateManager } from "../MainStateManager";
import { ElementsOfFormFactory } from "../Page/ElementsOfFormFactory";
import { IMainStateFactory } from "../Types";
import {
    AccountColumn,
    AmountColumn,
    BankColumn,
    BranchColumn,
    CapitalistColumn,
    CarColumn,
    CashColumn,
    CostCenterColumn,
    CountColumn,
    CustomerColumn,
    DateColumn,
    DetailedAccountColumn,
    DriveColumn,
    GridViewColumn,
    GridViewMergCaptionColumn,
    IdColumn,
    NumberColumn,
    NumberOfCheckColumn,
    QTYColumn,
    PersonColumn,
    PurchaseOfficerColumn,
    SaleManagerColumn,
    StakeholderColumn,
    StringColumn,
    VisitorColumn
} from "./Columns";
import { LockUnLockViewBargeFactory } from "./LockUnLockFactory";

export interface IViewBargeAxiosType {
    axios: (path: string) => AxiosInstance;
    controllerPath: string;
    actionGetByIdPath?: string;
    actionGetByLineIdPath?: string;
    controllerLockUnLockPath?: string;
    actionLockPath?: string;
    actionUnLockPath?: string;
}

export class ViewBargeFactory implements IMainStateFactory {
    public getTextBoxFactory = (fieldName: string): TextBoxFactory => {
        const selfFactoryName = 'selfFactory' + fieldName;
        return this.any[selfFactoryName];
    }
    public lastResponse: any;
    public cach: {} = {};
    public forceUpdate = () => { };
    public onDeserializedData?: (data: any) => void;
    public ContextMenuRow?: React.ComponentType<{ headFactory: ViewBargeFactory, row: any }>;

    public axiosInstance?: AxiosInstance;
    public controllerPath?: string;
    public actionGetByIdPath?: string;
    public actionGetByLineIdPath?: string;

    public columns: GridViewColumn[] = [];
    public columnsReverse: GridViewColumn[] = [];

    public mergeCaptionColumns: GridViewMergCaptionColumn[] | null = null;
    public rows: any[] = [];
    public waitForLoad?: boolean;

    public get any(): any {
        return this;
    }
    public elementsOfForm: ElementsOfFormFactory;

    public lockUnLockFactory: LockUnLockViewBargeFactory;

    constructor(
        public mainStateManager: MainStateManager,
        public yearId: number | null,
        public id: number,
        public isFindIdInRows: boolean,
        public axiosData?: IViewBargeAxiosType,
        public hasPagination?: boolean,

    ) {
        this.elementsOfForm = new ElementsOfFormFactory(this);
        if (this.axiosData) {
            this.controllerPath = this.axiosData.controllerPath || "";
            this.actionGetByIdPath = this.axiosData.actionGetByIdPath || 'getById';
            this.actionGetByLineIdPath = this.axiosData.actionGetByLineIdPath || 'getByLineId';
            this.axiosInstance = this.axiosData.axios(this.controllerPath);
        }
        this.lockUnLockFactory = new LockUnLockViewBargeFactory(this, this.axiosData, this.id, this.yearId);
    }

    public selectThisRowById = (_rowId: number) => {
        throw new Error('Method not implemented.');
    }
    public selectThisRowByIndex = (rowIndex: number) => {
        return this.currentRowIndex === rowIndex;
    }
    public showContextMenuForRow = (_rowData: any, _rowIndex: number, _arg2: number, _arg3: number) => {
        throw new Error('Method not implemented.');
    }
    public hideContextMenuForRow = () => {
        throw new Error('Method not implemented.');
    }

    public currentRowIndex = 0;
    public isThisCurrentRow = (rowIndex: number) => {
        return this.currentRowIndex === rowIndex;
    }
    public selectedRowsIds: number[] = [];
    public isSelectedThisRow = (rowId: number) => {
        return this.selectedRowsIds.includes(rowId);
    }

    public selectThisCell = (rowIndex: any, _columnIndex: number): void => {
        this.currentRowIndex = rowIndex;
        this.forceUpdate();
    }
    public refreshList = () => {
        this.loadData();
    }

    private loadData() {
        if (!this.axiosInstance) {
            return;
        }
        this.elementsOfForm.showWaitingFormSpinner();
        const actionPath = this.isFindIdInRows ? this.actionGetByLineIdPath : this.actionGetByIdPath;
        const yearAction = this.yearId && typeof this.yearId === 'number' ? `/${this.yearId}` : '';
        this.axiosInstance.get<{
            data: any;
            isSuccess: Boolean;
            messageRoot: string;
        }>(`${actionPath}/${this.id}${yearAction}`, this.mainStateManager.tokenInfo.headerOfAxios)
            .then(response => {
                const data = response.data;
                if (data === undefined) {
                    this.elementsOfForm.showSomeThingWentWrong();
                }
                if (data.getProp('isSuccess')) {
                    this.deserializeData(data.data);
                } else {
                    this.elementsOfForm.closeWaitingFormSpinner();
                    this.elementsOfForm.showInvalidArgumentMessageBox(data.getProp('messageRoot'));
                }
            })
            .catch(e => {
                this.rows = [];
                this.elementsOfForm.showErrorMessageBox(e);
                this.elementsOfForm.closeWaitingFormSpinner();
            });
    }

    private deserializeData(data: any) {
        this.elementsOfForm.deserializedResponse(data);

        this.rows = data.getProp('lines');

        this.hideAutoHideColumns();

        this.lastResponse = { ...data, lines: undefined };
        delete this.lastResponse.lines;
        if (typeof this.onDeserializedData === 'function') {
            this.onDeserializedData(data);
        }
        this.forceUpdate();
        this.elementsOfForm.closeWaitingFormSpinner();
    }

    private hideAutoHideColumns() {
        const autoHidColumns = this.columns.filter(i => i.autoHideIfEmpty);

        autoHidColumns.forEach(column => {
            column.visible = this.rows.some(row => !column.isCellValueEmpty(row));
        });
    }

    public getWidth(child: any): number {
        const width = child.props.width;
        const level = child.props.level;
        if (typeof width === 'number') {
            return width;
        }
        const setting = (this.mainStateManager as any).Setting;

        if (child.type === AccountColumn) {
            if (level === 1) {
                return setting.structureAccountCoding.levelLen1 * 5;
            } else if (level === 2) {
                return setting.structureAccountCoding.untilLevelLen2 * 5;
            } else if (level === 3) {
                return setting.structureAccountCoding.untilLevelLen3 * 5;
            } else if (level === 4) {
                return setting.structureAccountCoding.untilLevelLen4 * 5;
            } else if (level === 5) {
                return setting.structureAccountCoding.untilLevelLen5 * 5;
            } else if (level === 6) {
                return setting.structureAccountCoding.untilLevelLen6 * 5;
            } else if (level === 7) {
                return setting.structureAccountCoding.untilLevelLen7 * 5;
            } else if (level === 8) {
                return setting.structureAccountCoding.untilLevelLen8 * 5;
            } else if (level === 9) {
                return setting.structureAccountCoding.untilLevelLen9 * 5;
            } else {
                return 100;
            }
        } else if (child.type === DetailedAccountColumn) {

        } else if (child.type === CustomerColumn) {
        } else if (child.type === CostCenterColumn) {
        } else if (child.type === BankColumn) {
        } else if (child.type === BranchColumn) {
        } else if (child.type === CarColumn) {
        } else if (child.type === CashColumn) {
        } else if (child.type === DriveColumn) {
        } else if (child.type === PersonColumn) {
        } else if (child.type === PurchaseOfficerColumn) {
        } else if (child.type === SaleManagerColumn) {
        } else if (child.type === StakeholderColumn) {
        } else if (child.type === CapitalistColumn) {
        } else if (child.type === VisitorColumn) {
        } else if (child.type === StringColumn) {
            return 120;
        } else if (child.type === CountColumn) {
            return 50;
        } else if (child.type === QTYColumn) {
            return 100;
        } else if (child.type === NumberOfCheckColumn) {
            return 50;
        } else if (child.type === DateColumn) {
            return 135;
        } else if (child.type === NumberColumn) {
            return 100;
        } else if (child.type === AmountColumn) {
            return 140;
        } else if (child.type === IdColumn) {
            return 100;
        }
        return 100;
    }
    public close = () => {
        if (this.elementsOfForm.subPageItem) {
            this.elementsOfForm.subPageItem.close();
        }
    }


    public toggelLockUnlock = (fieldName: string) => {
        this.lockUnLockFactory.toggel(fieldName);
    }

    public lock = (fieldName: string) => {
        this.lockUnLockFactory.lock(fieldName);
    }

    public unLock = (fieldName: string) => {
        this.lockUnLockFactory.unLock(fieldName);
    }
}
