package com.xmomen.module.plan.controller;

import java.util.HashMap;
import java.util.Map;

import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.xmomen.framework.mybatis.dao.MybatisDao;
import com.xmomen.framework.mybatis.page.Page;
import com.xmomen.framework.web.exceptions.ArgumentValidException;
import com.xmomen.module.base.constant.AppConstants;
import com.xmomen.module.logger.Log;
import com.xmomen.module.plan.entity.TbTablePlan;
import com.xmomen.module.plan.mapper.TablePlanMapper;
import com.xmomen.module.plan.model.CreateTablePlan;
import com.xmomen.module.plan.model.TablePlanModel;
import com.xmomen.module.plan.model.UpdateTablePlan;
import com.xmomen.module.plan.service.TablePlanSercvice;
import com.xmomen.module.user.entity.SysUsers;

/**
 * 该控制器类用于处理与餐桌计划相关的HTTP请求，
 * 提供了查询、新增、修改、删除餐桌计划，以及暂停配送、手工调用创建计划订单等功能。
 * Created by ted on 16/3/28.
 */
@RestController
public class TablePlanController {

    // 注入餐桌计划服务类，用于处理餐桌计划的业务逻辑
    @Autowired
    TablePlanSercvice tablePlanService;
    // 注入餐桌计划映射器，用于与数据库进行交互
    @Autowired
    TablePlanMapper tablePlanMapper;
    // 注入MyBatis数据访问对象，用于执行数据库操作
    @Autowired
    MybatisDao mybatisDao;

    /**
     * 查询餐桌信息
     * @param limit 每页显示的记录数量
     * @param offset 分页查询的偏移量
     * @param id 餐桌计划的ID，可选参数
     * @param keyword 搜索关键词，可选参数
     * @param phoneNumber 电话号码，可选参数
     * @return 包含餐桌计划信息的分页对象
     */
    @RequestMapping(value = "/tablePlan", method = RequestMethod.GET)
    @Log(actionName = "查询餐桌信息")
    public Page<TablePlanModel> getTablePlanList(@RequestParam(value = "limit") Integer limit,
                                                 @RequestParam(value = "offset") Integer offset,
                                                 @RequestParam(value = "id", required = false) Integer id,
                                                 @RequestParam(value = "keyword", required = false) String keyword,
                                                 @RequestParam(value = "phoneNumber", required = false) String phoneNumber) {
        // 创建一个Map用于存储查询参数
        Map map = new HashMap<String, Object>();
        // 将餐桌计划ID放入Map中
        map.put("id", id);
        // 将搜索关键词放入Map中
        map.put("keyword", keyword);
        // 如果电话号码不为空，则将其放入Map中
        if (StringUtils.trimToNull(phoneNumber) != null) {
            map.put("phoneNumber", phoneNumber);
        }
        // 客服经理过滤，如果当前用户有客服经理角色且没有客服角色，则添加用户ID到查询条件中
        if (SecurityUtils.getSubject().hasRole(AppConstants.CUSTOMER_MANAGER_PERMISSION_CODE) && !SecurityUtils.getSubject().hasRole(AppConstants.CUSTOMER_PERMISSION_CODE)) {
            // 从会话中获取当前用户的ID
            Integer userId = (Integer) SecurityUtils.getSubject().getSession().getAttribute(AppConstants.SESSION_USER_ID_KEY);
            // 将用户ID放入Map中
            map.put("userId", userId);
        }
        // 调用MyBatis的分页查询方法，根据查询参数获取餐桌计划列表
        return (Page<TablePlanModel>) mybatisDao.selectPage(TablePlanMapper.TablePlanMapperNameSpace + "getTablePlanList", map, limit, offset);
    }

    /**
     * 新增餐桌计划
     * @param createTablePlan 包含新增餐桌计划信息的对象
     * @param bindingResult 数据绑定结果，用于验证数据有效性
     * @throws ArgumentValidException 如果数据验证失败，抛出该异常
     */
    @RequestMapping(value = "/tablePlan", method = RequestMethod.POST)
    @Log(actionName = "新增餐桌")
    public void createTablePlan(@RequestBody @Valid CreateTablePlan createTablePlan, BindingResult bindingResult) throws ArgumentValidException {
        // 如果数据绑定结果存在错误
        if (bindingResult != null && bindingResult.hasErrors()) {
            // 抛出参数验证异常
            throw new ArgumentValidException(bindingResult);
        }
        // 调用服务层的方法创建餐桌计划
        tablePlanService.createTablePlan(createTablePlan);
    }

    /**
     * 根据ID查询餐桌信息
     * @param id 餐桌计划的ID
     * @return 包含餐桌计划详细信息的对象
     */
    @RequestMapping(value = "/tablePlan/{id}", method = RequestMethod.GET)
    @Log(actionName = "根据ID查询餐桌信息")
    public TablePlanModel getTablePlan(@PathVariable(value = "id") Integer id) {
        // 创建一个Map用于存储查询参数
        Map map = new HashMap<String, Object>();
        // 将餐桌计划ID放入Map中
        map.put("id", id);
        // 调用MyBatis的查询方法，根据ID获取餐桌计划信息
        return mybatisDao.getSqlSessionTemplate().selectOne(TablePlanMapper.TablePlanMapperNameSpace + "getTablePlanList", map);
    }

    /**
     * 修改餐桌计划信息
     * @param id 要修改的餐桌计划的ID
     * @param updateTablePlan 包含更新后餐桌计划信息的对象
     * @param bindingResult 数据绑定结果，用于验证数据有效性
     * @throws ArgumentValidException 如果数据验证失败，抛出该异常
     */
    @RequestMapping(value = "/tablePlan/{id}", method = RequestMethod.PUT)
    @Log(actionName = "修改餐桌信息")
    public void updateTablePlan(@PathVariable(value = "id") Integer id,
                                @RequestBody @Valid UpdateTablePlan updateTablePlan, BindingResult bindingResult) throws ArgumentValidException {
        // 如果数据绑定结果存在错误
        if (bindingResult != null && bindingResult.hasErrors()) {
            // 抛出参数验证异常
            throw new ArgumentValidException(bindingResult);
        }
        // 调用服务层的方法更新餐桌计划信息
        tablePlanService.updateTablePlan(id, updateTablePlan);
    }

    /**
     * 删除餐桌计划信息
     * @param id 要删除的餐桌计划的ID
     */
    @RequestMapping(value = "/tablePlan/{id}", method = RequestMethod.DELETE)
    @Log(actionName = "删除餐桌信息")
    public void deleteTablePlan(@PathVariable(value = "id") Integer id) {
        // 调用服务层的方法删除餐桌计划
        tablePlanService.delete(id);
    }

    /**
     * 暂停配送
     * @param id 要暂停配送的餐桌计划的ID
     * @param locked 是否暂停，true表示暂停，false表示恢复
     */
    @RequestMapping(value = "/tablePlan/{id}/stop", method = RequestMethod.PUT)
    @Log(actionName = "暂停配送")
    public void stop(@PathVariable(value = "id") Integer id,
                     @RequestParam(value = "locked") Boolean locked) {
        // 创建一个餐桌计划实体对象
        TbTablePlan tablePlan = new TbTablePlan();
        // 根据locked的值设置是否暂停配送的标志，1表示暂停，0表示正常
        tablePlan.setIsStop(locked ? 1 : 0);
        // 设置餐桌计划的ID
        tablePlan.setId(id);
        // 调用MyBatis的更新方法更新餐桌计划信息
        mybatisDao.update(tablePlan);
    }

    /**
     * 手工调用创建计划订单
     */
    @RequestMapping(value = "/tablePlan/createPlanOrder", method = RequestMethod.PUT)
    @Log(actionName = "手工调用")
    public void createPlanOrder() {
        // 调用服务层的方法创建餐桌计划订单
        tablePlanService.createTablePlanOrder();
    }
}