package com.neusoft.smart.pos.org.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.dto.org.request.TableWithDishesRequest;
import com.neusoft.smart.pos.dto.org.request.TablesRequest;
import com.neusoft.smart.pos.dto.org.response.TableWithDishesResponse;
import com.neusoft.smart.pos.dto.org.response.TablesResponse;
import com.neusoft.smart.pos.dto.org.response.TablesWeChatResponse;
import com.neusoft.smart.pos.dto.printer.request.PostPrinterOrderRequest;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.framework.utils.BeanUtil;
import com.neusoft.smart.pos.framework.utils.DateUtils;
import com.neusoft.smart.pos.org.constants.TableErrorCode;
import com.neusoft.smart.pos.org.persistent.domain.Tables;
import com.neusoft.smart.pos.org.persistent.domain.TablesExample;
import com.neusoft.smart.pos.org.persistent.mapper.TablesMapper;
import com.neusoft.smart.pos.printer.service.PrinterService;
import lombok.val;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class TableService {
    
    @Resource
    private TablesMapper tablesMapper;
    
    @Autowired
    private   ShopService shopService;

//    @Autowired
//    private PrintService printService;
    
    @Autowired
    private PrinterService printerService;
    
    public void insert(TablesRequest record) {
        final int i = tablesMapper.countByTableName(record.getTableName(), record.getShopId());
        if (i > 0) {
            throw new BusinessCommonException("500", "重复的桌号");
        }
        Tables tables = new Tables();
        BeanUtils.copyProperties(record, tables);
        if (null == tables.getStatus()) tables.setStatus(0);
        tablesMapper.insert(tables);
    }
    
    /**
     * @param tableId
     * @return
     */
    public TablesResponse selectById(Integer tableId) {
        Tables tables = tablesMapper.selectByPrimaryKey(tableId);
        if (null == tables) {
            throw new BusinessCommonException(TableErrorCode.TABLE_NOT_EXIST);
        }
        return BeanUtil.parse(tables, TablesResponse.class);
    }
    
    /**
     * @param shopId
     * @return
     */
    public List<TablesResponse> selectByShopId(Integer shopId) {
        return BeanUtil.parseList(tablesMapper.selectByShopId(shopId), TablesResponse.class);
    }
    
    public TablesWeChatResponse selectWeChatOrder4Pos(Integer shopId, Long time, Date curTime) {
        TablesWeChatResponse tablesWeChatResponse = new TablesWeChatResponse();
        tablesWeChatResponse.setRequestTime(curTime);
        Date queryTime = new Date(time);
        TablesExample tablesExample = new TablesExample();
        tablesExample.createCriteria().andShopIdEqualTo(shopId).andUpdateTimeGreaterThanOrEqualTo(queryTime).andOrderIdEqualTo("WeChat");
        tablesWeChatResponse.setTables(BeanUtil.parseList(tablesMapper.selectByExample(tablesExample), TablesResponse.class));
        return tablesWeChatResponse;
    }
    
    /**
     * @param record
     */
    public void update(TablesRequest record) {
        final int i = tablesMapper.countByTableName2(record.getTableName(), record.getShopId(), record.getId());
        if (i > 0) {
            throw new BusinessCommonException("500", "重复的桌号");
        }
        Tables tables = new Tables();
        BeanUtils.copyProperties(record, tables);
        tablesMapper.updateByPrimaryKeySelective(tables);
    }
    
    /**
     * @param tableId
     */
    public void delete(Integer tableId) {
        tablesMapper.deleteByPrimaryKey(tableId);
    }
    
    /**
     * 开台之后保存数据
     * 桌状态 0 空桌 1 已开台 2 已下单 3 已结算 4 预定
     *
     * @param tableId
     * @param tableWithDishesRequest
     * @return
     */
    public void saveFoundingData(Integer tableId, TableWithDishesRequest tableWithDishesRequest) {
        Tables record = tablesMapper.selectByPrimaryKey(tableId);
        if (null == record) {
            throw new BusinessCommonException(TableErrorCode.TABLE_NOT_EXIST);
        }
        if (record.getStatus() != 1) {
            throw new BusinessCommonException(TableErrorCode.TABLE_ORDERED_ERROR);
        }
        record.setId(tableId);
        record.setStatus(2);
        record.setDishes(JSON.toJSONString(tableWithDishesRequest));
        record.setOrderId(tableWithDishesRequest.getDishesSource());
        record.setUpdateTime(new Date());
        tablesMapper.updateByPrimaryKeySelective(record);
        tableWithDishesRequest.getMenuList().forEach(menu -> menu.setTableName(record.getTableName()));
//        printService.insertToQueue(record.getShopId(), tableWithDishesRequest.getMenuList());
        this.createPrintTask(record.getShopId(), tableWithDishesRequest);
    }
    
    /**
     * 设置开台状态
     * 桌状态 0 空桌 1 已开台 2 已下单 3 已结算 4 预定
     *
     * @param tableId
     */
    public TableWithDishesResponse founding(Integer tableId) {
        Tables record = tablesMapper.selectByPrimaryKey(tableId);
        if (null == record) {
            throw new BusinessCommonException(TableErrorCode.TABLE_NOT_EXIST);
        }
        TableWithDishesResponse tableWithDishesResponse = new TableWithDishesResponse();
        if (record.getStatus() != 0) {
            tableWithDishesResponse = JSONObject.parseObject(record.getDishes(), TableWithDishesResponse.class);
            if (null == tableWithDishesResponse) {
                tableWithDishesResponse = new TableWithDishesResponse();
            }
            tableWithDishesResponse.setStatus(record.getStatus());
            return tableWithDishesResponse;
        }
        record.setStatus(1);
        tableWithDishesResponse.setCreateTime(new Date());
        record.setDishes(JSON.toJSONString(tableWithDishesResponse));
        record.setUpdateTime(new Date());
        tablesMapper.updateByPrimaryKeySelective(record);
        return null;
    }
    
    /**
     * 添加新菜肴
     *
     * @param tableId
     * @param tableWithDishesRequest
     */
    public void addDishes(Integer tableId, TableWithDishesRequest tableWithDishesRequest) {
        Tables record = tablesMapper.selectByPrimaryKey(tableId);
        if (null == record) {
            throw new BusinessCommonException(TableErrorCode.TABLE_NOT_EXIST);
        }
        if (record.getStatus() != 1 && record.getStatus() != 2) {
            throw new BusinessCommonException(TableErrorCode.TABLE_ADD_DISHES_ERROR);
        }
        TableWithDishesRequest original = JSONObject.parseObject(record.getDishes(), TableWithDishesRequest.class);
        List<TableWithDishesRequest.Menu> willPrintMenus = new ArrayList<>();//FIXME 打印队列添加新数据
        for (TableWithDishesRequest.Menu menu : tableWithDishesRequest.getMenuList()) {
            TableWithDishesRequest.Menu mappingMenu = original
                    .getMenuList().stream().filter(temp -> temp.getName().equals(menu.getName())).findAny().orElse(null);
            //能在原始菜单找到 并且加菜的数量不是空 并且加菜请求比原始菜单数量多，需要打印
            if (null != mappingMenu && null != menu.getCount()
                    && ((null == mappingMenu.getCount() ? 0 : mappingMenu.getCount()) - menu.getCount()) < 0) {
                TableWithDishesRequest.Menu willPrintMenu = BeanUtil.parse(menu, TableWithDishesRequest.Menu.class);
                willPrintMenu.setCount(willPrintMenu.getCount() - mappingMenu.getCount());
                willPrintMenu.setTableName(record.getTableName());
                willPrintMenus.add(willPrintMenu);
            } else if (null == mappingMenu) {
                menu.setTableName(record.getTableName());
                willPrintMenus.add(menu);
            }
        }
        record.setDishes(JSON.toJSONString(tableWithDishesRequest));
        record.setStatus(2);
        record.setOrderId(tableWithDishesRequest.getDishesSource());
        record.setUpdateTime(new Date());
        tablesMapper.updateByPrimaryKeySelective(record);
        TableWithDishesRequest temp = BeanUtil.parse(tableWithDishesRequest, TableWithDishesRequest.class);
        temp.setMenuList(willPrintMenus);
        this.createPrintTask(record.getShopId(), temp);
//        printService.insertToQueue(record.getShopId(), willPrintMenus);
    }
    
    /**
     * 清台 将状态改为空桌
     * 桌状态 0 空桌 1 已开台 2 已下单 3 已结算 4 预定
     *
     * @param tableId
     */
    public void unfounding(Integer tableId) {
        Tables record = new Tables();
        record.setId(tableId);
        record.setStatus(0);
        record.setOrderId("");
        record.setDishes("");
        record.setUpdateTime(new Date());
        tablesMapper.updateByPrimaryKeySelective(record);
    }
    
    
    /**
     * 结算 设置状态为已结算
     *
     * @param tableId
     * @param tableWithDishesRequest
     */
    public void settle(Integer tableId, TableWithDishesRequest tableWithDishesRequest) {
        Tables record = tablesMapper.selectByPrimaryKey(tableId);
        if (null == record) {
            throw new BusinessCommonException(TableErrorCode.TABLE_NOT_EXIST);
        }
        if (record.getStatus() != 2) {
            throw new BusinessCommonException(TableErrorCode.TABLE_SETTLE_ERROR);
        }
        TableWithDishesResponse tableWithDishesResponse = JSONObject.parseObject(record.getDishes(), TableWithDishesResponse.class);
        tableWithDishesResponse.setPaymentTime(tableWithDishesRequest.getPaymentTime());
        tableWithDishesResponse.setPaymentAmount(tableWithDishesRequest.getPaymentAmount());
        tableWithDishesResponse.setPaymentType(tableWithDishesRequest.getPaymentType());
        tableWithDishesResponse.setOrderNum(tableWithDishesRequest.getOrderNum());
        tableWithDishesResponse.setDiscountAmount(tableWithDishesRequest.getDiscountAmount());
        tableWithDishesResponse.setDiscountRate(tableWithDishesRequest.getDiscountRate());
        tableWithDishesResponse.setMemberDiscountRate(tableWithDishesRequest.getMemberDiscountRate());
        record.setId(tableId);
        record.setStatus(3);
        record.setDishes(JSON.toJSONString(tableWithDishesResponse));
        record.setUpdateTime(new Date());
        tablesMapper.updateByPrimaryKeySelective(record);
    }
    
    /**
     * @param originalTableId
     * @param targetTableId
     */
    public TableWithDishesResponse exchange(Integer originalTableId, Integer targetTableId) {
        Tables targetTable = tablesMapper.selectByPrimaryKey(targetTableId);
        if (null == targetTable) {
            throw new BusinessCommonException(TableErrorCode.TABLE_NOT_EXIST);
        }
        if (targetTable.getStatus() != 0) {
            TableWithDishesResponse tableWithDishesResponse = JSONObject.parseObject(targetTable.getDishes(), TableWithDishesResponse.class);
            tableWithDishesResponse.setStatus(targetTable.getStatus());
            return tableWithDishesResponse;
        }
        Tables originalTable = tablesMapper.selectByPrimaryKey(originalTableId);
        if (null == originalTable) {
            throw new BusinessCommonException(TableErrorCode.TABLE_NOT_EXIST);
        }
        targetTable.setStatus(originalTable.getStatus());
        targetTable.setDishes(originalTable.getDishes());
        targetTable.setUpdateTime(new Date());
        tablesMapper.updateByPrimaryKeySelective(targetTable);
        originalTable.setDishes("");
        originalTable.setStatus(0);
        tablesMapper.updateByPrimaryKeySelective(originalTable);
        return null;
    }
    
    /**

     * @param storeId
     * @param tableWithDishesRequest
     */
    private void createPrintTask(Integer storeId, TableWithDishesRequest tableWithDishesRequest) {
        if (tableWithDishesRequest.getMenuList().isEmpty()) {
            return;
        }
        PostPrinterOrderRequest postPrinterOrderRequest = new PostPrinterOrderRequest();
        postPrinterOrderRequest.setOrderAmount(tableWithDishesRequest.getTotalPrice());
        postPrinterOrderRequest.setOrgId(shopService.selectShopById(storeId).getOrg());
        postPrinterOrderRequest.setShopId(storeId);
        postPrinterOrderRequest.setPaidTime(DateUtils.format(tableWithDishesRequest.getCreateTime()));
        List<PostPrinterOrderRequest.OrderDetail> orderDetails = new ArrayList<>();
        tableWithDishesRequest.getMenuList().forEach(menu -> {
            //餐桌名称
            postPrinterOrderRequest.setLocationNo(menu.getTableName());
            val detail = new PostPrinterOrderRequest.OrderDetail();
            detail.setItemNumber(menu.getMenuId());
            detail.setItemName(menu.getName());
            detail.setCategoryName(menu.getCategory());
            detail.setCategoryNumber(menu.getCategoryId().toString());
            detail.setUnitPrice(menu.getPrice());
            detail.setQuantity(menu.getCount());
            detail.setDiscountAmount(new BigDecimal(0));
            detail.setSelectedFlavors(null != menu.getSelectedFlavors() ? JSON.toJSONString(menu.getSelectedFlavors()) : null);
            postPrinterOrderRequest.setLocationNo(menu.getTableName());
            orderDetails.add(detail);
        });
        postPrinterOrderRequest.setOrderDetails(orderDetails);
        postPrinterOrderRequest.setTemplateType(DictionaryConstant.PRINTER_TEMPLATE_TYPE_1.getCode());
        printerService.printerOrder(postPrinterOrderRequest);
    }

}
