package com.ylx.web.controller.massage;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ylx.common.core.domain.R;
import com.ylx.common.core.domain.model.LoginUser;
import com.ylx.common.core.domain.model.aliyun.SMSVerificationCode;
import com.ylx.common.core.domain.model.aliyun.SendSmsComponents;
import com.ylx.common.core.domain.model.aliyun.SendSmsEnum;
import com.ylx.common.utils.StringUtils;
import com.ylx.massage.domain.MaProject;
import com.ylx.massage.domain.dto.MaProjectSaveDto;
import com.ylx.massage.domain.dto.MaProjectUpdateDto;
import com.ylx.massage.domain.dto.MaTechnicianAuditQueryDTO;
import com.ylx.massage.domain.dto.MaTechnicianMerchantAddDTO;
import com.ylx.massage.domain.dto.MaTechnicianMerchantQueryDTO;
import com.ylx.massage.domain.vo.*;
import com.ylx.massage.service.IMaProjectService;
import com.ylx.project.domain.Project;
import com.ylx.servicecategory.domain.ServiceCategory;
import com.ylx.servicecategory.service.ServiceCategoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import com.ylx.common.annotation.Log;
import com.ylx.common.core.controller.BaseController;
import com.ylx.common.core.domain.AjaxResult;
import com.ylx.common.enums.BusinessType;
import com.ylx.massage.domain.MaTechnician;
import com.ylx.massage.service.IMaTechnicianService;
import com.ylx.common.utils.poi.ExcelUtil;
import com.ylx.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 技师Controller
 *
 * @author ylx
 * @date 2024-03-22
 */
@Api("技师管理")
@RestController
@RequestMapping("/technician/technician")
public class MaTechnicianController extends BaseController {
    @Autowired
    private IMaTechnicianService maTechnicianService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private SendSmsComponents sendSms;
    @Autowired
    private ServiceCategoryService serviceCategoryService;
    @Autowired
    private IMaProjectService maProjectService;

    public static final String PHONE_THREEUSERPARTCLIENT_CODE_KEY = "sys:threeUserPartClient:phone:";

    @GetMapping("/sendMsg")
    @ApiOperation(value = "短信发送", notes = "短信发送")
    public Result sendMsg(@RequestParam String phone, HttpServletRequest request) {
        if (org.apache.commons.lang3.StringUtils.isEmpty(phone)) {
            return Result.error("手机号不能为空");
        }
        Random rand = new Random();
        // randNumber 将被赋值为一个 MIN 和 MAX 范围内的随机数
        int randNumber = rand.nextInt(9999 - 1000 + 1) + 1000;
        // 保存验证码到redis
        redisTemplate.opsForValue()
                .set("userH5:order:phone:" + phone, String.valueOf(randNumber), 5L
                        , TimeUnit.MINUTES);
        try {
            SMSVerificationCode smsVerificationCode = new SMSVerificationCode(String.valueOf(randNumber));
            String jsonString = JSON.toJSONString(smsVerificationCode);
            sendSms.sendSms(phone, SendSmsEnum.SMS_220650024, jsonString);
            return Result.ok("发送成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.ok("发送失败");
    }

    /**
     * 商户登录接口
     *
     * @param thirdPartyLoginsVo
     * @return
     */
    @ApiOperation(value = "商户登录", notes = "商户登录")
    @PostMapping(value = "/clientLogin")
    @Transactional
    public Result<JSONObject> login(@RequestBody ThirdPartyLoginsVo thirdPartyLoginsVo) throws Exception {
        // 获取登录用户信息
        Result<JSONObject> result = new Result<>();

        // 校验手机号是否为空
        if (StringUtils.isEmpty(thirdPartyLoginsVo.getPhone())) {
            return result.error500("请输入手机号");
        }

        // 校验用户是否存在且有效
        LambdaQueryWrapper<MaTechnician> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaTechnician::getTePhone, thirdPartyLoginsVo.getPhone());
        MaTechnician maTechnician = maTechnicianService.getBaseMapper().selectOne(queryWrapper);
        // 校验用户是否有效
        if (ObjectUtils.isEmpty(maTechnician)) {
            return result.error500("商户不存在,请先注册");

        }

        if (thirdPartyLoginsVo.getCodeSwitch()) {
            // 短信验证
            String msg = redisTemplate.opsForValue().get(PHONE_THREEUSERPARTCLIENT_CODE_KEY + thirdPartyLoginsVo.getPhone());
            if (StringUtils.isEmpty(msg)) {
                return Result.error("验证码已失效");
            }

            if (!thirdPartyLoginsVo.getPhoneMsg().equals(msg)) {
                return Result.error("短信验证码不正确");
            }
        } else {
            if (!thirdPartyLoginsVo.getPassWord().equals(maTechnician.getTePassword())) {
                return Result.error("密码错误");
            }

        }

        // 登录成功删除验证码
        redisTemplate.delete(PHONE_THREEUSERPARTCLIENT_CODE_KEY + thirdPartyLoginsVo.getPhone());
        result.success("登录成功");
        return result;
    }

    /**
     * 商户忘记密码接口
     */
    @PostMapping("/resetPassword")
    public Result<?> resetPassword(@RequestBody ThirdPartyLoginsVo thirdPartyLoginsVo) {
        // 核心正则表达式：
        // ^ 表示开头，$ 表示结尾
        // [a-zA-Z0-9] 表示只能是字母或数字
        // {8,20} 表示长度必须在8到20之间
        String regex = "^[a-zA-Z0-9]{8,20}$";
        boolean isMatch = Pattern.matches(regex, thirdPartyLoginsVo.getPhoneMsg());
        if (!isMatch) {
            // 根据需求返回指定的异常提示
            return Result.error("请输入8-20位数字/字母组合");
        }
        // 短信验证
        String msg = redisTemplate.opsForValue().get(PHONE_THREEUSERPARTCLIENT_CODE_KEY + thirdPartyLoginsVo.getPhone());
        if (StringUtils.isEmpty(msg)) {
            return Result.error("验证码已失效");
        }
        if (!thirdPartyLoginsVo.getPhoneMsg().equals(msg)) {
            return Result.error("短信验证码不正确");
        }
        // 重置密码逻辑
        LambdaUpdateWrapper<MaTechnician> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(MaTechnician::getTePhone, thirdPartyLoginsVo.getPhone());
        updateWrapper.set(MaTechnician::getTePassword, thirdPartyLoginsVo.getPassWord());
        maTechnicianService.update(updateWrapper);
        redisTemplate.delete(PHONE_THREEUSERPARTCLIENT_CODE_KEY + thirdPartyLoginsVo.getPhone());
        return Result.ok("重置密码成功");
    }

    /**
     * 商户入驻申请接口
     */
    @PostMapping("/apply")
    public Result<?> apply(@RequestBody MaTechnicianAppAddVo req) {
        // 1. 基础参数校验
        if (StringUtils.isAnyBlank(req.getTeName(), req.getTePhone(), req.getTeAddress(), req.getAvatar())) {
            return Result.error("必填项不能为空");
        }
        //校验性别不能为空
        if(Objects.isNull(req.getTeSex())){
            return Result.error("性别不能为空");
        }
        // 2. 调用业务层处理入驻申请
        maTechnicianService.apply(req);
        return Result.ok("提交成功，进入审核流程");
    }

    /**
     * 查询商户信息接口
     */
    @GetMapping("/getTechnician")
    public Result<?> getTechnician(@RequestParam String phone) {
        LambdaQueryWrapper<MaTechnician> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaTechnician::getTePhone, phone);
        MaTechnician maTechnician = maTechnicianService.getBaseMapper().selectOne(queryWrapper);
        return Result.ok(maTechnician);
    }

    /**
     * 修改和上传商户信息接口
     */
    @PostMapping("/updateTechnician")
    public Result<?> updateTechnician(@RequestBody MaTechnicianAppAddVo req) {
        if (req.getAuditStatus() == 0 || req.getAuditStatus() == 3) {
            //修改基本信息
            updateMaTechnician(req);
        } else if (req.getAuditStatus() == 1 || req.getAuditStatus() == 2) {
            //上传商户资料信息
            extractedUpdate(req);
        }
        return Result.ok("修改成功");
    }

    private void extractedUpdate(MaTechnicianAppAddVo req) {
        LambdaUpdateWrapper<MaTechnician> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(MaTechnician::getId, req.getId());
        updateWrapper.set(MaTechnician::getTeAvatar, req.getTeAvatar());
        updateWrapper.set(MaTechnician::getTeNickName, req.getTeNickName());
        updateWrapper.set(MaTechnician::getTeBrief, req.getTeBrief());
        updateWrapper.set(MaTechnician::getLifePhotos, req.getLifePhotos());
        updateWrapper.set(MaTechnician::getIdCard, req.getIdCard());
        updateWrapper.set(MaTechnician::getHealthCertificate, req.getHealthCertificate());
        updateWrapper.set(MaTechnician::getQualificationCertificate, req.getQualificationCertificate());
        updateWrapper.set(MaTechnician::getNoCrimeRecord, req.getNoCrimeRecord());
        updateWrapper.set(MaTechnician::getPromoVideo, req.getPromoVideo());
        updateWrapper.set(MaTechnician::getCommitmentAudio, req.getCommitmentAudio());
        updateWrapper.set(MaTechnician::getCommitmentPdf, req.getCommitmentPdf());
        updateWrapper.set(MaTechnician::getCommitmentVideo, req.getCommitmentVideo());
        maTechnicianService.update(updateWrapper);
    }

    private void updateMaTechnician(MaTechnicianAppAddVo req) {
        LambdaUpdateWrapper<MaTechnician> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(MaTechnician::getId, req.getId());
        updateWrapper.set(MaTechnician::getTePhone, req.getTePhone());
        updateWrapper.set(MaTechnician::getTeName, req.getTeName());
        updateWrapper.set(MaTechnician::getOpenService, req.getOpenService());
        updateWrapper.set(MaTechnician::getTeAddress, req.getTeAddress());
        updateWrapper.set(MaTechnician::getTeAge, req.getTeAge());
        updateWrapper.set(MaTechnician::getAvatar, req.getAvatar());
        maTechnicianService.update(updateWrapper);
    }

    /**
     * 查询技师列表
     */
    @PreAuthorize("@ss.hasPermi('technician:technician:list')")
    @GetMapping("/list")
    public TableDataInfo list(MaTechnician maTechnician) {
        startPage();
        List<MaTechnician> list = maTechnicianService.selectMaTechnicianList(maTechnician);
        return getDataTable(list);
    }

    /**
     * 导出技师列表
     */
    @PreAuthorize("@ss.hasPermi('technician:technician:export')")
    @Log(title = "技师", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, MaTechnician maTechnician) {
        List<MaTechnician> list = maTechnicianService.selectMaTechnicianList(maTechnician);
        ExcelUtil<MaTechnician> util = new ExcelUtil<MaTechnician>(MaTechnician.class);
        util.exportExcel(response, list, "技师数据");
    }

    /**
     * 获取技师详细信息
     */
    @PreAuthorize("@ss.hasPermi('technician:technician:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(maTechnicianService.selectMaTechnicianById(id));
    }

    /**
     * 新增技师
     */
    @ApiOperation("技师入驻")
    @PreAuthorize("@ss.hasPermi('technician:technician:add')")
    @Log(title = "技师", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody MaTechnicianAppAddVo maTechnicianAppAddVo) {
        return toAjax(maTechnicianService.insertMaTechnician(maTechnicianAppAddVo));
    }

    /**
     * 后台新增商户
     *
     * @param dto 商户新增DTO
     * @return AjaxResult 结果
     */
    @ApiOperation("后台新增商户")
    @PreAuthorize("@ss.hasPermi('technician:technician:add')")
    @Log(title = "商户", businessType = BusinessType.INSERT)
    @PostMapping("/merchant")
    public AjaxResult addMerchant(@RequestBody MaTechnicianMerchantAddDTO dto) {
        try {
            LoginUser loginUser = getLoginUser();
            return toAjax(maTechnicianService.insertMerchant(dto, loginUser));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 后台编辑商户
     *
     * @param id  商户ID
     * @param dto 商户编辑DTO
     * @return AjaxResult 结果
     */
    @ApiOperation("后台编辑商户")
    @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
    @Log(title = "商户", businessType = BusinessType.UPDATE)
    @PutMapping("/merchant/{id}")
    public AjaxResult editMerchant(@PathVariable("id") Long id, @RequestBody MaTechnicianMerchantAddDTO dto) {
        try {
            LoginUser loginUser = getLoginUser();
            return toAjax(maTechnicianService.updateMerchant(id, dto, loginUser));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 后台上传商户合同文件
     *
     * @param id   商户ID
     * @param file 合同文件
     * @return AjaxResult 上传结果
     */
    @ApiOperation("后台上传商户合同文件")
    @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
    @Log(title = "商户合同", businessType = BusinessType.UPDATE)
    @PostMapping("/merchant/{id}/contract")
    public AjaxResult uploadMerchantContract(@PathVariable("id") Integer id, @RequestParam("file") MultipartFile file) {
        try {
            LoginUser loginUser = getLoginUser();
            return maTechnicianService.uploadMerchantContract(id, file, loginUser);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询商户入驻审核列表
     *
     * @param page 分页参数
     * @param dto  查询条件
     * @return Page 商户入驻审核分页列表
     */
    @ApiOperation("后台查询商户入驻审核列表")
    @PreAuthorize("@ss.hasPermi('technician:technician:list')")
    @GetMapping("/merchant/audit/list")
    public R<Page<MaTechnicianAuditListVO>> merchantAuditList(Page<MaTechnicianAuditListVO> page, MaTechnicianAuditQueryDTO dto) {
        try {
            return R.ok(maTechnicianService.selectMerchantAuditList(page, dto));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询商户列表
     *
     * @param page 分页参数
     * @param dto  商户查询DTO
     * @return Page 商户分页列表
     */
    @ApiOperation("后台查询商户列表")
    @PreAuthorize("@ss.hasPermi('technician:technician:list')")
    @GetMapping("/merchant/list")
    public R<Page<MaTechnicianMerchantListVO>> merchantList(Page<MaTechnicianMerchantListVO> page, MaTechnicianMerchantQueryDTO dto) {
        try {
            return R.ok(maTechnicianService.selectMerchantList(page, dto));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询商户详情
     *
     * @param id 商户ID
     * @return R<MaTechnicianMerchantDetailVO> 商户详情
     */
    @ApiOperation("后台查询商户详情")
    @PreAuthorize("@ss.hasPermi('technician:technician:query')")
    @GetMapping("/merchant/detail/{id}")
    public R<MaTechnicianMerchantDetailVO> merchantDetail(@PathVariable("id") Long id) {
        try {
            return R.ok(maTechnicianService.selectMerchantDetail(id));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 修改技师
     */
    @PreAuthorize("@ss.hasPermi('technician:technician:edit')")
    @Log(title = "技师", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody MaTechnicianAppAddVo maTechnicianAppAddVo) {
        return toAjax(maTechnicianService.updateMaTechnician(maTechnicianAppAddVo));
    }

    /**
     * 删除技师
     */
    @PreAuthorize("@ss.hasPermi('technician:technician:remove')")
    @Log(title = "技师", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(maTechnicianService.deleteMaTechnicianByIds(ids));
    }

    /**
     * 1. 获取服务类目列表 (对应图1、图3)
     */
    @GetMapping("/getServiceCategoryList")
    public AjaxResult getServiceCategoryList() {
        List<ServiceCategory> list = serviceCategoryService.listH5ServiceCategory();
        return AjaxResult.success(list);
    }

    /**
     * 1. 获取技能列表 (对应图1、图3)
     * 支持 Tab 切换：all(全部), active(已开通), applying(申请中), rejected(驳回)
     */
    @PostMapping("/getSkillList")
    public TableDataInfo getSkillList(@RequestBody MaProjectGetVo req) {
        startPage();
        List<MaProject> list = maTechnicianService.selectMaTechnicianListBy(req.getUserId(), req.getAuditStatus());
        if (ObjectUtils.isEmpty(list)) {
            List<Project> projectslist = maTechnicianService.selectTechnicianListBy(req.getTypeId());
            return getDataTable(projectslist);
        } else {
            return getDataTable(list);
        }
    }

    /**
     * 查询未开通的服务项目列表
     *
     * @param req
     * @return
     */
    @PostMapping("/getNotApplyList")
    public Result<?> getNotApplyList(@RequestBody MaProjectGetVo req) {

        return Result.ok(maTechnicianService.getNotApplyList(req.getUserId(), req.getTypeId()));

    }

    /**
     * 申请开通新服务
     */
    @PostMapping("/applyForService")
    public AjaxResult applyForService(@RequestBody MaProjectSaveDto dto) {

        return toAjax(maTechnicianService.applyForService(dto));
    }

    /**
     * 重新申请开通新服务
     *
     * @param req
     * @return
     */
    @PostMapping("/updateApply")
    public Result<?> updateApply(@RequestBody MaProjectUpdateDto req) {
        if (StringUtils.isNotEmpty(req.getProjectId()) && StringUtils.isNotEmpty(req.getApplyReason())) {
            LambdaUpdateWrapper<MaProject> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(MaProject::getId, req.getProjectId());
            updateWrapper.set(MaProject::getApplyReason, req.getApplyReason());
            updateWrapper.set(MaProject::getAuditStatus, 0);
            maProjectService.update(updateWrapper);
        }
        return Result.ok("重新申请成功,提交到审核阶段");

    }

    /**
     * 申请下架,删除服务项目,编辑售价价格
     *
     * @param req
     * @return
     */
    @PostMapping("/updateMaProject")
    public Result<?> updateMaProject(@RequestBody MaProjectUpdateDto req) {
        String message = "";
        if (StringUtils.isNotEmpty(req.getProjectId())) {
            if (req.getIsDelete()) {
                LambdaUpdateWrapper<MaProject> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(MaProject::getId, req.getProjectId());
                updateWrapper.set(MaProject::getIsDelete, 1);
                maProjectService.update(updateWrapper);
                message = "删除成功";
            }
            if (req.getIsPass()) {
                LambdaUpdateWrapper<MaProject> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(MaProject::getId, req.getProjectId());
                updateWrapper.set(MaProject::getProjectIsEnable, 1);
                maProjectService.update(updateWrapper);
                message = "申请下架成功";
            }
            if (req.getProjectCurrentPrice() != null) {

                LambdaUpdateWrapper<MaProject> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(MaProject::getId, req.getProjectId());
                updateWrapper.set(MaProject::getProjectCurrentPrice, req.getProjectCurrentPrice());
                maProjectService.update(updateWrapper);
                message = "修改价格完成";

            }
        }
        return Result.ok(message);
    }

}
