
package com.tmerclub.cloud.product.controller.supplier;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.tmerclub.cloud.api.auth.constant.SysTypeEnum;
import com.tmerclub.cloud.api.multishop.bo.EsShopDetailBO;
import com.tmerclub.cloud.api.multishop.constant.ShopStatus;
import com.tmerclub.cloud.api.multishop.feign.ShopDetailFeignClient;
import com.tmerclub.cloud.api.platform.dto.OfflineHandleEventDTO;
import com.tmerclub.cloud.api.platform.feign.ConfigFeignClient;
import com.tmerclub.cloud.api.platform.vo.OfflineHandleEventVO;
import com.tmerclub.cloud.api.product.util.ProductLangUtil;
import com.tmerclub.cloud.api.supplier.bo.SupplierDetailBO;
import com.tmerclub.cloud.api.supplier.feign.SupplierDetailFeignClient;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.constant.StatusEnum;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.product.constant.IsSynUpdate;
import com.tmerclub.cloud.common.product.constant.SpuStatus;
import com.tmerclub.cloud.common.product.constant.SpuType;
import com.tmerclub.cloud.common.product.constant.SupplierSpuType;
import com.tmerclub.cloud.common.product.dto.SpuDTO;
import com.tmerclub.cloud.common.product.vo.CategoryVO;
import com.tmerclub.cloud.common.product.vo.SkuVO;
import com.tmerclub.cloud.common.product.vo.SpuAttrValueVO;
import com.tmerclub.cloud.common.product.vo.SpuVO;
import com.tmerclub.cloud.common.response.ResponseEnum;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.common.util.ExcelUtil;
import com.tmerclub.cloud.common.util.Json;
import com.tmerclub.cloud.product.dto.SpuPageSearchDTO;
import com.tmerclub.cloud.product.listener.SupplierProdExcelListener;
import com.tmerclub.cloud.product.service.*;
import com.tmerclub.cloud.common.util.SheetUtil;
import com.tmerclub.cloud.product.service.*;
import com.tmerclub.cloud.product.vo.CategoryShopVO;
import com.tmerclub.cloud.product.vo.SpuExcelVO;
import com.tmerclub.cloud.product.vo.SupplierProdExcelVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * spu信息
 *
 * @author tmerclub
 * @date 2020-10-28 15:27:24
 */
@RestController("supplierSpuController")
@RequestMapping("/s/spu")
@Tag(name = "supplier-spu信息")
public class SpuController {

    @Autowired
    private SpuService spuService;
    @Autowired
    private SkuComboService skuComboService;
    @Autowired
    private SpuExcelService spuExcelService;
    @Autowired
    private SkuService skuService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private AttrService attrService;
    @Autowired
    private BrandService brandService;
    @DubboReference
    private ShopDetailFeignClient shopDetailFeignClient;
    @DubboReference
    private SupplierDetailFeignClient supplierDetailFeignClient;
    @Autowired
    private SpuAttrValueService spuAttrValueService;
    @Autowired
    private CategoryShopService categoryShopService;
    @Autowired
    private SpuSupplierChangeLogService spuSupplierChangeLogService;
    @DubboReference
    private ConfigFeignClient configFeignClient;
    @Autowired
    private ShopCartService shopCartService;


    @GetMapping
    @Operation(summary = "获取spu信息", description = "根据spuId获取spu信息")
    public ServerResponseEntity<SpuVO> getBySpuId(@RequestParam Long spuId) {
        // 获取spu信息
        SpuVO spuVO = spuService.getBySpuId(spuId);
        if (!Objects.equals(spuVO.getSupplierId(), AuthUserContext.get().getTenantId()) && !Objects.equals(Constant.PLATFORM_SHOP_ID, AuthUserContext.get().getTenantId())) {
            return ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED);
        }
        ProductLangUtil.spu(spuVO);
        ProductLangUtil.spuDetail(spuVO);
        List<SpuAttrValueVO> spuAttrsBySpuId = spuAttrValueService.getSpuAttrsBySpuId(spuId);
        spuVO.setSpuAttrValues(spuAttrsBySpuId);
        // 物流模板
        SpuVO.DeliveryModeVO deliveryModeVO = Json.parseObject(spuVO.getDeliveryMode(), SpuVO.DeliveryModeVO.class);
        spuVO.setDeliveryModeVO(deliveryModeVO);
        // 品牌信息
        spuVO.setBrand(brandService.getByBrandId(spuVO.getBrandId()));
        // sku信息
        spuVO.setSkus(skuService.listSkuAllInfoBySpuId(spuId, spuVO, false));
        spuService.loadSpuAttrs(spuVO);

        // 插入商品库存和销量
        int totalStock = 0;
        int saleNum = 0;
        for (SkuVO skus : spuVO.getSkus()) {
            totalStock += Objects.isNull(skus.getStock()) ? 0 : skus.getStock();
            saleNum += Objects.isNull(skus.getSaleNum()) ? 0 : skus.getSaleNum();
        }
        spuVO.setTotalStock(totalStock);
        spuVO.setSaleNum(saleNum);
        // 平台分类、供应商分类信息
        spuVO.setCategory(categoryService.getInfo(spuVO.getCategoryId()));
        ProductLangUtil.category(spuVO.getCategory());
        if (Objects.nonNull(spuVO.getSupplierCategoryId()) && !Objects.equals(spuVO.getSupplierCategoryId(), Constant.DEFAULT_ID)) {
            spuVO.setSupplierCategory(categoryService.getInfo(spuVO.getSupplierCategoryId()));
            ProductLangUtil.category(spuVO.getSupplierCategory());
        }
        return ServerResponseEntity.success(spuVO);
    }


    @PostMapping
    @Operation(summary = "保存spu信息", description = "保存spu信息")
    public ServerResponseEntity<Long> save(@Valid @RequestBody SpuDTO spuDTO) {
        spuDTO.setStatus(StatusEnum.ENABLE.value());
        spuDTO.setSpuType(SpuType.NORMAL.value());
        spuDTO.setSupplierSpuType(SupplierSpuType.YES.value());
//        spuDTO.setSpuMold(0);
        spuService.save(spuDTO);
        return ServerResponseEntity.success(spuDTO.getSpuId());
    }

    @PutMapping
    @Operation(summary = "更新spu信息", description = "更新spu信息")
    public ServerResponseEntity<Void> update(@Valid @RequestBody SpuDTO spuDTO) {
        SpuVO spuDb = spuService.getBySpuId(spuDTO.getSpuId());
        if (!Objects.equals(spuDb.getSupplierId(), AuthUserContext.get().getTenantId())) {
            return ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED);
        }
//        spuDTO.setSpuMold(0);
        spuService.update(spuDTO);
        //  清除购物车数量缓存
        shopCartService.removeShopCartItemCacheBySupplierSpuIds(Collections.singletonList(spuDTO.getSpuId()));
        return ServerResponseEntity.success();
    }


    @DeleteMapping
    @Operation(summary = "删除spu信息", description = "根据spu信息id删除spu信息")
    public ServerResponseEntity<Void> delete(@RequestParam Long spuId) {
        SpuVO spuDb = spuService.getBySpuId(spuId);
        Long supplierId = AuthUserContext.get().getTenantId();
        if (!Objects.equals(spuDb.getSupplierId(), supplierId) && !Objects.equals(supplierId, Constant.PLATFORM_SHOP_ID)) {
            return ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED);
        }
        spuService.deleteById(spuId);
        //  清除购物车数量缓存
        shopCartService.removeShopCartItemCacheBySupplierSpuIds(Collections.singletonList(spuId));
        return ServerResponseEntity.success();
    }

    @DeleteMapping("/batch")
    @Operation(summary = "批量删除spu信息", description = "根据spu信息id删除spu信息")
    public ServerResponseEntity<Void> delete(@RequestParam List<Long> spuIds) {
        Long supplierId = AuthUserContext.get().getTenantId();
        if (CollUtil.isEmpty(spuIds)) {
            throw new LuckException("商品id不能为空");
        }
        for (Long spuId : spuIds) {
            SpuVO spuDb = spuService.getBySpuId(spuId);
            if (!Objects.equals(spuDb.getSupplierId(), supplierId) && !Objects.equals(supplierId, Constant.PLATFORM_SHOP_ID)) {
                return ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED);
            }
            spuService.deleteById(spuId);
        }
        //  清除购物车数量缓存
        shopCartService.removeShopCartItemCacheBySupplierSpuIds(spuIds);
        return ServerResponseEntity.success();
    }

    @PutMapping("/update_spu_data")
    @Operation(summary = "修改spu（名称、价格、库存、序号）信息", description = "更新spu信息")
    public ServerResponseEntity<Void> updateSpuData(@RequestBody SpuDTO spuDTO) {
        SpuVO spuDb = spuService.getBySpuId(spuDTO.getSpuId());
        if (!Objects.equals(spuDb.getSupplierId(), AuthUserContext.get().getTenantId())) {
            return ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED);
        }
        spuService.updateSpuOrSku(spuDTO);
        //  清除购物车数量缓存
        shopCartService.removeShopCartItemCacheBySupplierSpuIds(Collections.singletonList(spuDTO.getSpuId()));
        return ServerResponseEntity.success();
    }


    /**
     * 更新商品状态
     */
    @PutMapping("/prod_status")
    @Operation(summary = "商品上下架", description = "商品上下架")
    public ServerResponseEntity<Void> spuChangeStatus(@RequestBody SpuPageSearchDTO spuDTO) {
        if (Objects.nonNull(spuDTO.getSpuId())) {
            spuDTO.setSpuIds(Collections.singletonList(spuDTO.getSpuId()));
        }
        if (CollUtil.isEmpty(spuDTO.getSpuIds())) {
            throw new LuckException("商品id不能为空");
        }
        Long shopId = AuthUserContext.get().getTenantId();
        List<SpuVO> spuList = spuService.listSpuBySpuIds(spuDTO.getSpuIds());

        if (Objects.equals(spuDTO.getStatus(), StatusEnum.ENABLE.value())) {
            // 上架商品时，需要根据供应商状态判断是否可以上架商品
            ServerResponseEntity<SupplierDetailBO> supplierRequest = supplierDetailFeignClient.getSupplierBySupplierId(shopId);
            SupplierDetailBO supplierDetailBO = supplierRequest.getData();
            if (!Objects.equals(supplierDetailBO.getSupplierStatus(), ShopStatus.OPEN.value())) {
                // 合同到期
                if (supplierDetailBO.getContractEndTime() != null && supplierDetailBO.getContractEndTime().compareTo(new Date()) < 0) {
                    throw new LuckException("店铺有效期已过，不能进行此操作，请联系管理员后重试");
                }
                throw new LuckException("供应商处于违规下线状态，不能上架商品");
            }
        }
        for (SpuVO spuVO : spuList) {
            if (Objects.equals(spuDTO.getStatus(), StatusEnum.ENABLE.value())) {
                CategoryVO category = categoryService.getInfo(spuVO.getCategoryId());
                if (category == null || Objects.equals(category.getStatus(), StatusEnum.DISABLE.value())) {
                    // 平台分类处于下线中，商品不能上架，请联系管理员后再进行操作
                    throw new LuckException("商品【" + spuVO.getName() + "】的平台分类处于下线中，商品不能上架，请联系管理员后再进行操作");
                }
                //供应商没有店铺分类
                if (!Objects.equals(spuVO.getSpuType(), SpuType.SCORE.value()) && !Objects.equals(AuthUserContext.get().getSysType(), SysTypeEnum.SUPPLIER.value())) {
                    CategoryVO shopCategory = categoryService.getById(spuVO.getShopCategoryId());
                    if (shopCategory == null || Objects.equals(shopCategory.getStatus(), StatusEnum.DISABLE.value())) {
                        // 本店分类处于下线中，商品不能上架
                        throw new LuckException("商品【" + spuVO.getName() + "】的本店分类处于下线中，商品不能上架");
                    }
                }
                // 如果商品正在下架，但又是活动商品，代表这个商品所属的活动被平台下架了
                if (Objects.equals(spuVO.getSpuType(), SpuType.SECKILL.value())) {
                    throw new LuckException("商品【" + spuVO.getName() + "】所属的秒杀活动处于违规下线中，商品不能上架");
                }
                if (Objects.equals(spuVO.getSpuType(), SpuType.GROUP.value())) {
                    throw new LuckException("商品【" + spuVO.getName() + "】所属的团购活动处于违规下线中，商品不能上架");
                }
            }
            if (!Objects.equals(spuVO.getSupplierId(), shopId) && !Objects.equals(shopId, Constant.PLATFORM_SHOP_ID)) {
                return ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED);
            }
        }
        // 是否开启“商品发布时审核”，若开启，上架修改状态为“待审核”【平台端不用审核】
        String prodSwitchConfig = configFeignClient.getConfig(Constant.SPU_SWITCH_CONFIG).getData();
        if (SpuStatus.PUT_SHELF.value().equals(spuDTO.getStatus())
                && !SysTypeEnum.PLATFORM.value().equals(AuthUserContext.get().getSysType())
                && !ObjectUtils.isEmpty(prodSwitchConfig)) {
            Boolean spuAudit = JSON.parseObject(prodSwitchConfig, new TypeReference<Map<String, Boolean>>() {
                    })
                    .getOrDefault("spuAudit", false);
            if (spuAudit) {
                spuDTO.setStatus(SpuStatus.PUBLISH_WAIT_AUDIT.value());
            }
        }
        spuBatchUpdateStatus(spuDTO);
        for (SpuVO spuVO : spuList) {
            spuService.removeSpuCacheBySpuId(spuVO.getSpuId());
        }
        //  清除购物车数量缓存
        shopCartService.removeShopCartItemCacheBySupplierSpuIds(spuDTO.getSpuIds());
        return ServerResponseEntity.success();
    }

    @GetMapping("/soldExcel")
    @Operation(summary = "导出excel", description = "导出商品excel")
    public ServerResponseEntity<Void> spuSoldExcel(HttpServletResponse response, SpuPageSearchDTO spuDTO) {
        List<SpuExcelVO> list = spuExcelService.excelSpuList(spuDTO);
        List<SupplierProdExcelVO> supplierProdExcelVOList = list.stream().map(spu -> {
            SupplierProdExcelVO supplierProdExcelVO = new SupplierProdExcelVO();
            BeanUtils.copyProperties(spu, supplierProdExcelVO);
            return supplierProdExcelVO;

        }).collect(Collectors.toList());
        ExcelUtil.soleExcel(response, supplierProdExcelVOList, SupplierProdExcelVO.EXCEL_NAME, SupplierProdExcelVO.MERGE_ROW_INDEX, SupplierProdExcelVO.MERGE_COLUMN_INDEX, SupplierProdExcelVO.class);
        return ServerResponseEntity.success();
    }

    @GetMapping("/exportModel")
    @Operation(summary = "导出商品excel模板", description = "导出商品excel模板")
    public ServerResponseEntity<Void> exportModel(HttpServletResponse response) {
        spuExcelService.downloadModel(response);
        return ServerResponseEntity.success();
    }

    @Operation(summary = "导入文件")
    @PostMapping("/export_excel")
    public ServerResponseEntity<String> exportExcel(@RequestParam("excelFile") MultipartFile file) {
        if (file == null) {
            throw new LuckException("网络繁忙，请稍后重试");
        }
        // 判断execl文件是否为空
        if (SheetUtil.sheetIsNull(file)) {
            return ServerResponseEntity.success("[导入文件为空]");
        }
        String info;
        try {
            Map<Integer, List<String>> errorMap = new HashMap<>(8);
            EasyExcel.read(file.getInputStream(), SupplierProdExcelVO.class, new SupplierProdExcelListener(spuExcelService, errorMap)).sheet().doRead();
            info = spuExcelService.spuExportError(errorMap);
        } catch (IOException e) {
            throw new LuckException(e.getMessage());
        }
        return ServerResponseEntity.success(info);
    }

    /**
     * spu批量上下架
     *
     * @param spuDTO
     */
    private void spuBatchUpdateStatus(SpuPageSearchDTO spuDTO) {
        List<Long> spuIds = spuDTO.getSpuIds();
        Integer status = spuDTO.getStatus();
        spuDTO.setStatus(null);
        List<SpuVO> spuList = spuService.list(spuDTO);
        if (CollUtil.isEmpty(spuList)) {
            throw new LuckException("获取不到该商品信息，请刷新后重试");
        }
        checkUpdateStatusData(spuList, status);
        if (CollUtil.isEmpty(spuIds)) {
            throw new LuckException("您所选择的商品中没有符合操作条件的商品");
        }
        spuService.batchChangeSpuStatus(spuIds, status);
        spuSupplierChangeLogService.insertBatchChangeStatus(spuIds, status);
        //给代销商品增加供应商是商品更新标识
        List<Long> spuIdList = spuService.getSupIdListBySupplierId(spuDTO.getSpuId());
        if (CollUtil.isNotEmpty(spuIdList)) {
            spuService.batchChangeSynUpdate(spuIdList, IsSynUpdate.NO_CHANGE.value());
        }
    }

    /**
     * 校验spu上下架信息
     *
     * @param list   商品列表
     * @param status 更新的状态
     * @return
     */
    private void checkUpdateStatusData(List<SpuVO> list, Integer status) {
        ProductLangUtil.spuList(list);
        Long shopId = AuthUserContext.get().getTenantId();
        Integer sysType = AuthUserContext.get().getSysType();
        ServerResponseEntity<EsShopDetailBO> shopRequest = shopDetailFeignClient.getShopByShopId(shopId);
        EsShopDetailBO shopDetail = shopRequest.getData();
        if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE.value()) || Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE_AWAIT_AUDIT.value())) {
            throw new LuckException("供应商处于违规下线中，不能修改商品");
        }
        for (SpuVO spu : list) {
            if (!Objects.equals(spu.getSupplierId(), shopId) && !Objects.equals(AuthUserContext.get().getTenantId(), Constant.PLATFORM_SHOP_ID)) {
                throw new LuckException(ResponseEnum.UNAUTHORIZED);
            }
            // 商品状态不为启用或未启用状态
            if (!Objects.equals(spu.getStatus(), StatusEnum.ENABLE.value())
                    && !Objects.equals(spu.getStatus(), StatusEnum.DISABLE.value())) {
                throw new LuckException("商品(" + spu.getName() + ")不能进行上下架操作");
            }
            if (Objects.equals(status, StatusEnum.ENABLE.value()) && !Objects.equals(spu.getSpuType(), SpuType.SCORE.value())) {
                CategoryVO category = categoryService.getById(spu.getCategoryId());
                if (!Objects.equals(category.getStatus(), StatusEnum.ENABLE.value())) {
                    throw new LuckException("商品(" + spu.getName() + ")所属的平台分类处于下线中，商品不能进行上架操作，请联系管理员后再进行操作");
                }
                //供应商没有店铺分类
                if (!Objects.equals(spu.getSpuType(), SpuType.SCORE.value())) {
                    if (!Objects.equals(sysType, SysTypeEnum.SUPPLIER.value())) {
                        CategoryVO shopCategory = categoryService.getById(spu.getShopCategoryId());
                        if (!Objects.equals(shopCategory.getStatus(), StatusEnum.ENABLE.value())) {
                            throw new LuckException("商品(" + spu.getName() + ")所属的店铺分类处于下线中，商品不能进行上架操作");
                        }
                    }
                    CategoryShopVO categoryShopVO = categoryShopService.getByShopIdAndCategoryId(Objects.equals(sysType, SysTypeEnum.SUPPLIER.value()) ? spu.getSupplierId() : spu.getShopId(), spu.getCategoryId(), sysType);
                    if (Objects.isNull(categoryShopVO)) {
                        throw new LuckException("商品(" + spu.getName() + ")所属的平台分类与店铺的签约关系已失效，商品不能进行上架操作");
                    }
                }
            }
        }
    }

    @PostMapping("/offline")
    @Operation(summary = "下线商品", description = "下线商品")
    public ServerResponseEntity<Void> offline(@RequestBody OfflineHandleEventDTO offlineHandleEventDto) {
        if (!Objects.equals(Constant.PLATFORM_SHOP_ID, AuthUserContext.get().getTenantId())) {
            throw new LuckException(ResponseEnum.UNAUTHORIZED);
        }
        SpuVO spuVO = spuService.getBySpuId(offlineHandleEventDto.getHandleId());
        if (Objects.isNull(spuVO)) {
            throw new LuckException(ResponseEnum.DATA_ERROR);
        }
        spuService.offline(offlineHandleEventDto);
        spuService.removeSpuCacheBySpuId(offlineHandleEventDto.getHandleId());
        return ServerResponseEntity.success();
    }

    @PostMapping("/batch_offline")
    @Operation(summary = "批量下线商品", description = "批量下线商品")
    public ServerResponseEntity<Void> batchOffline(@RequestBody OfflineHandleEventDTO offlineHandleEventDto) {
        if (!Objects.equals(Constant.PLATFORM_SHOP_ID, AuthUserContext.get().getTenantId())) {
            throw new LuckException(ResponseEnum.UNAUTHORIZED);
        }
        if (CollUtil.isEmpty(offlineHandleEventDto.getHandleIds())) {
            throw new LuckException("下线的商品id列表不能为空");
        }
        spuService.batchOffile(offlineHandleEventDto);
        return ServerResponseEntity.success();
    }

    @GetMapping("/getOfflineHandleEvent/{spuId}")
    @Operation(summary = "获取最新下线的事件", description = "获取最新下线的事件")
    public ServerResponseEntity<OfflineHandleEventVO> getOfflineHandleEvent(@PathVariable Long spuId) {
        SpuVO spuDb = spuService.getBySpuId(spuId);
        if (!Objects.equals(spuDb.getSupplierId(), AuthUserContext.get().getTenantId()) && !Objects.equals(Constant.PLATFORM_SHOP_ID, AuthUserContext.get().getTenantId())) {
            return ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED);
        }
        return ServerResponseEntity.success(spuService.getOfflineHandleEvent(spuId));
    }

    @PostMapping("/audit")
    @Operation(summary = "审核商品", description = "审核商品")
    public ServerResponseEntity<Void> audit(@RequestBody OfflineHandleEventDTO offlineHandleEventDto) {
        if (!Objects.equals(Constant.PLATFORM_SHOP_ID, AuthUserContext.get().getTenantId())) {
            throw new LuckException(ResponseEnum.UNAUTHORIZED);
        }
        spuService.audit(offlineHandleEventDto);
        spuService.removeSpuCacheBySpuId(offlineHandleEventDto.getHandleId());
        return ServerResponseEntity.success();
    }

    @PostMapping("/auditApply")
    @Operation(summary = "违规活动提交审核", description = "违规活动提交审核")
    public ServerResponseEntity<Void> auditApply(@RequestBody OfflineHandleEventDTO offlineHandleEventDto) {
        SpuVO spuDb = spuService.getBySpuId(offlineHandleEventDto.getHandleId());
        if (!Objects.equals(spuDb.getSupplierId(), AuthUserContext.get().getTenantId())) {
            return ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED);
        }
        spuService.auditApply(offlineHandleEventDto);
        return ServerResponseEntity.success();
    }
}
