package com.cyl.manager.staff.controller;

import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cyl.manager.staff.domain.BondTransaction;
import com.cyl.manager.staff.domain.dto.StaffBondPageListDTO;
import com.cyl.manager.staff.domain.vo.DeductBondSubmitForm;
import com.cyl.manager.staff.domain.vo.StaffVO;
import com.cyl.manager.staff.domain.Staff;
import com.cyl.manager.staff.service.IBondTransactionService;
import com.cyl.manager.staff.service.IStaffService;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisService;
import com.ruoyi.common.enums.BondOrderStatus;
import com.ruoyi.common.enums.BondTransactionType;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 人员信息Controller
 *
 * @author ruoyi
 * @date 2023-12-26
 */
@RestController
@RequestMapping("/system/staff")
@Slf4j
public class StaffController extends BaseController {
    @Autowired
    private IStaffService staffService;

    @Autowired
    private IBondTransactionService bondTransactionService;

    @Autowired
    private RedisService redisService;

    /**
     * 查询人员信息列表
     */
    @PreAuthorize("@ss.hasPermi('system:staff:list')")
    @GetMapping("/list")
    public TableDataInfo list(Staff staff) {
        startPage();
        List<StaffVO> list = staffService.selectStaffListForFont(staff);
        return getDataTable(list);
    }

    /**
     * 导出人员信息列表
     */
    @PreAuthorize("@ss.hasPermi('system:staff:export')")
    @Log(title = "人员信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Staff staff) throws IOException {
        List<Staff> list = staffService.selectStaffList(staff);
        ExcelUtil<Staff> util = new ExcelUtil<Staff>(Staff.class);
        util.exportExcel(response, list, "人员信息数据");
    }

    /**
     * 获取人员信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:staff:query')")
    @GetMapping(value = "/{id}")
    public ResponseEntity<Staff> getInfo(@PathVariable("id") Long id) {
        return ResponseEntity.ok(staffService.selectStaffById(id));
    }

    /**
     * 新增人员信息
     */
    @PreAuthorize("@ss.hasPermi('system:staff:add')")
    @Log(title = "人员信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Staff staff) {
        return toAjax(staffService.insertStaff(staff));
    }

    /**
     * 修改人员信息
     */
    @PreAuthorize("@ss.hasPermi('system:staff:edit')")
    @Log(title = "人员信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Staff staff) {
        return toAjax(staffService.updateStaff(staff));
    }

    /**
     * 删除人员信息
     */
    @PreAuthorize("@ss.hasPermi('system:staff:remove')")
    @Log(title = "人员信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(staffService.deleteStaffByIds(ids));
    }


    /**
     * 保证金扣除
     */
    @PreAuthorize("@ss.hasPermi('system:staff:edit')")
    @Log(title = "保证金扣除", businessType = BusinessType.UPDATE)
    @PostMapping("/deductBond")
    public AjaxResult edit(@RequestBody @Valid DeductBondSubmitForm form) {
        log.info("保证金扣除,提交的数据：{}", JSONObject.toJSONString(form));

        //防止用户重复提交
        String redisKey = "h5_oms_staff_deduct_bond_" + form.getStaffId();
        String redisValue = form.getStaffId() + "_" + System.currentTimeMillis();
        try {
            redisService.lock(redisKey, redisValue, 60);
            Staff staff = staffService.getById(form.getStaffId());
            //校验参数
            form.validParams(staff, form.getAmount());

            //更新staff表金额 以及 保证金缴纳状态
            staffService.updateStaffBondMoney(staff.getId(), form.getAmount(), 0);

            //保存保证金交易流水
            BondTransaction bondTransaction = new BondTransaction();
            bondTransaction.setAmount(form.getAmount());
            bondTransaction.setReason(form.getRemark());
            bondTransaction.setType(BondTransactionType.DEDUCT.getType());
            bondTransaction.setStaffId(staff.getId());
            bondTransaction.setStatus(BondOrderStatus.SUCCESS.getType());
            bondTransaction.setPayType(Constants.PayType.MANUAL);//手动扣款
            bondTransactionService.addBondTransaction(bondTransaction);

            return AjaxResult.success("保证金扣除成功");
        } catch (Exception e) {
            log.error("保证金扣除异常", e);
            throw new RuntimeException(e.getMessage());
        } finally {
            try {
                redisService.unLock(redisKey, redisValue);
            } catch (Exception e) {
                log.error("", e);
            }
        }
    }


    /**
     * 后台查询人员保证金信息列表
     */
    @PreAuthorize("@ss.hasPermi('system:staff:list')")
    @GetMapping("/getBondPageList")
    public AjaxResult getBondPageList(@ApiParam(value = "查询条件", required = false) StaffBondPageListDTO staffBondPageParam) {
        startPage();
        LambdaQueryWrapper<BondTransaction> queryWrapper = new LambdaQueryWrapper<>();
        if (staffBondPageParam.getStaffId() != null) {
            queryWrapper.eq(BondTransaction::getStatus, staffBondPageParam.getStaffId());
        }
        queryWrapper.orderByDesc(BondTransaction::getCreateTme);
        List<BondTransaction> list = bondTransactionService.list(queryWrapper);
        return AjaxResult.success(getDataTable(list));
    }

}
