package com.handong.smartservice.controller.api;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import com.handong.smartservice._AG;
import com.handong.smartservice.component.CtExcelMaker;
import com.handong.smartservice.component.CtResponse;
import com.handong.smartservice.component.ErrorCode;
import com.handong.smartservice.service.GoodsService;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;


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


@RestController
@RequestMapping("/api")
class GoodsController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    private final GoodsService goodsService;


    public GoodsController(GoodsService goodsService) {
        this.goodsService = goodsService;
    }

    @RequestMapping(value = "/get-goods.do", method = RequestMethod.POST)
    public CtResponse getGoodsList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, String> body) {
        logger.info("req: " + request.getRequestURI());

        CtResponse result = new CtResponse();

        Boolean is_excel = _AG.toBoolean(body.get("is_excel"));
        Long offset= _AG.toLong(body.get("offset"));
        Long limit = _AG.toLong(body.get("limit"));
        if (limit > 100)
            limit = 100L;

        Boolean is_group_access = _AG.toBoolean(body.get("is_group_access"));
        Long biz_group_id = _AG.toLong(body.get("biz_group_id"));
        Long device_id = _AG.toLong(body.get("device_id"));
        Long state = _AG.toLong(body.get("state"));
        String code = body.get("code");
        String name = body.get("name");
        String vendor = body.get("vendor");
        String date_start = body.get("date_start");
        String date_end = body.get("date_end");
        
        Map<String, Object> mapResult = goodsService.getGoodsList(is_excel, offset, limit, is_group_access, biz_group_id, device_id, state, code, name, vendor, date_start, date_end);

        if (is_excel) {
            List<Map<String, String>> list = (List<Map<String, String>>)mapResult.get("list");

            for (Map<String, String> item : list) {
                item.replace("reg_time", _AG.timestampToStr(item.get("reg_time")));
            }

            String[] arrHeader = {"등록일", "사업자", "상품코드", "상품명", "가격", "공급사"};
            String[] arrColumn = {"reg_time", "biz_group_name", "code", "name", "price", "vendor"};

            CtExcelMaker.makeExcelResponse(request, response, "상품목록", arrHeader, arrColumn, list, null);
            return null;
        }

        result.put("result", mapResult);
        return result;
    }

    public CtResponse addOrModifyGoods(boolean isModify, HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, String> body) {
        CtResponse result = new CtResponse();

        Long biz_group_id = _AG.toLong(body.get("biz_group_id"));
        Long goods_id =  _AG.toLong(body.get("goods_id"));
        String code = body.get("code");
        String name = body.get("name");
        String vendor = body.get("vendor");
        Long price = _AG.toLongOrNull(body.get("price"));// nullable
        Long inventory = _AG.toLongOrNull(body.get("inventory"));// nullable

        if (code == null || code.isEmpty() || name == null || name.isEmpty()) {
            result.setErrCode(ErrorCode.INVALID_PARAMETER);
            return result;
        }

        result = goodsService.addOrModifyGoods(isModify, biz_group_id, goods_id, code, name, price, inventory, vendor);
        return result;
    }

    @RequestMapping(value = "/add-goods.do", method = RequestMethod.POST)
    public CtResponse addGoods(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, String> body) {
        logger.info("req: " + request.getRequestURI());

        return addOrModifyGoods(false, request, response, body);
    }

    @RequestMapping(value = "/modify-goods.do", method = RequestMethod.POST)
    public CtResponse modifyGoods(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, String> body) {
        logger.info("req: " + request.getRequestURI());

        return addOrModifyGoods(true, request, response, body);
    }

    @RequestMapping(value = "/remove-goods.do", method = RequestMethod.POST)
    public CtResponse removeGoods(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, String> body) {
        logger.info("req: " + request.getRequestURI());
        String ids = body.get("ids");

        CtResponse result = goodsService.removeGoods(ids);
        return result;
    }

    //
    @RequestMapping(value = "/get-device-goods.do", method = RequestMethod.POST)
    public CtResponse getDeviceGoodsList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, String> body) {
        logger.info("req: " + request.getRequestURI());

        CtResponse result = new CtResponse();

        Long device_id = _AG.toLong(body.get("device_id"));
        String slot = body.get("slot");
        Long goods_id = _AG.toLong(body.get("goods_id"));

        if (device_id == 0) {
            result.setErrCode(ErrorCode.INVALID_PARAMETER);
            return result;
        }
        
        Map<String, Object> mapResult = goodsService.getDeviceGoodsList(device_id, slot, goods_id);
        result.put("result", mapResult);
        return result;
    }
    
    @Transactional
    @RequestMapping(value = "/manage-device-goods.do", method = RequestMethod.POST)
    public CtResponse addOrModifyDeviceGoods(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> body) {
        logger.info("req: " + request.getRequestURI());
        //logger.info("body: " + body);
        //logger.info("prev_device_goods: " + body.get("prev_device_goods"));
        //logger.info("new_device_goods: " + body.get("new_device_goods"));

        CtResponse result = new CtResponse();

        Long device_id =  _AG.toLong((Integer)body.get("device_id"));
        List<Map<String, String>> prev_device_goods = (List<Map<String, String>>)body.get("prev_device_goods");
        List<Map<String, String>> new_device_goods = (List<Map<String, String>>)body.get("new_device_goods");

        Long biz_group_id = _AG.toLong((Integer)body.get("biz_group_id"));
        boolean isSaveTemplate = (boolean)body.get("isSaveTemplate");
        String templateName = (String)body.get("templateName");
        List<Map<String, String>> goods_template_elements = (List<Map<String, String>>)body.get("goods_template_elements");
        Map<String, Object> goods_template_inventory = (Map<String, Object>)body.get("goods_template_inventory");

        if (device_id == null) {
            result.setErrCode(ErrorCode.INVALID_PARAMETER);
            return result;
        }

        try {
            if (prev_device_goods != null && prev_device_goods.size() != 0) {
                goodsService.deleteDeviceGoods(device_id, prev_device_goods);
            }

            if (new_device_goods != null && new_device_goods.size() != 0) {
                result = goodsService.addDeviceGoods(device_id, new_device_goods);
            }
            
            if (isSaveTemplate) {
                result = goodsService.addGoodsTemplate(biz_group_id, templateName, goods_template_inventory, goods_template_elements);
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            result.setErrCode(ErrorCode.INVALID_PARAMETER);
        }
        return result;
    }

    @RequestMapping(value="/get-goods-templates.do", method = RequestMethod.POST)
    public CtResponse getGoodsTemplate(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, String> body) {
        logger.info("req: " + request.getRequestURI());

        CtResponse result = new CtResponse();

        Boolean is_excel = _AG.toBoolean(body.get("is_excel"));
        Long offset= _AG.toLong(body.get("offset"));
        Long limit = _AG.toLong(body.get("limit"));
        if (limit > 100)
            limit = 100L;

        Boolean is_group_access = _AG.toBoolean(body.get("is_group_access"));

        // goods_template_id 가 있으면 하나만 탐색 
        // biz_group_id 가 있으면 모두 탐색
        Long biz_group_id = _AG.toLong(body.get("biz_group_id"));
        Long goods_template_id = _AG.toLong(body.get("goods_template_id"));
        String date_start = body.get("date_start");
        String date_end = body.get("date_end");

        if (biz_group_id == 0 && goods_template_id == 0) {
            result.setErrCode(ErrorCode.INVALID_PARAMETER);
            return result;
        }

        logger.info("biz_group_id: " + biz_group_id);
        logger.info("goods_template_id: " + goods_template_id);

        try {
            Map<String, Object> mapResult;
            if (goods_template_id != 0) {
                mapResult = goodsService.getGoodsTemplateById(goods_template_id);
            }
            else {
                mapResult = goodsService.getGoodsTemplateByBizGroupId(biz_group_id);
            }
            result.put("result", mapResult);
        }
        catch (Exception e) {
            e.printStackTrace();
            result.setErrCode(ErrorCode.INVALID_PARAMETER);
        }

        return result;
    }

    @Transactional
    @RequestMapping(value="/manage-goods-template.do", method = RequestMethod.POST)
    public CtResponse manageGoodsTemplate(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> body) {
        logger.info("req: " + request.getRequestURI());

        CtResponse result = new CtResponse();

        Long biz_group_id = _AG.toLong((Integer)body.get("biz_group_id"));
        Long goods_template_id = _AG.toLong((Integer)body.get("goods_template_id"));
        String goods_template_name = (String)body.get("goods_template_name");
        Map<String, Object> goods_template_inventory = (Map<String, Object>)body.get("goods_template_inventory");
        List<Map<String, String>> goods_template_elements = (List<Map<String, String>>)body.get("goods_template_elements");

        if (biz_group_id == 0) {
            result.setErrCode(ErrorCode.INVALID_PARAMETER);
            return result;
        }

        try {
            if (goods_template_id != 0) {
                result = goodsService.removeGoodsTemplate(goods_template_id);
            }

            result = goodsService.addGoodsTemplate(biz_group_id, goods_template_name, goods_template_inventory, goods_template_elements);
        }
        catch (Exception e) {
            e.printStackTrace();
            result.setErrCode(ErrorCode.INVALID_PARAMETER);
        }

        return result;
    }

    @Transactional
    @RequestMapping(value="/remove-goods-template.do", method = RequestMethod.POST)
    public CtResponse removeGoodsTemplate(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> body) {
        logger.info("req: " + request.getRequestURI());

        CtResponse result = new CtResponse();

        Long goods_template_id = _AG.toLong((Integer)body.get("goods_template_id"));

        if (goods_template_id == null) {
            result.setErrCode(ErrorCode.INVALID_PARAMETER);
            return result;
        }

        try {
            result = goodsService.removeGoodsTemplate(goods_template_id);
        }
        catch (Exception e) {
            e.printStackTrace();
            result.setErrCode(ErrorCode.INVALID_PARAMETER);
        }

        return result;
    }

}
