package com.ruoyi.web.modules.store.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.account.dto.AccountPasswordUpdateDTO;
import com.ruoyi.web.modules.account.dto.AccountProfileUpdateDTO;
import com.ruoyi.web.modules.account.service.IAccountProfileService;
import com.ruoyi.web.modules.account.util.MemberMobileUtils;
import com.ruoyi.web.modules.merchant.domain.BizMerchant;
import com.ruoyi.web.modules.merchant.facade.IMerchantFacade;
import com.ruoyi.web.modules.merchant.facade.IMerchantShopFacade;
import com.ruoyi.web.modules.merchant.mapper.BizMerchantMapper;
import com.ruoyi.web.modules.merchant.support.MerchantDisplayUtils;
import com.ruoyi.web.modules.merchant.vo.OpenShopCheckVO;
import com.ruoyi.web.modules.store.constant.ShopConstants;
import com.ruoyi.web.modules.store.domain.BizMerchantAccount;
import com.ruoyi.web.modules.store.domain.BizShop;
import com.ruoyi.web.modules.store.dto.MerchantAccountUpdateDTO;
import com.ruoyi.web.modules.store.dto.SellerShopProfileDTO;
import com.ruoyi.web.modules.store.dto.ShopCreateDTO;
import com.ruoyi.web.modules.store.dto.ShopUpdateDTO;
import com.ruoyi.web.modules.store.exception.ShopBatchDeleteException;
import com.ruoyi.web.modules.store.facade.IGoodsShopFacade;
import com.ruoyi.web.modules.store.facade.IShopGlobalConfigFacade;
import com.ruoyi.web.modules.store.facade.IShopOrderFacade;
import com.ruoyi.web.modules.store.mapper.BizMerchantAccountMapper;
import com.ruoyi.web.modules.store.mapper.BizShopMapper;
import com.ruoyi.web.modules.store.service.IShopService;
import com.ruoyi.web.modules.store.vo.MerchantAccountManageVO;
import com.ruoyi.web.modules.store.vo.MerchantAccountUserVO;
import com.ruoyi.web.modules.store.vo.ShopDeleteCheckVO;
import com.ruoyi.web.modules.store.vo.SellerShopProfileVO;
import com.ruoyi.web.modules.store.vo.SellerShopEmployeeStatsVO;
import com.ruoyi.web.modules.store.vo.ShopEmployeeCountRow;
import com.ruoyi.web.modules.store.vo.ShopDetailVO;
import com.ruoyi.web.modules.store.vo.ShopListVO;
import com.ruoyi.web.modules.merchant.vo.MerchantShopBriefVO;

@Service
public class ShopServiceImpl implements IShopService
{
    @Autowired
    private BizShopMapper shopMapper;

    @Autowired
    private BizMerchantAccountMapper accountMapper;

    @Autowired
    private BizMerchantMapper merchantMapper;

    @Autowired
    private IMerchantFacade merchantFacade;

    @Autowired
    private IMerchantShopFacade merchantShopFacade;

    @Autowired
    private IGoodsShopFacade goodsShopFacade;

    @Autowired
    private IShopOrderFacade shopOrderFacade;

    @Autowired
    private IShopGlobalConfigFacade shopGlobalConfigFacade;

    @Autowired
    private IAccountProfileService accountProfileService;

    @Override
    public List<ShopListVO> selectShopList(BizShop query)
    {
        List<ShopListVO> rows = shopMapper.selectList(query);
        for (ShopListVO row : rows)
        {
            if (StringUtils.isNotEmpty(row.getAccountLoginName()))
            {
                row.setAccountLoginName(MemberMobileUtils.mask(row.getAccountLoginName()));
            }
        }
        return rows;
    }

    @Override
    public ShopDetailVO selectShopDetail(Long shopId)
    {
        BizShop shop = requireShop(shopId);
        ShopDetailVO vo = new ShopDetailVO();
        vo.setShopId(shop.getShopId());
        vo.setMerchantId(shop.getMerchantId());
        vo.setShopName(shop.getShopName());
        vo.setShopAvatar(shop.getShopAvatar());
        vo.setShopStatus(shop.getShopStatus());
        vo.setShopDesc(shop.getShopDesc());
        vo.setShopPhone(shop.getShopPhone());
        BizMerchant merchant = merchantMapper.selectById(shop.getMerchantId());
        if (merchant != null)
        {
            String name = StringUtils.isNotEmpty(merchant.getMerchantName())
                    ? merchant.getMerchantName() : MerchantDisplayUtils.unitName(merchant);
            vo.setMerchantName(name);
        }
        MerchantAccountUserVO account = accountMapper.selectMerchantAdminWithUser(shop.getMerchantId());
        if (account != null)
        {
            vo.setAccountAdminName(account.getAdminName());
            vo.setAccountLoginName(MemberMobileUtils.mask(account.getLoginName()));
        }
        vo.setCanDelete(deleteCheck(shopId).isCanDelete());
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createShop(ShopCreateDTO dto, String operator)
    {
        assertOpenShop(dto.getMerchantId());
        validateShopFieldsOnCreate(dto);
        if (shopMapper.countByShopName(dto.getShopName(), null) > 0)
        {
            throw new ServiceException(ShopConstants.MSG_SHOP_NAME_EXISTS);
        }
        if (accountMapper.selectByMerchantId(dto.getMerchantId()) == null)
        {
            throw new ServiceException(ShopConstants.MSG_NO_MERCHANT_ACCOUNT);
        }
        BizShop shop = new BizShop();
        shop.setMerchantId(dto.getMerchantId());
        shop.setShopName(dto.getShopName());
        shop.setShopAvatar(dto.getShopAvatar());
        shop.setShopPhone(dto.getShopPhone());
        shop.setShopDesc(dto.getShopDesc());
        shop.setShopStatus(resolveShopStatusOnCreate(dto.getShopStatus()));
        shop.setDelFlag(ShopConstants.DEL_NORMAL);
        shop.setCreateBy(operator);
        shopMapper.insert(shop);
        merchantShopFacade.incrementShopCount(dto.getMerchantId());
        return shop.getShopId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> updateShop(ShopUpdateDTO dto, String operator)
    {
        BizShop existing = requireShop(dto.getShopId());
        validateShopFieldsOnUpdate(dto);
        if (StringUtils.isNotEmpty(dto.getShopName())
                && shopMapper.countByShopName(dto.getShopName(), dto.getShopId()) > 0)
        {
            throw new ServiceException(ShopConstants.MSG_SHOP_NAME_EXISTS);
        }
        String targetStatus = StringUtils.isNotEmpty(dto.getShopStatus())
                ? dto.getShopStatus() : existing.getShopStatus();
        if (ShopConstants.STATUS_OPEN.equals(existing.getShopStatus())
                && ShopConstants.STATUS_CLOSED.equals(targetStatus)
                && !dto.isConfirmed())
        {
            Map<String, Object> data = new HashMap<>();
            data.put("needConfirm", true);
            data.put("confirmMessage", ShopConstants.MSG_CLOSE_CONFIRM);
            return data;
        }
        BizShop update = new BizShop();
        update.setShopId(dto.getShopId());
        update.setShopName(dto.getShopName());
        update.setShopAvatar(dto.getShopAvatar());
        update.setShopStatus(targetStatus);
        update.setShopDesc(dto.getShopDesc());
        update.setShopPhone(dto.getShopPhone());
        update.setUpdateBy(operator);
        shopMapper.update(update);
        Map<String, Object> data = new HashMap<>();
        data.put("needConfirm", false);
        return data;
    }

    @Override
    public SellerShopProfileVO selectSellerShopProfile(Long shopId)
    {
        requireShop(shopId);
        SellerShopProfileVO vo = shopMapper.selectSellerProfileById(shopId);
        if (vo == null)
        {
            throw new ServiceException("店铺不存在");
        }
        if (StringUtils.isNotEmpty(vo.getContactPhone()))
        {
            vo.setContactPhone(MemberMobileUtils.mask(vo.getContactPhone()));
        }
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSellerShopProfile(Long shopId, SellerShopProfileDTO dto, String operator)
    {
        requireShop(shopId);
        validateSellerShopProfile(dto);
        if (shopMapper.countByShopName(dto.getShopName(), shopId) > 0)
        {
            throw new ServiceException(ShopConstants.MSG_SHOP_NAME_EXISTS);
        }
        BizShop update = new BizShop();
        update.setShopId(shopId);
        update.setShopName(dto.getShopName());
        update.setShopAvatar(dto.getShopAvatar());
        update.setShopDesc(dto.getShopDesc());
        update.setShopPhone(dto.getShopPhone());
        update.setUpdateBy(operator);
        shopMapper.update(update);
    }

    @Override
    public SellerShopEmployeeStatsVO selectSellerEmployeeStats(Long shopId)
    {
        BizShop shop = requireShop(shopId);
        ShopEmployeeCountRow countRow = accountMapper.countEmployeesByShopId(shop.getMerchantId(), shopId);
        int totalCount = countRow != null ? countRow.getTotalCount() : 0;
        int disabledCount = countRow != null ? countRow.getDisabledCount() : 0;
        int usedCount = accountMapper.countEmployeesByMerchantId(shop.getMerchantId());
        Integer maxCount = shopGlobalConfigFacade.getMaxSubAdmin();
        if (maxCount == null)
        {
            maxCount = ShopConstants.DEFAULT_MAX_SUB_ADMIN;
        }
        SellerShopEmployeeStatsVO vo = new SellerShopEmployeeStatsVO();
        vo.setShopId(shopId);
        vo.setShopName(shop.getShopName());
        vo.setTotalCount(totalCount);
        vo.setDisabledCount(disabledCount);
        vo.setUsedCount(usedCount);
        vo.setMaxCount(maxCount);
        return vo;
    }

    @Override
    public ShopDeleteCheckVO deleteCheck(Long shopId)
    {
        return buildDeleteCheck(requireShop(shopId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteShopByIds(Long[] shopIds, String operator)
    {
        if (shopIds == null || shopIds.length == 0)
        {
            throw new ServiceException("请选择要删除的店铺");
        }
        List<String> reasons = new ArrayList<>();
        List<BizShop> toDelete = new ArrayList<>();
        for (Long shopId : shopIds)
        {
            BizShop shop = shopMapper.selectById(shopId);
            if (shop == null)
            {
                reasons.add("店铺不存在");
                continue;
            }
            ShopDeleteCheckVO check = buildDeleteCheck(shop);
            if (!check.isCanDelete())
            {
                reasons.addAll(check.getReasons());
            }
            else
            {
                toDelete.add(shop);
            }
        }
        if (!reasons.isEmpty())
        {
            throw new ShopBatchDeleteException(ShopConstants.MSG_BATCH_DELETE, reasons);
        }
        List<Long> ids = new ArrayList<>();
        for (BizShop shop : toDelete)
        {
            ids.add(shop.getShopId());
        }
        shopMapper.logicDeleteByIds(ids, operator);
        for (BizShop shop : toDelete)
        {
            merchantShopFacade.decrementShopCount(shop.getMerchantId());
        }
    }

    @Override
    public MerchantAccountManageVO getMerchantAccount(Long merchantId)
    {
        requireMerchant(merchantId);
        MerchantAccountUserVO account = accountMapper.selectMerchantAdminWithUser(merchantId);
        MerchantAccountManageVO vo = new MerchantAccountManageVO();
        if (account != null)
        {
            vo.setAdminName(account.getAdminName());
            vo.setLoginName(MemberMobileUtils.mask(account.getLoginName()));
        }
        List<MerchantShopBriefVO> shops = shopMapper.selectBriefByMerchantId(merchantId);
        for (MerchantShopBriefVO brief : shops)
        {
            MerchantAccountManageVO.ShopBriefItem item = new MerchantAccountManageVO.ShopBriefItem();
            item.setShopId(brief.getShopId());
            item.setShopName(brief.getShopName());
            item.setShopStatus(brief.getShopStatus());
            vo.getShops().add(item);
        }
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> updateMerchantAccount(Long merchantId, MerchantAccountUpdateDTO dto, String operator)
    {
        requireMerchant(merchantId);
        BizMerchantAccount account = accountMapper.selectByMerchantId(merchantId);
        if (account == null)
        {
            throw new ServiceException(ShopConstants.MSG_NO_MERCHANT_ACCOUNT);
        }
        AccountProfileUpdateDTO profile = new AccountProfileUpdateDTO();
        profile.setUserId(account.getAccountId());
        profile.setAccountName(dto.getAdminName());
        profile.setMobile(dto.getLoginName());
        profile.setConfirm(dto.getConfirm());
        Map<String, Object> data = accountProfileService.updateProfile(profile, operator);
        if (Boolean.TRUE.equals(data.get("needConfirm")))
        {
            return data;
        }
        if (StringUtils.isNotEmpty(dto.getPassword()))
        {
            AccountPasswordUpdateDTO pwd = new AccountPasswordUpdateDTO();
            pwd.setUserId(account.getAccountId());
            pwd.setPassword(dto.getPassword());
            pwd.setConfirmPassword(dto.getPassword());
            accountProfileService.updatePassword(pwd, operator);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("needConfirm", false);
        return result;
    }

    private ShopDeleteCheckVO buildDeleteCheck(BizShop shop)
    {
        ShopDeleteCheckVO vo = new ShopDeleteCheckVO();
        List<String> reasons = new ArrayList<>();
        if (goodsShopFacade.hasBlockingGoodsForShopDelete(shop.getShopId()))
        {
            reasons.add(ShopConstants.MSG_DELETE_GOODS);
        }
        if (shopOrderFacade.hasUnfinishedOrdersByShop(shop.getShopId()))
        {
            reasons.add(ShopConstants.MSG_DELETE_ORDER);
        }
        vo.setReasons(reasons);
        vo.setCanDelete(reasons.isEmpty());
        return vo;
    }

    private void assertOpenShop(Long merchantId)
    {
        OpenShopCheckVO check = merchantFacade.checkOpenShop(merchantId);
        if (check == null || !check.isAllowed())
        {
            String reason = check != null && StringUtils.isNotEmpty(check.getReason())
                    ? check.getReason() : ShopConstants.MSG_MERCHANT_CANNOT_OPEN;
            throw new ServiceException(reason);
        }
    }

    private void validateShopFieldsOnCreate(ShopCreateDTO dto)
    {
        if (dto.getMerchantId() == null)
        {
            throw new ServiceException("请选择商户");
        }
        validateShopName(dto.getShopName());
        validateShopAvatar(dto.getShopAvatar());
        if (StringUtils.isNotEmpty(dto.getShopPhone()))
        {
            validateShopPhone(dto.getShopPhone());
        }
        if (StringUtils.isNotEmpty(dto.getShopStatus())
                && !ShopConstants.STATUS_OPEN.equals(dto.getShopStatus())
                && !ShopConstants.STATUS_CLOSED.equals(dto.getShopStatus()))
        {
            throw new ServiceException("店铺状态无效");
        }
        if (StringUtils.isNotEmpty(dto.getShopDesc()) && dto.getShopDesc().length() > 1000)
        {
            throw new ServiceException("店铺描述过长");
        }
    }

    private void validateSellerShopProfile(SellerShopProfileDTO dto)
    {
        validateShopName(dto.getShopName());
        validateShopAvatar(dto.getShopAvatar());
        if (StringUtils.isNotEmpty(dto.getShopPhone()))
        {
            validateShopPhone(dto.getShopPhone());
        }
        if (dto.getShopDesc() != null && dto.getShopDesc().length() > 1000)
        {
            throw new ServiceException("店铺描述过长");
        }
    }

    private void validateShopFieldsOnUpdate(ShopUpdateDTO dto)
    {
        if (dto.getShopId() == null)
        {
            throw new ServiceException("店铺ID不能为空");
        }
        if (StringUtils.isNotEmpty(dto.getShopName()))
        {
            validateShopName(dto.getShopName());
        }
        if (StringUtils.isNotEmpty(dto.getShopAvatar()))
        {
            validateShopAvatar(dto.getShopAvatar());
        }
        if (StringUtils.isNotEmpty(dto.getShopPhone()))
        {
            validateShopPhone(dto.getShopPhone());
        }
        if (StringUtils.isNotEmpty(dto.getShopDesc()) && dto.getShopDesc().length() > 1000)
        {
            throw new ServiceException("店铺描述过长");
        }
        if (StringUtils.isNotEmpty(dto.getShopStatus())
                && !ShopConstants.STATUS_OPEN.equals(dto.getShopStatus())
                && !ShopConstants.STATUS_CLOSED.equals(dto.getShopStatus()))
        {
            throw new ServiceException("店铺状态无效");
        }
    }

    private String resolveShopStatusOnCreate(String shopStatus)
    {
        if (StringUtils.isEmpty(shopStatus))
        {
            return ShopConstants.STATUS_OPEN;
        }
        return shopStatus;
    }

    private void validateShopPhone(String shopPhone)
    {
        if (StringUtils.isEmpty(shopPhone))
        {
            return;
        }
        if (!shopPhone.matches("^[0-9\\-+()\\s]{5,20}$"))
        {
            throw new ServiceException("商家电话格式不正确");
        }
    }

    private void validateShopName(String shopName)
    {
        if (StringUtils.isEmpty(shopName))
        {
            throw new ServiceException("请输入店铺名称");
        }
        if (shopName.length() > 128)
        {
            throw new ServiceException("店铺名称过长");
        }
    }

    private void validateShopAvatar(String shopAvatar)
    {
        if (StringUtils.isEmpty(shopAvatar))
        {
            throw new ServiceException("请上传店铺头像");
        }
    }

    private BizShop requireShop(Long shopId)
    {
        BizShop shop = shopMapper.selectById(shopId);
        if (shop == null)
        {
            throw new ServiceException("店铺不存在");
        }
        return shop;
    }

    private BizMerchant requireMerchant(Long merchantId)
    {
        BizMerchant m = merchantMapper.selectById(merchantId);
        if (m == null)
        {
            throw new ServiceException("商户不存在");
        }
        return m;
    }
}
