import {
    AUTOSNAB_DEPARTMENT_ASSET_ID,
    AUTOSNAB_ORDER_ASSET_ID,
    AUTOSNAB_PROJECT_ID,
} from '../../constants';
import {Injectable} from "@nestjs/common";
import {AssetSelectorContext, AssetSelectorService} from "../asset-selector.service";
import {InjectRepository} from "@nestjs/typeorm";
import {AssetEntity} from "../../entities/asset.entity";
import {Repository} from "typeorm";
import {UserEntity} from "../../entities/user.entity";
import {AssetRefEntity} from "../../entities/asset-ref.entity";
import {ProjectActionEntity} from "../../entities/project-action.entity";
import {AssetUserRightEntity} from "../../entities/asset-user-right.entity";
import {AssetForeignBlockEntity} from "../../entities/asset-foreign-block.entity";
import {RefService} from "../ref.service";
import {ComputingService} from "../computing.service";
import {AssetService} from "../asset.service";
import {AssetCreateDTO} from "../dto/asset-change-dto";
import {AssetBlock, getAssetAllBlocksTx} from "../block-helpers";
import {AssetChanger} from "../logic/AssetChanger";
import {castAssetPropValueToString} from "../logic/Props";

@Injectable()
export class IzhAutosnabService {
    constructor(
        private readonly assetSelectorService: AssetSelectorService,
        @InjectRepository(AssetEntity)
        private readonly assetRepo: Repository<AssetEntity>,
        @InjectRepository(UserEntity)
        private readonly userRepo: Repository<UserEntity>,
        @InjectRepository(AssetRefEntity)
        private readonly refRepo: Repository<AssetRefEntity>,
        @InjectRepository(ProjectActionEntity)
        private readonly projectActionRepo: Repository<ProjectActionEntity>,
        @InjectRepository(AssetUserRightEntity)
        private readonly assetUserRightEntity: Repository<AssetUserRightEntity>,
        @InjectRepository(AssetForeignBlockEntity)
        private readonly assetForeignBlockIntity: Repository<AssetForeignBlockEntity>,
        private readonly refService: RefService,
        private readonly computingService: ComputingService,
    ) {}

    public async assetPostUpdate(
        assetService: AssetService,
        change: AssetCreateDTO,
        asset_ids: string[],
        context: AssetSelectorContext,
    ) {
        await this._orderChangeCompute(assetService, change, asset_ids, context);
        await this._departmentChangeCompute(context, asset_ids)
    }

    private async _orderChangeCompute(
        assetService: AssetService,
        change: AssetCreateDTO,
        asset_ids: string[],
        context: AssetSelectorContext,
    ) {
        if (context.projectId !== AUTOSNAB_PROJECT_ID) {
            return;
        }

        const order_assets = await this.assetRepo
            .createQueryBuilder('a')
            .where('a.id = ANY(:asset_ids)', {
                asset_ids,
            })
            .getMany();
        if (order_assets.length === 0) {
            return;
        }

        for (const order_asset of order_assets) {
            const blocks = await getAssetAllBlocksTx(
                this.assetRepo.manager,
                [order_asset.id],
                context,
            );
            const blocks_map = new Map<string, AssetBlock>();
            for (const block of blocks) {
                blocks_map.set(block.name, block);
            }

            const info_block = blocks_map.get('info');

            let status: string = ""
            let additional_status: any
            let additional_comment: string = ""

            if(info_block) {
                status = castAssetPropValueToString(info_block.props['\\статус']);
                additional_status = info_block.props['\\допстатус'];
                additional_comment = castAssetPropValueToString(info_block.props['\\комментарий']);

                if(status !== 'В работе') {
                    additional_status = ""
                    additional_comment = ""
                }
            }

            const current_h = new Date().getHours()
            const current_m = new Date().getMinutes()

            const current_day = new Date().toLocaleDateString()
            const title = `Заявка от ${current_h}:${current_m} ${current_day}`;

            const asset_changer = await AssetChanger.ChangeAssets(
                {
                    ...context,
                    tx: this.assetRepo.manager,
                },
                {
                    id: order_asset.id,
                    issystem: false,
                    typeids: AUTOSNAB_ORDER_ASSET_ID
                },
                {
                    main: {
                        title
                    },
                    props: {
                        'info||props': {
                            '\\допстатус': additional_status,
                            '\\комментарий': additional_comment
                        }
                    }
                },
            );

            await asset_changer.commit();
        }
    }

    private async _departmentChangeCompute(
        context: AssetSelectorContext,
        asset_ids: string[]
    ) {
        if (context.projectId !== AUTOSNAB_PROJECT_ID) {
            return;
        }

        const departments_assets = await this.assetRepo
            .createQueryBuilder('a')
            .where('a.id = ANY(:asset_ids)', {
                asset_ids,
            })
            .andWhere(`parent_ids[1] = :order_id`, {
                order_id: AUTOSNAB_DEPARTMENT_ASSET_ID,
            })
            .getMany();
        if (departments_assets.length === 0) {
            return;
        }


        for (const department_asset of departments_assets) {
            const blocks = await getAssetAllBlocksTx(
                this.assetRepo.manager,
                [department_asset.id],
                context,
            );


            const blocks_map = new Map<string, AssetBlock>();
            for (const block of blocks) {
                blocks_map.set(block.name, block);
            }
            const info_block = blocks_map.get('info');
            if (!info_block) continue;


            const dep_title_prop: string = castAssetPropValueToString(
                info_block.props['\\наименование'],
            );
            const title: string = dep_title_prop ? dep_title_prop : 'Без наименования';



            const asset_changer = await AssetChanger.ChangeAssets(
                {
                    ...context,
                    tx: this.assetRepo.manager,
                },
                {
                    id: department_asset.id,
                    issystem: false,
                },
                {
                    main: {
                        title
                    }
                },
            );

            await asset_changer.commit();
        }


        await this.computingService.runComputeForAssets(
            context.projectId,
            asset_ids,
        );
    }
}