package shop.alien.store.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import shop.alien.entity.result.R;
import shop.alien.entity.store.StoreImg;
import shop.alien.entity.store.StoreUser;
import shop.alien.entity.store.vo.StoreInfoVo;
import shop.alien.entity.store.vo.StoreUserVo;
import shop.alien.mapper.StoreImgMapper;
import shop.alien.mapper.StoreUserMapper;
import shop.alien.store.service.StoreInfoService;
import shop.alien.store.service.StoreUserService;

import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * 门店用户 前端控制器
 *
 * @author ssk
 * @since 2024-12-11
 */
@Slf4j
@Api(tags = {"二期-门店用户"})
@ApiSort(8)
@CrossOrigin
@RestController
@RequestMapping("/store/user")
@RequiredArgsConstructor
public class StoreUserController {

    private final StoreUserService storeUserService;
    private final StoreUserMapper storeUserMapper;
    private final StoreInfoService storeInfoService;
    private final StoreImgMapper storeImgMapper;

    @ApiOperation("门店用户登录")
    @ApiOperationSupport(order = 1)
    @ApiImplicitParams({@ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "password", value = "密码", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "isPassword", value = "是否密码登录", dataType = "Boolean", paramType = "query", required = true)})
    @GetMapping("/login")
    public R<StoreUserVo> login(String phone, String password,
                                @RequestParam(defaultValue = "true", required = false) Boolean isPassword) {
        log.info("StoreUserController.login?phone={}&password={}&isPassword={}", phone, password, isPassword);
        StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>()
                .eq(StoreUser::getPhone, phone));
        if (null == storeUser) {
            return R.fail("当前账号不存在，请先去注册账号！");
        }
        if (storeUser.getStatus() == 1) {
            return R.fail("账号被禁用");
        }
        return Optional.ofNullable(storeUser).
                map(user -> isPassword ? checkPassword(user, password) : storeUserService.createToKen(user)).
                orElseGet(() -> R.fail("手机号不存在"));
    }

    /**
     * 校验商户端账号是否禁用
     *
     * @param accountId
     * @return
     */
    @ApiOperation("校验账号是否被禁用")
    @ApiOperationSupport(order = 1)
    @ApiImplicitParams({@ApiImplicitParam(name = "accountId", value = "账号id", dataType = "Integer", paramType = "query", required = true)})
    @GetMapping("/checkAccount")
    private R<StoreUserVo> checkAccount(Integer accountId) {
        return storeUserService.getById(accountId).getStatus() != 1 ? R.success("账号正常")
                : R.fail("账号禁用");
    }

    /**
     * checkPwd
     *
     * @param user
     * @param password
     * @return
     */
    private R<StoreUserVo> checkPassword(StoreUser user, String password) {
        return Objects.equals(password, user.getPassword())
                ? storeUserService.createToKen(user)
                : R.fail("密码错误");
    }

    @ApiOperation("修改密码/忘记密码/更换绑定手机号")
    @ApiOperationSupport(order = 2)
    @ApiImplicitParams({@ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "newPhone", value = "新手机号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "oldPassword", value = "旧密码", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "newPassword", value = "新密码", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "confirmNewPassword", value = "新密码确认", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "verificationCode", value = "验证码", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "type", value = "类型:0:忘记密码,1:修改密码,2:更换绑定手机号", dataType = "Integer", paramType = "query", required = true)})
    @GetMapping("/updatePassword")
    public R<String> updatePassword(String phone,String newPhone, String oldPassword, String newPassword, String confirmNewPassword,String verificationCode, Integer type) {
        log.info("StoreUserController.updatePassword?phone={}&newPhone&oldPassword={}&newPassword={}&confirmNewPassword={}&verificationCode={}&type={}", phone, newPhone, oldPassword, newPassword, confirmNewPassword, verificationCode, type);
        return  storeUserService.forgetOrModifyPassword(phone, newPhone, oldPassword, newPassword, confirmNewPassword, verificationCode, type);
    }

    @ApiOperation("更换绑定手机号效验原密码或验证码")
    @ApiOperationSupport(order = 2)
    @ApiImplicitParams({@ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "oldPassword", value = "旧密码", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "verificationCode", value = "验证码", dataType = "String", paramType = "query")})
    @GetMapping("/changePhoneVerification")
    public R<Map<String, String>> changePhoneVerification(String phone, String oldPassword, String verificationCode) {
        log.info("StoreUserController.changePhoneVerification?phone={}&oldPassword={}&verificationCode={}", phone,  oldPassword,  verificationCode);
        return R.data(storeUserService.changePhoneVerification(phone, oldPassword, verificationCode));

    }

    @ApiOperation("修改用户信息")
    @ApiOperationSupport(order = 3)
    @PostMapping("/setUserInfo")
    public R<Boolean> setUserInfo(@RequestBody StoreUser storeUserVo) {
        log.info("StoreUserController.setUserInfo?storeUserVo={}", storeUserVo);
        if (storeUserService.setUserInfo(storeUserVo)) {
            return R.success("修改成功");
        }
        return R.fail("修改失败");
    }

    @ApiOperation("根据手机号获取用户")
    @ApiOperationSupport(order = 4)
    @ApiImplicitParams({@ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query", required = true)})
    @GetMapping("/getUserByPhone")
    public R<StoreUser> getUserByPhone(String phone) {
        log.info("StoreUserController.getUserInfo?phone={}", phone);
        StoreUser storeUser = storeUserService.getUserByPhone(phone);
        if (null != storeUser) {
            return R.data(storeUser);
        }
        return R.fail("手机号不存在");
    }

    @ApiOperation("修改支付密码")
    @ApiOperationSupport(order = 5)
    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "主键", dataType = "String", paramType = "query", required = true), @ApiImplicitParam(name = "payPassword", value = "支付密码", dataType = "String", paramType = "query", required = true)})
    @GetMapping("/setPayPassword")
    public R<Boolean> setPayPassword(Integer id, String payPassword) {
        if (storeUserService.setPayPassword(id, payPassword)) {
            return R.success("修改成功");
        }
        return R.fail("修改失败");
    }

    @ApiOperation("修改用户状态")
    @ApiOperationSupport(order = 6)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "type", value = "修改类型 (pass:密码状态改为1, face:人脸状态改为2)", dataType = "String", paramType = "query", required = true)
    })
    @GetMapping("/updateUserStatus")
    public R<StoreUser> updateUserStatus(String phone, String type) {
        log.info("StoreUserController.updateUserStatus?phone={}&type={}", phone, type);
        if (storeUserService.updateUserStatus(phone, type)) {
            return R.success("修改成功");
        }
        return R.fail("修改失败");
    }

    @ApiOperation("修改商户信息")
    @ApiOperationSupport(order = 7)
    @PostMapping("/setStoreUserInfo")
    public R<Boolean> setStoreUserInfo(@RequestBody StoreInfoVo storeInfo) {
        log.info("StoreUserController.setStoreUserInfo?storeInfo={}", storeInfo);

        // 查询店铺图片信息
        LambdaQueryWrapper<StoreImg> queryWrapper = new LambdaQueryWrapper<StoreImg>()
                .eq(StoreImg::getImgType, 10)
                .eq(StoreImg::getStoreId, storeInfo.getId());
        StoreImg storeImg = storeImgMapper.selectOne(queryWrapper);

        // 如果查询到店铺图片信息，则更新图片 URL
        if (storeImg != null) {
            storeImg.setImgUrl(storeInfo.getImgUrl());
            int imgUpdateResult = storeImgMapper.updateById(storeImg);
            if (imgUpdateResult == 0) {
                log.error("更新店铺图片信息失败，storeInfo: {}", storeInfo);
                return R.fail("修改失败，更新店铺图片信息失败");
            }
        } else {
            StoreImg storeImg1 = new StoreImg();
            storeImg1.setStoreId(storeInfo.getId());
            storeImg1.setImgType(10);
            storeImg1.setImgUrl(storeInfo.getImgUrl());
            storeImg1.setImgSort(0);
            int insert = storeImgMapper.insert(storeImg1);
            if (insert == 0) {
                log.error("添加店铺图片信息失败，storeInfo: {}", storeInfo);
                return R.fail("添加失败，添加店铺图片信息失败");
            }
        }

        // 更新店铺信息
        boolean infoUpdateResult = storeInfoService.updateById(storeInfo);
        if (!infoUpdateResult) {
            log.error("更新店铺信息失败，storeInfo: {}", storeInfo);
            return R.fail("修改失败，更新店铺信息失败");
        }

        // 所有更新操作成功，返回成功信息
        return R.success("修改成功");

    }

    /**
     * web端查询用户列表
     */
    @ApiOperation("web端查询用户列表")
    @ApiOperationSupport(order = 7)
    @GetMapping("/getStoreUserList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "页容", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "storeName", value = "门店名称", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "storeContact", value = "门店联系人", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "storePhone", value = "门店电话", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "storeType", value = "门店类型", dataType = "String", paramType = "query")
    })
    public R<IPage<StoreUserVo>> getStoreUserList(@RequestParam(defaultValue = "1") int pageNum,
                                                  @RequestParam(defaultValue = "10") int pageSize,
                                                  @RequestParam(required = false) String id,
                                                  @RequestParam(required = false) String phone,
                                                  @RequestParam(required = false) Integer status) {
        log.info("StoreInfoController.getStoreUserList?pageNum={},pageSize={},id={},phone={},status={}", pageNum, pageSize, id, phone, status);
        R<IPage<StoreUserVo>> storeUserVoR = storeUserService.getStoreUserList(pageNum, pageSize, id, phone, status);
        return storeUserVoR;
    }

    /**
     * web端新增商家端用户
     */
    @ApiOperation("web端新增商家端用户")
    @ApiOperationSupport(order = 7)
    @PostMapping("/addStoreUser")
    public R<StoreUserVo> addStoreUser(@RequestBody StoreUserVo storeUserVo) {
        log.info("StoreUserController.addStoreUser?storeUserVo={}", storeUserVo);
        R<StoreUserVo> storeUserVoR = storeUserService.addStoreUser(storeUserVo);
        return storeUserVoR;
    }

    /**
     * web端编辑商家端用户
     */
    @ApiOperation("web端编辑商家端用户")
    @ApiOperationSupport(order = 7)
    @PostMapping("/editStoreUser")
    public R<StoreUserVo> editStoreUser(@RequestBody StoreUser storeUser) {
        log.info("StoreUserController.editStoreUser?storeUser={}", storeUser);
        R<StoreUserVo> storeUserVoR = storeUserService.editStoreUser(storeUser);
        return storeUserVoR;
    }

    /**
     * web端重置商家端用户密码
     */
    @ApiOperation("web端编辑商家端用户")
    @ApiOperationSupport(order = 7)
    @PutMapping("/resetStoreUserPassword")
    public R<StoreUserVo> resetStoreUserPassword(@RequestBody StoreUser storeUser) {
        log.info("StoreUserController.resetStoreUserPassword?storeUser={}", storeUser);
        storeUserService.resetStoreUserPassword(storeUser);
        return R.success("初始化成功");
    }

    /**
     * web端删除商家端用户
     */
    @ApiOperation("web端删除商家端用户")
    @ApiOperationSupport(order = 7)
    @DeleteMapping("/deleteStoreUser")
    public R<StoreUserVo> deleteStoreUser(@RequestParam(value = "id") String id) {
        log.info("StoreUserController.deleteStoreUser?id={}", id);
        return storeUserService.deleteStoreUser(id);
    }

    /**
     * web端切换商家端用户
     */
    @ApiOperation("web端切换商家端用户")
    @ApiOperationSupport(order = 7)
    @PutMapping("/switchingStates")
    public R<StoreUserVo> switchingStates(@RequestBody StoreUser storeUser) {
        log.info("StoreUserController.switchingStates?storeUser={}", storeUser);
        storeUserService.switchingStates(storeUser);
        return R.success("切换成功");
    }

    @ApiOperation(value = "web端导出商家端账号相关信息")
    @ApiOperationSupport(order = 6)
    @GetMapping("/exportExcel")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户id", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "phone", value = "联系电话", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "状态", dataType = "String", paramType = "query"),
    })
    @ResponseBody
    public R exportExcel(@RequestParam(value = "id", required = false) String id
            , @RequestParam(value = "phone", required = false) String phone
            , @RequestParam(value = "status", required = false) String status) throws IOException {
        log.info("StoreInfoController.exportExcel");
        String excelPath = storeUserService.exportExcel(id, phone, status);
        return R.data(excelPath);
    }


    /**
     * register
     *
     * @param phone
     * @param password
     * @return
     */
    @ApiOperation("门店用户注册")
    @ApiOperationSupport(order = 7)
    @ApiImplicitParams({@ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "password", value = "密码", dataType = "String", paramType = "query", required = true)})
    @GetMapping("/register")
    public R<Boolean> register(String phone, String password) {
        log.info("StoreUserController.register?phone={}&password={}", phone, password);
        return storeUserService.register(phone, password);
    }


    /**
     * register
     *
     * @param phone
     * @return
     */
    @ApiOperation("门店用户注册校验")
    @ApiOperationSupport(order = 8)
    @ApiImplicitParams({@ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query", required = true)})
    @GetMapping("/checkRegister")
    public R<Boolean> checkRegister(String phone) {
        log.info("StoreUserController.register?phone={}", phone);
        Boolean res = storeUserService.checkRegister(phone);
        return R.data(res);
    }


    /**
     * register
     *
     * @param phone
     * @return
     */
    @ApiOperation("门店用户登录校验")
    @ApiOperationSupport(order = 9)
    @ApiImplicitParams({@ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query", required = true)})
    @GetMapping("/checkLogin")
    public R<Boolean> checkLogin(String phone) {
        log.info("StoreUserController.checkLogin?phone={}", phone);
        return storeUserService.checkLogin(phone);
    }

    /**
     * 商家端注销用户效验
     */
    @ApiOperation("商家端注销用户效验")
    @PostMapping("/storeCancelAccountVerification")
    public R<Map<String, String>> storeCancelAccountVerification(@RequestBody StoreUserVo storeUserVo) {
        log.info("StoreUserController.storeCancelAccountVerification?storeUserVo={}", storeUserVo);
             return R.data(storeUserService.storeCancelAccountVerification(storeUserVo));
    }

    /**
     * 商家端注销用户
     */
    @ApiOperation("商家端注销用户")
    @PostMapping("/storeCancelAccount")
    public R<StoreUserVo> storeCancelAccount(@RequestBody StoreUserVo storeUserVo) {
        log.info("StoreUserController.storeCancelAccount?storeUserVo={}", storeUserVo);
        try {
            storeUserService.storeCancelAccount(storeUserVo);
        } catch (Exception e) {
            return R.fail(e.getMessage());
        }
        return R.success("注销成功");
    }

    /**
     * 商家端撤销注销用户
     */
    @ApiOperation("商家端撤销注销用户")
    @PostMapping("/storeCancelAccountUn")
    public R<StoreUserVo> storeCancelAccountUn(@RequestBody StoreUserVo storeUserVo) {
        log.info("StoreUserController.storeCancelAccountUn?storeUserVo={}", storeUserVo);
        storeUserService.storeCancelAccountUn(storeUserVo);
        return R.success("撤回注销成功");
    }

    /**
     * 手动删除商家账号及店铺
     */
    @ApiOperation("手动删除商家账号及店铺")
    @PostMapping("/deleteStoreAccountInfo")
    public R<StoreUserVo> deleteStoreAccountInfo(@RequestBody StoreUserVo storeUserVo) {
        log.info("StoreUserController.deleteStoreAccountInfo?storeUserVo={}", storeUserVo);
        storeUserService.deleteStoreAccountInfo(storeUserVo);
        return R.success("删除成功");
    }

    /**
     * 根据id判断是否有支付密码
     */
    @ApiOperation("是否有支付密码")
    @GetMapping("/havePayPassword")
    public R<Boolean> havePayPassword(@RequestParam String storeUserId,@RequestParam(required = false) String password){
        log.info("StoreUserController.havePayPassword?storeUserId={},password={}",storeUserId,password);
        return storeUserService.havePayPassword(storeUserId,password);
    }
}
