package com.fuint.module.backendApi.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fuint.common.dto.AccountInfo;
import com.fuint.common.dto.ext.TableInfoDto;
import com.fuint.common.enums.StatusEnum;
import com.fuint.common.param.PageParam;
import com.fuint.common.service.CartService;
import com.fuint.common.service.TableCategoryService;
import com.fuint.common.service.TableInfoService;
import com.fuint.common.util.I18nUtil;
import com.fuint.common.util.TokenUtil;
import com.fuint.framework.exception.BusinessCheckException;
import com.fuint.framework.web.BaseController;
import com.fuint.framework.web.PageResult;
import com.fuint.framework.web.ResponseObject;
import com.fuint.repository.bean.TableInfoBean;
import com.fuint.repository.model.MtCart;
import com.fuint.repository.model.MtTableInfo;
import com.fuint.utils.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;

/**
 * 餐桌信息管理类controller
 *
 * Created by pzg
 * CopyRight https://www.fuint.cn
 */
@Api(tags="管理端-餐桌信息相关接口")
@RestController
@AllArgsConstructor
@RequestMapping(value = "/backendApi/table_info")
public class BackendTableInfoController extends BaseController {

    /**
     * 餐桌信息服务接口
     */
    private TableInfoService tableInfoService;

    private TableCategoryService categoryService;

    private CartService cartService;

    /**
     * 餐桌信息列表查询
     *
     * @return 餐桌信息列表
     */
    @ApiOperation(value = "餐桌信息列表查询")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @CrossOrigin
    @PreAuthorize("@pms.hasPermission('table:index')")
    public PageResult<TableInfoBean> list(@RequestParam(value = "tableNumber",defaultValue = "") String tableNumber,
                                          @RequestParam(value = "tableStatus",required = false) Integer tableStatus, PageParam param) throws BusinessCheckException {
        return  tableInfoService.selectTableList(tableNumber,tableStatus,param);

    }

    /**
     * 更新餐桌信息状态
     *
     * @return
     */
    @ApiOperation(value = "更新餐桌信息状态")
    @RequestMapping(value = "/updateStatus", method = RequestMethod.POST)
    @CrossOrigin
    @PreAuthorize("@pms.hasPermission('table:edit')")
    public ResponseObject updateStatus(HttpServletRequest request, @RequestBody Map<String, Object> params) throws BusinessCheckException {
        String token = request.getHeader("Access-Token");
        String status = params.get("tableStatus") != null ? params.get("tableStatus").toString() : StatusEnum.ENABLED.getKey();
        Long id = params.get("id") == null ? 0 : Long.parseLong(params.get("id").toString());

        AccountInfo accountInfo = TokenUtil.getAccountInfoByToken(token);
        if (accountInfo == null) {
            return getFailureResult(1001, I18nUtil.getMessage("notAuthenticated"));
        }

        MtTableInfo mtTableInfo = tableInfoService.queryTableInfoById(id);
        if (mtTableInfo == null) {
            return getFailureResult(201);
        }
        int count = cartService.count(new LambdaQueryWrapper<MtCart>()
                .eq(MtCart::getTableId, id));
        if (Integer.parseInt(status)==1 && count>0){
            return getFailureResult(1001, I18nUtil.getMessage("inUseTable"));
        }
        mtTableInfo.setTableStatus(Integer.parseInt(status));

        tableInfoService.updateTableInfo(mtTableInfo);

        return getSuccessResult(true);
    }

    /**
     * 保存餐桌信息
     *
     * @param request HttpServletRequest对象
     * @return
     */
    @ApiOperation(value = "保存餐桌信息")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @CrossOrigin
    @PreAuthorize("@pms.hasPermission('tableInfo:add')")
    public ResponseObject saveHandler(HttpServletRequest request, @RequestBody Map<String, Object> params) throws BusinessCheckException {
        String token = request.getHeader("Access-Token");
        String id = params.get("id") == null ? "" : params.get("id").toString();
        String status = params.get("status") == null ? "" : params.get("status").toString();
        String storeId = params.get("storeId") == null ? "0" : params.get("storeId").toString();

        AccountInfo accountInfo = TokenUtil.getAccountInfoByToken(token);
        if (accountInfo == null) {
            return getFailureResult(1001, I18nUtil.getMessage("notAuthenticated"));
        }

        MtTableInfo info = new MtTableInfo();
        if (StringUtil.isNotEmpty(id)) {
            tableInfoService.updateTableInfo(info);
        } else {
            tableInfoService.addTableInfo(info);
        }

        return getSuccessResult(true);
    }

    /**
     * 获取餐桌信息详情
     *
     * @param tableId
     * @return
     */
    @ApiOperation(value = "根据餐桌分类id获取餐桌信息详情")
    @RequestMapping(value = "/info/{tableId}", method = RequestMethod.GET)
    @CrossOrigin
    @PreAuthorize("@pms.hasPermission('table:index')")
    public ResponseObject info(HttpServletRequest request, @PathVariable("tableId") Long tableId) throws BusinessCheckException {
        String token = request.getHeader("Access-Token");
        AccountInfo accountInfo = TokenUtil.getAccountInfoByToken(token);
        if (accountInfo == null) {
            return getFailureResult(1001, I18nUtil.getMessage("notAuthenticated"));
        }

        MtTableInfo tableInfoServiceById = tableInfoService.getById(tableId);

        return getSuccessResult(tableInfoServiceById);
    }



    @ApiOperation("新增餐桌信息接口")
    @PostMapping("/create")
    @CrossOrigin
    @PreAuthorize("@pms.hasPermission('table:create')")
    public ResponseObject createTable(
            HttpServletRequest request,
             @RequestBody TableInfoDto dto) throws BusinessCheckException {

        // 身份验证
        String token = request.getHeader("Access-Token");
        AccountInfo account = TokenUtil.getAccountInfoByToken(token);
        if (account == null) {
            return getFailureResult(1001, I18nUtil.getMessage("notAuthenticated"));
        }

        // 校验分类是否存在
        if (!categoryService.existCategory(dto.getCategoryId())) {
            return getFailureResult(2001, I18nUtil.getMessage("nonExistentCategory"));
        }

        // 构造实体
        MtTableInfo entity = new MtTableInfo();
        BeanUtils.copyProperties(dto, entity);
        entity.setCreateUserId(account.getAccountName());
        entity.setUpdateUserId(account.getAccountName());
        entity.setTableStatus(0); // 默认空闲状态
        entity.setDeleteFlag(0);
        entity.setStoreId(account.getStoreId());
        // 保存数据
        boolean result = tableInfoService.saveTable(entity);
        return result ? getSuccessResult(true) : getFailureResult(500, I18nUtil.getMessage("saveErr"));
    }

    @ApiOperation("修改餐桌信息接口")
    @PostMapping("/update")
    @CrossOrigin
    @PreAuthorize("@pms.hasPermission('table:edit')")
    public ResponseObject updateTable(
            HttpServletRequest request,
           @RequestBody TableInfoDto dto) throws BusinessCheckException {

        // 1. 身份验证
        String token = request.getHeader("Access-Token");
        AccountInfo account = TokenUtil.getAccountInfoByToken(token);
        if (account == null) {
            return getFailureResult(1001, I18nUtil.getMessage("notAuthenticated"));
        }

        // 2. 校验基础数据
        MtTableInfo existTable = tableInfoService.getById(dto.getId());
        if (existTable == null || existTable.getDeleteFlag() == 1) {
            return getFailureResult(201, I18nUtil.getMessage("tableDeletedOrNonExistent"));
        }

        // 3. 业务校验
        verifyUpdateData(dto, existTable, account);

        // 4. 执行更新
        MtTableInfo updateEntity = buildUpdateEntity(dto, existTable, account);
        boolean result = tableInfoService.updateTable(updateEntity);

        return result ? getSuccessResult(true) : getFailureResult(500, I18nUtil.getMessage("updateErr"));
    }




    @ApiOperation("逻辑删除餐桌")
    @DeleteMapping("/delete/{id}")
    @CrossOrigin
    @PreAuthorize("@pms.hasPermission('table:delete')")
    public ResponseObject logicalDelete(
            HttpServletRequest request,
            @PathVariable Long id) throws BusinessCheckException {

        // 1. 身份验证
        String token = request.getHeader("Access-Token");
        AccountInfo account = TokenUtil.getAccountInfoByToken(token);
        if (account == null) {
            return getFailureResult(1001, I18nUtil.getMessage("notAuthenticated"));
        }
        Long storeId = account.getStoreId();
        if (storeId==null || storeId<=0){
            return getFailureResult(1001, I18nUtil.getMessage("superAdminNotAllowedUseMerchantAccount"));
        }
        // 2. 校验数据存在性
        MtTableInfo table = tableInfoService.getById(id);
        if (table == null || table.getDeleteFlag().equals(1)) {
            return getFailureResult(201, I18nUtil.getMessage("tableDeletedOrNonExistent"));
        }

        //校验在购物车是否使用了
        int count = cartService.count(new LambdaQueryWrapper<MtCart>()
                .eq(MtCart::getTableId, table.getId()));
        if (count>0){
            return getFailureResult(201, I18nUtil.getMessage("inUseTable"));
        }
        // 3. 执行逻辑删除
        MtTableInfo updateEntity = new MtTableInfo();
        updateEntity.setId(id);
        boolean result = tableInfoService.removeById(updateEntity);
        return result ? getSuccessResult(true) : getFailureResult(500, I18nUtil.getMessage("deleteErr"));
    }



    private void verifyUpdateData(TableInfoDto dto, MtTableInfo existTable, AccountInfo account)
            throws BusinessCheckException {

       /* // 校验分类有效性
        if (!categoryService.existCategory(dto.getCategoryId())) {
            throw new BusinessCheckException("关联分类不存在");
        }*/

        // 校验桌号唯一性（排除自身）
        LambdaQueryWrapper<MtTableInfo> query = new LambdaQueryWrapper<>();
        query.ne(MtTableInfo::getId, dto.getId())
                .eq(MtTableInfo::getTableNumber, dto.getTableNumber())
                .eq(MtTableInfo::getDeleteFlag, 0);
        if (tableInfoService.count(query) > 0) {
            throw new BusinessCheckException(I18nUtil.getMessage("tableInUseAlready"));
        }
    }

    private MtTableInfo buildUpdateEntity(TableInfoDto dto, MtTableInfo exist, AccountInfo account) {
        MtTableInfo entity = new MtTableInfo();
        BeanUtils.copyProperties(dto, entity);
        entity.setUpdateUserId(account.getAccountName());
        entity.setUpdateTime(new Date());

        // 保留不可修改字段
        entity.setCreateUserId(exist.getCreateUserId());
        entity.setCreateTime(exist.getCreateTime());
        entity.setDeleteFlag(exist.getDeleteFlag());

        return entity;
    }


    /**
     * 新增餐桌信息接口（无关联分类表）
     * @param request
     * @param dto
     * @return
     * @throws BusinessCheckException
     */
    @ApiOperation("新增餐桌信息接口")
    @PostMapping("/addTableInfo")
    @CrossOrigin
    @PreAuthorize("@pms.hasPermission('table:create')")
    public ResponseObject addTableInfo(
            HttpServletRequest request,
            @RequestBody TableInfoDto dto) throws BusinessCheckException {
        // 身份验证
        String token = request.getHeader("Access-Token");
        AccountInfo account = TokenUtil.getAccountInfoByToken(token);
        if (account == null) {
            return getFailureResult(1001, I18nUtil.getMessage("notAuthenticated"));
        }
        Long storeId = account.getStoreId();
        if (storeId==null || storeId<=0){
            return getFailureResult(1001, I18nUtil.getMessage("superAdminNotAllowedUseMerchantAccount"));
        }
        // 构造实体
        MtTableInfo entity = new MtTableInfo();
        BeanUtils.copyProperties(dto, entity);
        entity.setCreateUserId(account.getAccountName());
        entity.setUpdateUserId(account.getAccountName());
        entity.setTableStatus(dto.getTableStatus()==null?0:dto.getTableStatus()); // 默认空闲状态
        entity.setDeleteFlag(0);
        entity.setStoreId(storeId);
        // 保存数据
        boolean result = tableInfoService.saveTable(entity);
        return result ? getSuccessResult(true) : getFailureResult(500, I18nUtil.getMessage("saveErr"));
    }




}
