package com.seer.teach.mp.admin.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.seer.teach.mp.admin.controller.req.MpMenuSaveReq;
import com.seer.teach.mp.admin.controller.resp.AdminMpMenuResp;
import com.seer.teach.mp.entity.MpAccountEntity;
import com.seer.teach.mp.entity.MpAccountMenuEntity;
import com.seer.teach.mp.factory.MpServiceFactory;
import com.seer.teach.mp.service.IMpAccountService;
import com.seer.teach.mp.service.IMpAccountMenuService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.bean.menu.WxMenuButton;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@RequiredArgsConstructor
@Slf4j
@Validated
@Service
public class AdminMpAccountMenuService {

    private final IMpAccountService mpAccountService;

    private final IMpAccountMenuService mpMenuService;

    @Autowired
    @Lazy
    private MpServiceFactory mpServiceFactory;

    /**
     * 创建公众号菜单
     *
     * @param createReqVO 创建信息
     * @return 是否创建成功
     */
    public boolean createAccountMenu(@Valid MpMenuSaveReq createReqVO) {
        // 验证公众号是否存在
        MpAccountEntity account = mpAccountService.getById(createReqVO.getAccountId());
        if (account == null) {
            throw new RuntimeException("公众号不存在");
        }

        try {
            // 获取微信公众号服务
            WxMpService wxMpService = mpServiceFactory.getRequiredMpService(account.getAppId());

            // 构建微信菜单对象
            WxMenu wxMpMenu = buildWxMpMenu(createReqVO);

            // 调用微信API创建菜单
            wxMpService.getMenuService().menuCreate(wxMpMenu);

            // 保存菜单配置到数据库
            saveMenuToDatabase(createReqVO, account);

            log.info("[createAccount][创建公众号菜单成功，公众号ID为:{}]", account.getId());
            return true;
        } catch (WxErrorException e) {
            log.error("[createAccount][创建公众号菜单失败，公众号ID为:{}]，错误信息:{}",
                    createReqVO.getAccountId(), e.getError().getErrorMsg());
            throw new RuntimeException("创建公众号菜单失败：" + e.getError().getErrorMsg());
        }
    }

    /**
     * 构建微信菜单对象
     */
    private WxMenu buildWxMpMenu(MpMenuSaveReq createReqVO) {
        WxMenu wxMpMenu = new WxMenu();
        List<WxMenuButton> buttons = new ArrayList<>();

        for (MpMenuSaveReq.Button button : createReqVO.getButton()) {
            buttons.add(convertToWxMpButton(button));
        }

        wxMpMenu.setButtons(buttons);
        return wxMpMenu;
    }

    /**
     * 将请求按钮转换为微信菜单按钮对象
     */
    private WxMenuButton convertToWxMpButton(MpMenuSaveReq.Button button) {
        WxMenuButton wxButton = new WxMenuButton();
        wxButton.setType(button.getType());
        wxButton.setName(button.getName());

        // 根据按钮类型设置相应属性
        if ("click".equalsIgnoreCase(button.getType())) {
            wxButton.setKey(button.getKey());
        } else if ("view".equalsIgnoreCase(button.getType())) {
            wxButton.setUrl(button.getUrl());
        } else if ("miniprogram".equalsIgnoreCase(button.getType())) {
            wxButton.setAppId(button.getAppid());
            wxButton.setPagePath(button.getPagepath());
            wxButton.setUrl(button.getUrl()); // 备用URL
        } else if ("media_id".equalsIgnoreCase(button.getType()) ||
                "view_limited".equalsIgnoreCase(button.getType())) {
            wxButton.setMediaId(button.getMediaId());
        } else if ("article_id".equalsIgnoreCase(button.getType()) ||
                "article_view_limited".equalsIgnoreCase(button.getType())) {
            wxButton.setArticleId(button.getArticleId());
        } else {
            // 其他类型如扫码、拍照等，设置key值
            if (button.getKey() != null) {
                wxButton.setKey(button.getKey());
            }
        }

        if (button.getSubButton() != null && !button.getSubButton().isEmpty()) {
            List<WxMenuButton> subButtons = new ArrayList<>();
            for (MpMenuSaveReq.Button subButton : button.getSubButton()) {
                subButtons.add(convertToWxMpButton(subButton));
            }
            wxButton.setSubButtons(subButtons);
        }

        return wxButton;
    }

    /**
     * 保存菜单配置到数据库
     */
    private void saveMenuToDatabase(MpMenuSaveReq createReqVO, MpAccountEntity account) {
        // 保存新的菜单配置
        for (int i = 0; i < createReqVO.getButton().size(); i++) {
            MpMenuSaveReq.Button button = createReqVO.getButton().get(i);
            saveButtonToDatabase(button, account, 0, i);
        }
    }

    private void saveButtonToDatabase(MpMenuSaveReq.Button button, MpAccountEntity account, Integer parentId, Integer sort) {
        MpAccountMenuEntity menuEntity = new MpAccountMenuEntity();
        menuEntity.setAccountId(account.getId());
        menuEntity.setAppid(account.getAppId());
        menuEntity.setName(button.getName());
        menuEntity.setType(button.getType());
        menuEntity.setMenuKey(button.getKey());
        menuEntity.setUrl(button.getUrl());
        menuEntity.setMediaId(button.getMediaId());
        menuEntity.setAppid(button.getAppid());
        menuEntity.setPagepath(button.getPagepath());
        menuEntity.setArticleId(button.getArticleId());
        menuEntity.setParentId(parentId);
        menuEntity.setSort(sort);
        menuEntity.setStatus(1);

        mpMenuService.save(menuEntity);

        // 如果有子菜单，递归保存
        if (button.getSubButton() != null && !button.getSubButton().isEmpty()) {
            Integer currentMenuId = menuEntity.getId();
            for (int i = 0; i < button.getSubButton().size(); i++) {
                com.seer.teach.mp.admin.controller.req.MpMenuSaveReq.Button subButton = button.getSubButton().get(i);
                saveButtonToDatabase(subButton, account, currentMenuId, i);
            }
        }
    }

    /**
     * 获取公众号菜单列表
     *
     * @param accountId 公众号ID
     * @return 菜单列表
     */
    public List<AdminMpMenuResp> getMenuList(Integer accountId) {
        // 查询一级菜单
        List<MpAccountMenuEntity> menus = mpMenuService.list(
                com.baomidou.mybatisplus.core.toolkit.Wrappers.<MpAccountMenuEntity>lambdaQuery()
                        .eq(MpAccountMenuEntity::getAccountId, accountId)
                        .eq(MpAccountMenuEntity::getParentId, 0)
                        .orderByAsc(MpAccountMenuEntity::getSort)
        );

        List<AdminMpMenuResp> result = new ArrayList<>();
        for (MpAccountMenuEntity menu : menus) {
            AdminMpMenuResp resp = convertToMenuResp(menu);
            // 查询子菜单
            List<MpAccountMenuEntity> subMenus = mpMenuService.list(
                    com.baomidou.mybatisplus.core.toolkit.Wrappers.<MpAccountMenuEntity>lambdaQuery()
                            .eq(MpAccountMenuEntity::getAccountId, accountId)
                            .eq(MpAccountMenuEntity::getParentId, menu.getId())
                            .orderByAsc(MpAccountMenuEntity::getSort)
            );
            if (!subMenus.isEmpty()) {
                resp.setSubMenus(subMenus.stream()
                        .map(this::convertToMenuResp)
                        .toList());
            }
            result.add(resp);
        }
        return result;
    }

    /**
     * 删除公众号菜单
     *
     * @param accountId 菜单ID
     * @return 是否删除成功
     */
    public boolean deleteMenuByAppId(Integer accountId) {
        MpAccountEntity account = mpAccountService.getById(accountId);
        if(Objects.isNull(account)){
            log.error("[deleteMenu][删除公众号菜单失败，公众号ID为:{}]", accountId);
            return false;
        }
        String appId = account.getAppId();
        try {
            WxMpService wxMpService = mpServiceFactory.getRequiredMpService(appId);
            wxMpService.getMenuService().menuDelete();
            deleteMenuRecursive(appId);
            return true;
        } catch (Exception e) {
            log.error("[deleteMenu][删除公众号菜单失败，菜单AppID为:{}]", appId, e);
            return false;
        }
    }

    /**
     * 递归删除菜单
     */
    private void deleteMenuRecursive(String appId) {
        mpMenuService.removeById(new LambdaQueryWrapper<MpAccountMenuEntity>().eq(MpAccountMenuEntity::getAppid, appId));
    }

    /**
     * 转换菜单实体为响应对象
     */
    private AdminMpMenuResp convertToMenuResp(MpAccountMenuEntity menu) {
        AdminMpMenuResp resp = new AdminMpMenuResp();
        resp.setId(menu.getId());
        resp.setAccountId(menu.getAccountId());
        resp.setName(menu.getName());
        resp.setType(menu.getType());
        resp.setMenuKey(menu.getMenuKey());
        resp.setUrl(menu.getUrl());
        resp.setMediaId(menu.getMediaId());
        resp.setAppid(menu.getAppid());
        resp.setPagepath(menu.getPagepath());
        resp.setArticleId(menu.getArticleId());
        resp.setParentId(menu.getParentId());
        resp.setMenuConfig(menu.getMenuConfig());
        resp.setSort(menu.getSort());
        resp.setStatus(menu.getStatus());
        resp.setCreateTime(menu.getCreateTime());
        resp.setUpdateTime(menu.getUpdateTime());
        return resp;
    }


}