package com.flossom.system.controller;

import javax.servlet.http.HttpServletResponse;

import com.flossom.common.core.domain.R;
import com.flossom.common.core.domain.entity.WxUserInstrument;
import com.flossom.common.core.domain.entity.WxUserMember;
import com.flossom.common.core.domain.entity.WxUserTag;
import com.flossom.common.core.domain.export.WxUserMemberExport;
import com.flossom.common.core.domain.req.*;
import com.flossom.common.core.domain.ret.WxUserMemberRet;
import com.flossom.common.core.enums.IntegralChangeTypeEnum;
import com.flossom.common.core.exception.ServiceException;
import com.flossom.common.core.utils.StringUtils;
import com.flossom.common.core.utils.poi.ExcelUtil;
import com.flossom.common.core.web.controller.BaseController;
import com.flossom.common.core.web.domain.AjaxResult;
import com.flossom.common.core.web.page.TableDataInfo;
import com.flossom.common.log.annotation.Log;
import com.flossom.common.log.enums.BusinessType;
import com.flossom.common.security.annotation.RequiresPermissions;
import com.flossom.system.service.IWxUserMemberService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Array;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户Controller
 *
 * @author flossom
 * @date 2023-12-08
 */
@RestController
@RequestMapping("/member")
public class WxUserMemberController extends BaseController {
    @Autowired
    private IWxUserMemberService wxUserMemberService;

    /**
     * 查询用户列表
     */
    @RequiresPermissions("system:member:list")
    @GetMapping("/list")
    public TableDataInfo list(WxUserMemberVm wxUserMemberVm) {
        startPage();
        List<WxUserMember> list = wxUserMemberService.selectWxUserMemberList(wxUserMemberVm);
        return getDataTable(list);
    }

    /**
     * 查询用户列表
     */
    @GetMapping("/listRet")
    public TableDataInfo listRet(WxUserMemberVm wxUserMemberVm) {
        startPage();
        List<WxUserMemberRet> list = wxUserMemberService.selectWxUserMemberRetList(wxUserMemberVm);
        return getDataTable(list);
    }

    /**
     * 全量导出用户列表
     */
    @RequiresPermissions("system:member:export")
    @Log(title = "用户", businessType = BusinessType.EXPORT)
    @PostMapping("/allExport")
    public void allExport(HttpServletResponse response, WxUserMemberExportVm wxUserMemberExportVm) {
        List<WxUserMemberRet> list = wxUserMemberService.selectWxUserMemberRetList(wxUserMemberExportVm);
        export(response, list, wxUserMemberExportVm.getExportFields());
    }

    /**
     * 批量导出用户列表
     */
    @RequiresPermissions("system:member:export")
    @Log(title = "用户", businessType = BusinessType.EXPORT)
    @PostMapping("/batchExport")
    public void batchExport(HttpServletResponse response, WxUserMemberExportVm wxUserMemberExportVm) {
        List<Integer> userIdList = wxUserMemberExportVm.getUserIdList();
        if (userIdList == null || userIdList.size() == 0) {
            throw new ServiceException("请选择导出用户");
        }
        List<WxUserMemberRet> list = wxUserMemberService.selectWxUserMemberByIdList(wxUserMemberExportVm.getUserIdList());
        export(response, list, wxUserMemberExportVm.getExportFields());
    }

    private static void export(HttpServletResponse response, List<WxUserMemberRet> list, List<String> exportFields) {
        List<WxUserMemberExport> exportList = new ArrayList<>();
        WxUserMemberExport export;
        for (WxUserMemberRet wxUserMemberRet : list) {
            export = new WxUserMemberExport();
            BeanUtils.copyProperties(wxUserMemberRet, export);
            List<WxUserTag> miniProgramTags = wxUserMemberRet.getMiniProgramTags();
            if (miniProgramTags != null && miniProgramTags.size() > 0) {
                export.setMiniProgramTags(miniProgramTags.stream().map(WxUserTag::getTagName).collect(Collectors.joining(",")));
            }
            List<WxUserTag> wecomTags = wxUserMemberRet.getWecomTags();
            if (wecomTags != null && wecomTags.size() > 0) {
                export.setWecomTags(wecomTags.stream().map(WxUserTag::getTagName).collect(Collectors.joining(",")));
            }
            List<WxUserInstrument> instrumentList = wxUserMemberRet.getInstrumentList();
            if (instrumentList != null && instrumentList.size() > 0) {
                export.setDevicesName(instrumentList.stream().map(WxUserInstrument::getInstrumentName).collect(Collectors.joining(",")));
            }
            exportList.add(export);
        }
        ExcelUtil<WxUserMemberExport> util = new ExcelUtil(WxUserMemberExport.class);
        util.exportExcel(response, exportList, "用户数据", exportFields);
    }

    /**
     * 获取用户详细信息
     */
    @RequiresPermissions("system:member:query")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(wxUserMemberService.selectWxUserMemberById(id));
    }

    /**
     * 新增用户
     */
    @RequiresPermissions("system:member:add")
    @Log(title = "用户", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody WxUserMember wxUserMember) {
        return toAjax(wxUserMemberService.insertWxUserMember(wxUserMember));
    }

    /**
     * 修改用户
     */
    @RequiresPermissions("system:member:edit")
    @Log(title = "用户", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody WxUserMemberReq wxUserMember) {
        return toAjax(wxUserMemberService.updateWxUserMember(wxUserMember));
    }

    /**
     * 删除用户
     */
//    @RequiresPermissions("system:member:remove")
    @Log(title = "用户", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(wxUserMemberService.deleteWxUserMemberByIds(ids));
    }

    /**
     * 查询用户总数，已注册用户，已绑定仪器用户数
     */
    @GetMapping("/selectUserCount")
    public R selectUserCount() {
        return R.ok(wxUserMemberService.selectUserCount());
    }

    /**
     * 批量 添加小程序标签
     */
    @PostMapping("/batchAddMiniProgramTag")
    public R batchAddMiniProgramTag(@RequestParam("tagIdList") List<Integer> tagIdList,
                                    @RequestParam("userIdList") List<Integer> userIdList) {
        if (tagIdList == null || tagIdList.size() == 0) {
            logger.error("参数有误");
            throw new ServiceException("参数有误");
        }
        wxUserMemberService.batchAddMiniProgramTag(tagIdList, userIdList);
        return R.ok();
    }

    /**
     * 全量添加小程序标签
     */
    @PostMapping("/allAddMiniProgramTag")
    public R allAddMiniProgramTag(@RequestParam("tagIdList") List<Integer> tagIdList, @RequestBody WxUserMemberVm wxUserMemberVm) {
        if (tagIdList == null || tagIdList.size() == 0) {
            logger.error("参数有误");
            throw new ServiceException("参数有误");
        }
        List<WxUserMember> list = wxUserMemberService.selectWxUserMemberList(wxUserMemberVm);
        if (list != null && list.size() > 0) {
            List<Integer> collect = list.stream().map(wxUserMember -> wxUserMember.getId().intValue()).collect(Collectors.toList());
            wxUserMemberService.batchAddMiniProgramTag(tagIdList, collect);
        }
        return R.ok();
    }

    /**
     * 批量 删除小程序标签
     */
    @PostMapping("/batchDelMiniProgramTag")
    public R batchDelMiniProgramTag(@RequestParam("tagIdList") List<Integer> tagIdList,
                                    @RequestParam(value = "userIdList") List<Integer> userIdList) {
        if (tagIdList == null || tagIdList.size() == 0
                || userIdList == null || userIdList.size() == 0) {
            logger.error("参数有误");
            throw new ServiceException("参数有误");
        }
        wxUserMemberService.batchDelMiniProgramTag(tagIdList, userIdList);
        return R.ok();
    }

    /**
     * 全量 删除小程序标签
     */
    @PostMapping("/allDelMiniProgramTag")
    public R allDelMiniProgramTag(@RequestParam("tagIdList") List<Integer> tagIdList, @RequestBody WxUserMemberVm wxUserMemberVm) {
        if (tagIdList == null || tagIdList.size() == 0) {
            logger.error("参数有误");
            throw new ServiceException("参数有误");
        }
        List<WxUserMember> list = wxUserMemberService.selectWxUserMemberList(wxUserMemberVm);
        if (list != null && list.size() > 0) {
            List<Integer> collect = list.stream().map(wxUserMember -> wxUserMember.getId().intValue()).collect(Collectors.toList());
            wxUserMemberService.batchDelMiniProgramTag(tagIdList, collect);
        }
        return R.ok();
    }

    /**
     * 批量 操作积分
     */
    @PostMapping("/batchChangIntegral")
    public R batchChangIntegral(@Validated @RequestBody WxUserIntegralVm wxUserIntegralVm, @RequestParam(value = "userIdList") List<Long> userIdList) {
        if (userIdList == null || userIdList.size() == 0
                || !IntegralChangeTypeEnum.isIntegralChangType(wxUserIntegralVm.getSource())) {
            logger.error("积分操作类型选择有误");
            throw new ServiceException("积分操作类型选择有误");
        }
        wxUserMemberService.batchChangIntegral(wxUserIntegralVm, userIdList);
        return R.ok();
    }

    /**
     * 全量 操作积分
     */
    @PostMapping("/allChangIntegral")
    public R allChangIntegral(@Validated @RequestBody AllChangIntegralOperateReq operateReq) {
        if (!IntegralChangeTypeEnum.isIntegralChangType(operateReq.getWxUserIntegralVm().getSource())) {
            logger.error("积分操作类型选择有误");
            throw new ServiceException("积分操作类型选择有误");
        }
        List<WxUserMember> list = wxUserMemberService.selectWxUserMemberList(operateReq.getWxUserMemberVm());
        if (list != null && list.size() > 0) {
            List<Long> collect = list.stream().map(wxUserMember -> wxUserMember.getId()).collect(Collectors.toList());
            wxUserMemberService.batchChangIntegral(operateReq.getWxUserIntegralVm(), collect);
        }
        return R.ok();
    }

    /**
     * 开启或者禁止打卡
     */
    @GetMapping("/openOrCloseClock/{id}")
    public R openOrCloseClock(@PathVariable Long id) {
        if (id == null) {
            return R.fail("id 不能为空");
        }
        wxUserMemberService.openOrCloseClock(id);
        return R.ok();
    }

    /**
     * 开启或者禁止活动
     */
    @GetMapping("/openOrCloseActivity/{id}")
    public R openOrCloseActivity(@PathVariable Long id) {
        if (id == null) {
            return R.fail("id 不能为空");
        }
        wxUserMemberService.openOrCloseActivity(id);
        return R.ok();
    }

}
