package org.dromara.mp.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.bean.result.WxMpUserList;
import me.chanjar.weixin.mp.bean.tag.WxUserTag;
import org.dromara.common.core.domain.R;
import org.dromara.common.web.core.BaseController;
import org.dromara.mp.annotation.SwitchoverCheck;
import org.dromara.mp.service.WxMpUserService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 微信公众号用户管理控制器
 *
 * @author pengles
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/wx/mp/user/{appid}")
public class WxMpUserController extends BaseController {

    private final WxMpService wxMpService;
    private final WxMpUserService wxMpUserService;

    /**
     * 获取用户信息
     *
     * @param appid  公众号appid
     * @param openid 用户openid
     * @return 用户信息
     */
    @GetMapping("/info/{openid}")
    @SwitchoverCheck
    public R<WxMpUser> getUserInfo(@PathVariable String appid, @PathVariable String openid) {
        try {
            WxMpUser user = wxMpUserService.getUserInfo(openid);
            return R.ok(user);
        } catch (Exception e) {
            log.error("获取用户信息失败: {}", e.getMessage(), e);
            return R.fail("获取用户信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户列表
     *
     * @param appid      公众号appid
     * @param nextOpenid 下一个openid
     * @return 用户列表
     */
    @GetMapping("/list")
    @SwitchoverCheck
    public R<WxMpUserList> getUserList(@PathVariable String appid,
                                       @RequestParam(required = false) String nextOpenid) {
        try {
            return R.ok(wxMpUserService.getUserList(nextOpenid));
        } catch (Exception e) {
            log.error("获取用户列表失败: {}", e.getMessage(), e);
            return R.fail("获取用户列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取所有用户
     *
     * @param appid 公众号appid
     * @return 所有用户openid列表
     */
    @GetMapping("/all")
    @SwitchoverCheck
    public R<List<String>> getAllUsers(@PathVariable String appid) {
        try {
            List<String> allUsers = wxMpUserService.getAllUsers();
            return R.ok(allUsers);
        } catch (Exception e) {
            log.error("获取所有用户失败: {}", e.getMessage(), e);
            return R.fail("获取所有用户失败: " + e.getMessage());
        }
    }

    /**
     * 创建标签
     *
     * @param appid   公众号appid
     * @param tagName 标签名称
     * @return 创建结果
     */
    @PostMapping("/tag/create")
    @SwitchoverCheck
    public R<WxUserTag> createTag(@PathVariable String appid, @RequestParam String tagName) {
        try {
            WxUserTag tag = wxMpUserService.createTag(tagName);
            return R.ok(tag);
        } catch (Exception e) {
            log.error("创建标签失败: {}", e.getMessage(), e);
            return R.fail("创建标签失败: " + e.getMessage());
        }
    }

    /**
     * 获取所有标签
     *
     * @param appid 公众号appid
     * @return 标签列表
     */
    @GetMapping("/tag/list")
    @SwitchoverCheck
    public R<List<WxUserTag>> getTags(@PathVariable String appid) {
        try {
            List<WxUserTag> tags = wxMpUserService.getTags();
            return R.ok(tags);
        } catch (Exception e) {
            log.error("获取标签列表失败: {}", e.getMessage(), e);
            return R.fail("获取标签列表失败: " + e.getMessage());
        }
    }

    /**
     * 更新标签
     *
     * @param appid   公众号appid
     * @param tagId   标签ID
     * @param tagName 新标签名称
     * @return 更新结果
     */
    @PutMapping("/tag/{tagId}")
    @SwitchoverCheck
    public R<Void> updateTag(@PathVariable String appid,
                             @PathVariable Long tagId,
                             @RequestParam String tagName) {
        try {
            boolean result = wxMpUserService.updateTag(tagId, tagName);
            return result ? R.ok() : R.fail("更新标签失败");
        } catch (Exception e) {
            log.error("更新标签失败: {}", e.getMessage(), e);
            return R.fail("更新标签失败: " + e.getMessage());
        }
    }

    /**
     * 删除标签
     *
     * @param appid 公众号appid
     * @param tagId 标签ID
     * @return 删除结果
     */
    @DeleteMapping("/tag/{tagId}")
    @SwitchoverCheck
    public R<Void> deleteTag(@PathVariable String appid, @PathVariable Long tagId) {
        try {
            boolean result = wxMpUserService.deleteTag(tagId);
            return result ? R.ok() : R.fail("删除标签失败");
        } catch (Exception e) {
            log.error("删除标签失败: {}", e.getMessage(), e);
            return R.fail("删除标签失败: " + e.getMessage());
        }
    }

    /**
     * 批量为用户打标签
     *
     * @param appid      公众号appid
     * @param tagId      标签ID
     * @param openidList 用户openid列表
     * @return 操作结果
     */
    @PostMapping("/tag/{tagId}/users")
    @SwitchoverCheck
    public R<Void> batchTagging(@PathVariable String appid,
                                @PathVariable Long tagId,
                                @RequestBody List<String> openidList) {
        try {
            boolean result = wxMpUserService.batchTagging(tagId, openidList);
            return result ? R.ok() : R.fail("批量打标签失败");
        } catch (Exception e) {
            log.error("批量打标签失败: {}", e.getMessage(), e);
            return R.fail("批量打标签失败: " + e.getMessage());
        }
    }

    /**
     * 批量为用户取消标签
     *
     * @param appid      公众号appid
     * @param tagId      标签ID
     * @param openidList 用户openid列表
     * @return 操作结果
     */
    @DeleteMapping("/tag/{tagId}/users")
    @SwitchoverCheck
    public R<Void> batchUntagging(@PathVariable String appid,
                                  @PathVariable Long tagId,
                                  @RequestBody List<String> openidList) {
        try {
            boolean result = wxMpUserService.batchUntagging(tagId, openidList);
            return result ? R.ok() : R.fail("批量取消标签失败");
        } catch (Exception e) {
            log.error("批量取消标签失败: {}", e.getMessage(), e);
            return R.fail("批量取消标签失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户身上的标签列表
     *
     * @param appid  公众号appid
     * @param openid 用户openid
     * @return 用户标签列表
     */
    @GetMapping("/tag/user/{openid}")
    @SwitchoverCheck
    public R<List<Long>> getUserTags(@PathVariable String appid, @PathVariable String openid) {
        try {
            List<Long> userTags = wxMpUserService.getUserTags(openid);
            return R.ok(userTags);
        } catch (Exception e) {
            log.error("获取用户标签失败: {}", e.getMessage(), e);
            return R.fail("获取用户标签失败: " + e.getMessage());
        }
    }

    /**
     * 获取标签下的用户列表
     *
     * @param appid      公众号appid
     * @param tagId      标签ID
     * @param nextOpenid 下一个openid
     * @return 用户列表
     */
    @GetMapping("/tag/{tagId}/users")
    @SwitchoverCheck
    public R<List<String>> getTagUsers(@PathVariable String appid,
                                       @PathVariable Long tagId,
                                       @RequestParam(required = false) String nextOpenid) {
        try {
            List<String> tagUsers = wxMpUserService.getTagUsers(tagId, nextOpenid);
            return R.ok(tagUsers);
        } catch (Exception e) {
            log.error("获取标签用户列表失败: {}", e.getMessage(), e);
            return R.fail("获取标签用户列表失败: " + e.getMessage());
        }
    }
}
