package nlib.col.web;

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

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import nlib.cmm.NlibCommonController;
import nlib.cmm.service.NlibProperty;
import nlib.col.service.CartService;
import nlib.col.service.CollectionService;
import nlib.col.service.CollectionVO;
import nlib.util.StringUtil;

/**
 * <pre>
 * @Class Name : CartController.java
 * 
 * @Description : 소장자료 카트 컨트롤러
 * 로그인하지 않은 사용자도 카트 추가 가능하며, 추가 시 정보가 저장되는 영역은 다음과 같다.
 * - 비회원 카트정보 쿠키 저장 
 * - 회원 카트정보 DB 저장 
 * 
 * 
 * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
 *
 * </pre>
 *
 * @ ------------    --------    ---------------------------
 * @ 수정일                     수정자             수정내용
 * @ ------------    --------    ---------------------------
 * @ 2021. 10. 5.    KNKIM       최초 생성
 *
 * 
 * @author 이씨플라자 * DIGITALSHIP KNKIM
 * @since 2021. 10. 5.
 * @version 1.0
 *
 */
@Controller
public class CartController extends NlibCommonController
{
    private static final Logger log = LoggerFactory.getLogger(CartController.class);
    static final String DEFUALT_PAGE_SIZE = NlibProperty.getProperty("list.paging.page.size");
    
    @Resource(name = "cartService")
    private CartService cartService;

    @Resource(name = "collectionService") 
    private CollectionService collectionService;

    /**
     * 카트 목록을 조회한다. 
     * 로그인되지 않은 사용자의 경우, 쿠키에 저장된 값으로 처리한다. 
     * 
     * @param request
     * @param cartTyp
     * eCd
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping(value= {"/cart/listCartItems.do", "/login/listCartItems.do"})
    public String listCartItems(HttpServletRequest request, HttpServletResponse response, String message, String cartTypeCd, ModelMap model) throws Exception {
    	
		if(StringUtil.isEmpty(cartTypeCd)) cartTypeCd = "1"; // 대출 기본 설정
		
		String mbInfoId = getMbInfoId(request);
		
		List<CollectionVO> list = null;
		int cartTypeCd1Cnt = 0; // 대출 카트건수 
		int cartTypeCd2Cnt = 0; // 열람 카트건수
		
		// 카트 목록 가져오기 
		if(StringUtil.isEmpty(mbInfoId)) {
			// 쿠키에서 값 가져오기 
			list = cartService.listCartItemsFromCookie(request, response, cartTypeCd);
			
			// 카트 목록 자료에 대한 상세자료 설정 
			collectionService.setDetailInfoForList(list, null, NlibProperty.getString("thumbnail.image.url.small"));

			// 문화원별 정렬 처리
			list = sortCollectionListByMngOrgCd(list);
			
			// 카트 건수 
			cartTypeCd1Cnt = cartService.countCartItemsFromCookie(request, response, "1");
			cartTypeCd2Cnt = cartService.countCartItemsFromCookie(request, response, "2");
			
		} else {
			list = cartService.listCartItems(mbInfoId, cartTypeCd);
			
			// 카트 목록 자료에 대한 상세자료 설정 
			collectionService.setDetailInfoForList(list, getMbInfoId(request), NlibProperty.getString("thumbnail.image.url.small"));
			
			// 카트 건수 
			cartTypeCd1Cnt = cartService.countCartItems(mbInfoId, "1");
			cartTypeCd2Cnt = cartService.countCartItems(mbInfoId, "2");
		}
		
		if(StringUtil.isNotEmpty(message) && message.startsWith("%")) {
			message = StringUtil.decodeUrl(message);
		}
		
		model.addAttribute("cartTypeCd1Cnt", cartTypeCd1Cnt);
		model.addAttribute("cartTypeCd2Cnt", cartTypeCd2Cnt);
		
		model.addAttribute("list", list);
    	model.addAttribute("cartTypeCd", cartTypeCd);
    	model.addAttribute("message", message);
    	
    	return "nlib/cart/listCartItems";
    }
    
    /**
     * 자료 목록을 문화원별로 정렬하여 리턴한다. 
     * 
     * @param list
     * @return
     */
    public List<CollectionVO> sortCollectionListByMngOrgCd(List<CollectionVO> list) {
    	
    	if(list == null || list.size() < 1) return list;
    	
    	Map<String, List<CollectionVO>> orgMap = new HashMap<String, List<CollectionVO>>();
    	
    	for(CollectionVO vo : list) {
    		String mngOrgCd = vo.getMngOrgCd();
    		
    		if(StringUtil.isEmpty(mngOrgCd)) {
    			mngOrgCd = "NONE";
    			vo.setMngOrgCd(mngOrgCd);
    			vo.setMngOrgNm("(없음)");
    		}
    		List<CollectionVO> orgList = orgMap.get(mngOrgCd);
    		if(orgList == null) {
    			orgList = new ArrayList<CollectionVO>();
    		}
    		
    		orgList.add(vo);
    		
    		orgMap.put(mngOrgCd, orgList);
    	}
    	
    	List<CollectionVO> retList = new ArrayList<CollectionVO>();
    	for(String key : orgMap.keySet()) {
    		List<CollectionVO> orgList = orgMap.get(key);
    		
    		for(CollectionVO vo : orgList) {
    			retList.add(vo);
    		}
    	}
    	
    	return retList;
    }

    /**
     * 카트 영역 구분코드를 변경한다. (대출 <-> 방문열람)
     * 
     * @param request
     * @param cartVO
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("/cart/changeCartType.do")
    public String changeCartType(HttpServletRequest request, HttpServletResponse response, CollectionVO cartVO, ModelMap model) throws Exception {
    	
    	String message = null;
		String mbInfoId = getMbInfoId(request);
		
		if(StringUtil.isEmpty(mbInfoId)) {
			message = cartService.changeCartTypeToCookie(request, response, cartVO);
		} else {
			cartVO.setMbInfoId(getMbInfoId(request));
			message = cartService.changeCartType(cartVO);
		}
		
		if(message == null) message = "정상적으로 변경되었습니다.";
    	model.addAttribute("message", StringUtil.encodeUrl(message));
    	model.addAttribute("cartTypeCd", cartVO.getCartTypeCd());
    	return "redirect:/cart/listCartItems.do"; 
    }

    /**
     * 카트에 추가한다. 
     * 
     * @param request
     * @param cartVO
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("/cart/insertCartItemAjax.do")
    public ResponseEntity<String> insertCartItemAjax(HttpServletRequest request, HttpServletResponse response, @RequestBody CollectionVO cartVO, ModelMap model) throws Exception {
    	
    	log.debug("insertCartItemAjax > masterId = " + cartVO.getMasterId());

    	String code = "S";
    	String message = null;
    			
		String mbInfoId = getMbInfoId(request);
		
		int changedCnt = 0; 
		
		try {
			
			// 로그인한 경우 
			if(!StringUtil.isEmpty(mbInfoId)) {
				log.debug("insertCartItemAjax > masterId = " + cartVO.getMasterId());
				log.debug("insertCartItemAjax > cartDivCd = " + cartVO.getCartTypeCd());
				cartVO.setMbInfoId(mbInfoId);
				cartVO.setRegId(mbInfoId);
				message = cartService.insertCartItem(cartVO);
			}
			// 비회원인 경우 
			else {
				message = cartService.insertCartItemToCookie(request, response, cartVO);
			}
			
			if(message == null) {
				code = "S";
				message = "정상적으로 추가되었습니다.";
			} else {
				code = "F";
			}
			
		} catch(Exception e) {
			code = "F";
			message = "등록되지 않았습니다. : " + e.toString();
		}

		
		//-------------------------------
		// JSON변환 응답 처리
		//-------------------------------
    	// JS-GRID 페이징 처리를 포함한 응답값 처리
    	// {data: [{...}], 
    	//  itemsCount: 255
    	// }
    	HashMap<String, Object> retMap = new HashMap<String, Object>();
    	retMap.put("code", code);
    	retMap.put("message", message);
    	
    	return makeResponseEntityJson(retMap);
    }
    
    @RequestMapping("/cart/deleteCartItems.do")
    public String deleteCartItems(HttpServletRequest request, HttpServletResponse response, CollectionVO cartVO, ModelMap model) throws Exception {
    	String mbInfoId = getMbInfoId(request);
    	cartVO.setMbInfoId(mbInfoId);
    	String message = null;
    	
    	if(!StringUtil.isEmpty(mbInfoId)) {
    		message = cartService.deleteCartItems(cartVO);
    	} else {
    		message = cartService.deleteCartItemsFromCookie(request, response, cartVO);
    	}
		
    	if(message == null) message = "정상적으로 삭제되었습니다.";
    	model.addAttribute("message", StringUtil.encodeUrl(message));
    	return "redirect:/cart/listCartItems.do"; 
    }
    
    /**
     * 비로그인시 카트에 저장된 내역을 로그인한 후 해당 사용자의 카트로 저장하고, 쿠키 카트내용은 초기화한다.  
     * 
     * @param request
     * @param model
     * @return
     * @throws Exception
     */
    @Secured("ROLE_USER")
    @RequestMapping("/cart/mergeCartItemsAjax.do")
    public ResponseEntity<String> mergeCartItemsAjax(HttpServletRequest request, HttpServletResponse response, ModelMap model) throws Exception {
    	
		String mbInfoId = getMbInfoId(request);
		int mergedCnt = 0;
		
		if(StringUtil.isEmpty(mbInfoId)) mergedCnt = -1;
		else mergedCnt = cartService.mergeCart(mbInfoId, request, response);
    	
    	HashMap<String, Object> retMap = new HashMap<String, Object>();
    	retMap.put("mergedCnt", mergedCnt);
    	
    	return makeResponseEntityJson(retMap);
    }
    
}