package com.handong.smartservice.service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import com.handong.smartservice._AG;
import com.handong.smartservice.component.CtResponse;
import com.handong.smartservice.component.ErrorCode;

import org.apache.ibatis.jdbc.SQL;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.handong.smartservice.mapper.TransactionMapper;
import com.handong.smartservice.mapper.BizGroupMapper;
import com.handong.smartservice.mapper.GoodsMapper;
import com.handong.smartservice.mapper.TerminalMapper;

@Service
public class TransactionService {

    private final TransactionMapper transactionMapper;
    private final GoodsMapper goodsMapper;
    private final BizGroupMapper bizGroupMapper;
    private final TerminalMapper terminalMapper;

    public TransactionService(TransactionMapper transactionMapper, GoodsMapper goodsMapper, BizGroupMapper bizGroupMapper, TerminalMapper terminalMapper) {
        this.transactionMapper = transactionMapper;
        this.goodsMapper = goodsMapper;
        this.bizGroupMapper = bizGroupMapper;
        this.terminalMapper = terminalMapper;
    }

    public Map<String, Object> getTransactionList(Boolean is_excel, Long offset, Long limit, Boolean is_group_access, Long biz_group_id, String date_start, String date_end, 
        String uid1, Long uid1_type, String type, Long amount, String approval, String pay_name, String pay_vendor, String slot, String code, String goods_name) {
        Map<String, Object> mapResult = new HashMap<>();

        /*
        if (is_group_access == false) {
            List<Map<String, Object>> listForTopId = bizGroupMapper.selectBizGroup(biz_group_id, false, 0L, 1L, null, null, null, null, null, null, null);
            if (listForTopId != null && listForTopId.size() > 0) {
                biz_group_id = (Long)listForTopId.get(0).get("top_group_id");
                if (biz_group_id == null)
                    biz_group_id = (Long)listForTopId.get(0).get("biz_group_id");
            }
        }
        */
       
        List<Map<String, Object>> listMap = (List<Map<String, Object>>)transactionMapper.selectTransaction(false, is_excel, offset, limit, is_group_access,
            biz_group_id, date_start, date_end, uid1, uid1_type, type, amount, approval, pay_name, pay_vendor, slot, code, goods_name);
        mapResult.put("list", listMap);

        Long totalCount = _AG.getNumberFromQuery("COUNT(*)", transactionMapper.selectTransaction(true, is_excel, offset, limit, is_group_access,
            biz_group_id, date_start, date_end, uid1, uid1_type, type, amount, approval, pay_name, pay_vendor, slot, code, goods_name));
        mapResult.put("totalCount", totalCount);
        mapResult.put("offset", offset);
        return mapResult;
    }

    public Map<String, Object> getUndefinedTransactionList(Boolean is_excel, Long offset, Long limit, String date_start, String date_end, 
        String uid1, Long uid1_type, String type, Long amount, String approval, String pay_name, String pay_vendor, String slot, String code, String goods_name) {
        Map<String, Object> mapResult = new HashMap<>();
       
        List<Map<String, Object>> listMap = (List<Map<String, Object>>)transactionMapper.selectTransactionBizGroup0(
            false, is_excel, offset, limit, date_start, date_end, uid1, uid1_type, type, amount, approval, pay_name, pay_vendor, slot, code, goods_name);
        mapResult.put("list", listMap);

        Long totalCount = _AG.getNumberFromQuery("COUNT(*)", transactionMapper.selectTransactionBizGroup0(
            true, is_excel, offset, limit, date_start, date_end, uid1, uid1_type, type, amount, approval, pay_name, pay_vendor, slot, code, goods_name));
        mapResult.put("totalCount", totalCount);
        mapResult.put("offset", offset);
        return mapResult;
    }

    public CtResponse addTransaction(String uid1, Long uid1_type, String type, Long amount, String approval, String pay_name, String pay_vendor, String slot, String pay_unique_num, String pay_order_time) {
        CtResponse result = new CtResponse();
        Long biz_group_id = 0L;
        Long device_id = 0L;

        Map<String, Object> terminal = terminalMapper.selectTerminal3(uid1, uid1_type);
        if (terminal != null) {
            device_id = (Long)terminal.get("device_id");
            Map<String, Object> mapBizGroup = bizGroupMapper.selectBizGroupByDeviceId(device_id);
            if (mapBizGroup != null) {
                biz_group_id = (Long)mapBizGroup.get("biz_group_id");
            }
            else {
                Long terminal_id = (Long)terminal.get("terminal_id");
                Map<String, Object> mapBizGroup2 = bizGroupMapper.selectBizGroupByTerminalId(terminal_id);
                if (mapBizGroup2 != null) {
                    biz_group_id = (Long)mapBizGroup2.get("biz_group_id");
                }
            }
        }

        //select  uid1, uid1_type -> device_id ->device_goods (slot) -> goods_id
        Map<String, Object> goods = goodsMapper.selectGoodsByUid1(uid1, uid1_type, slot);        
        if (goods != null) {
            device_id = (Long)goods.get("device_id");
        }

        Map<String, Object> params = new HashMap<>();
        params.put("uid1", uid1);
        params.put("uid1_type", uid1_type);
        params.put("order_time", pay_order_time);
        params.put("type", type);
        params.put("amount", amount);
        params.put("approval", approval);
        params.put("pay_unique_num", pay_unique_num);
        params.put("pay_name", pay_name);
        params.put("pay_vendor", pay_vendor);
        params.put("slot", slot);
        params.put("biz_group_id", biz_group_id);
        params.put("device_id", device_id);

        if (type.compareTo("D4") == 0) {
            goodsMapper.updateDeviceGoodsPlusInventory(approval);
        }
        else if (goods != null) {
            params.put("goods_name", goods.get("name"));
            params.put("code", goods.get("code"));
            params.put("price", goods.get("price"));
            
            goodsMapper.updateDeviceGoodsMinusInventory((Long)goods.get("device_id"), slot);
        }

        transactionMapper.insertTransaction(params);        
    
        return result;
    }
}
