/*******************************************************************************
 * Copyright 2014 2Fi Business Solutions Ltd.
 *
 * This code is part of the PCS project.
 *
 * This code is copyrighted. Under no circumstances should any party, people,
 * or organization should redistribute any portions of this code in any form,
 * either verbatim or through electronic media, to any third parties, unless
 * under explicit written permission by 2Fi Business Solutions Ltd.
 ******************************************************************************/
package com.ffii.tbms.common.web;

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

import javax.servlet.http.HttpServletRequest;

import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartHttpServletRequest;
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.multipart.MultipartFile;

import com.ffii.core.utils.MapUtils;
import com.ffii.core.utils.Params;
import com.ffii.core.utils.SecurityUtils;
import com.ffii.core.web.AbstractController;
import com.ffii.core.web.view.json.JsonView;
import com.ffii.tbms.common.MaterialBand;
import com.ffii.tbms.common.MaterialItem;
import com.ffii.tbms.common.service.MaterialService;
import com.ffii.tbms.file.FileRefType;
import com.ffii.tbms.file.service.FileService;
import com.ffii.core.utils.web.ServletRequestUtils;


@Controller
@RequestMapping(value = "/common/material")
public class MaterialController extends AbstractController {

	@Autowired
	private MaterialService service;
	
	@Autowired
	private FileService fileService;

	@RequestMapping(value = "/band/save", method = RequestMethod.POST)
	public String bandSave(Model model, HttpServletRequest request,
	 @RequestParam(defaultValue = "-1") Integer id) throws Exception {

		if (SecurityUtils.isGranted("SUPERUSER") 
		|| SecurityUtils.isGranted("PRICE_LIST_MAINTAIN")) {
			MaterialBand instance;
			if (id > 0) {
				instance = service.findBand(id);
			} else {
				instance = new MaterialBand();
			}
			ServletRequestUtils.doBind(request, instance, null);
			id = service.saveOrUpdateBand(instance);
			
			model.addAttribute(Params.ID, id);
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}
		return JsonView.NAME;
	}

	
	@RequestMapping(value = "/band/icon", method =  { RequestMethod.GET, RequestMethod.POST })
	public String getIcon(Model model, HttpServletRequest request,  @RequestParam Integer bandId) throws Exception {

		if (SecurityUtils.isGranted("SUPERUSER")
			|| SecurityUtils.isGranted("PRICE_LIST_VIEW")
			|| SecurityUtils.isGranted("PRICE_LIST_MAINTAIN")) {
			List<Map<String, Object>> list = service.searchBandIcon(bandId);
			model.addAttribute(Params.RECORDS, list);
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}
		return JsonView.NAME;
	}

	@RequestMapping(value = "/band/delete", method = RequestMethod.POST)
	public String bandDelete(Model model, HttpServletRequest request, @RequestParam Integer id) throws Exception {

		if (SecurityUtils.isGranted("SUPERUSER") 
		|| SecurityUtils.isGranted("PRICE_LIST_MAINTAIN")) {

			// find, mark delete, and save
			MaterialBand instance = service.findBand(id);
			instance.setDeleted(true);
			service.saveOrUpdateBand(instance);

			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	@RequestMapping(value = "/band/icon/delete", method = RequestMethod.POST)
	public String bandIconDelete(Model model, HttpServletRequest request, @RequestParam Integer id) throws Exception {

		if (SecurityUtils.isGranted("SUPERUSER") 
		|| SecurityUtils.isGranted("PRICE_LIST_MAINTAIN")) {

			// find, mark delete, and save
			MaterialBand instance = service.findBand(id);

			// search for existing file(s) with the same refType, refId, and filename
			List<Map<String, Object>> existingFiles = fileService.searchFiles(
					MapUtils.toHashMap("refType", FileRefType.BAND_ICON, "refId", id));

			// delete them if found
			for (Map<String, Object> existingFile : existingFiles) {
				fileService.deleteFile((Integer) existingFile.get("id"), (Integer) existingFile.get("refId"),
						(String) existingFile.get("refType"), (String) existingFile.get("skey"));
			}

			instance.setFileId(null);
			service.saveOrUpdateBand(instance);

			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}


	@RequestMapping(value = "/band/list.json", method = { RequestMethod.GET, RequestMethod.POST })
	public String bandList(Model model, HttpServletRequest request) throws Exception {

		if (SecurityUtils.isGranted("SUPERUSER")
			|| SecurityUtils.isGranted("PRICE_LIST_VIEW")
			|| SecurityUtils.isGranted("PRICE_LIST_MAINTAIN")) {
	
			List<Map<String, Object>> list = service.searchBands();
			model.addAttribute(Params.RECORDS, list);
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}
		return JsonView.NAME;
	}

	@RequestMapping(value = "/band/load", method = { RequestMethod.GET, RequestMethod.POST })
	public String loadBand(Model model, HttpServletRequest request, @RequestParam Integer id) throws Exception {

		if (SecurityUtils.isGranted("SUPERUSER")
			|| SecurityUtils.isGranted("PRICE_LIST_VIEW")
			|| SecurityUtils.isGranted("PRICE_LIST_MAINTAIN")) {

			Map<String, Object> data = service.loadBand(id);

			model.addAttribute(Params.DATA, data);
			model.addAttribute(Params.SUCCESS, data != null);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	
	@RequestMapping(value = "/item/save", method = RequestMethod.POST)
	public String itemSave(Model model, HttpServletRequest request, @RequestParam(defaultValue = "-1") Integer id) throws Exception {

		if (SecurityUtils.isGranted("SUPERUSER")
			|| SecurityUtils.isGranted("PRICE_LIST_MAINTAIN")) {
			MaterialItem instance;
			if (id > 0) {
				instance = service.findItem(id);
			} else {
				instance = new MaterialItem();
			}
			ServletRequestUtils.doBind(request, instance, null);
			id = service.saveOrUpdateBandItem(instance);

			
			model.addAttribute(Params.ID, id);
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}
		return JsonView.NAME;
	}

	@RequestMapping(value = "/item/delete", method = RequestMethod.POST)
	public String itemDelete(Model model, HttpServletRequest request, @RequestParam Integer id) throws Exception {

		if (SecurityUtils.isGranted("SUPERUSER")
			|| SecurityUtils.isGranted("PRICE_LIST_MAINTAIN")) {

			// find, mark delete, and save
			MaterialItem instance = service.findItem(id);
			instance.setDeleted(true);
			service.saveOrUpdateBandItem(instance);

			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	@RequestMapping(value = "/item/list.json", method =  { RequestMethod.GET, RequestMethod.POST })
	public String itemList(Model model, HttpServletRequest request,  @RequestParam Integer bandId) throws Exception {

		if (SecurityUtils.isGranted("SUPERUSER")
			|| SecurityUtils.isGranted("PRICE_LIST_VIEW")
			|| SecurityUtils.isGranted("PRICE_LIST_MAINTAIN")) {
			List<Map<String, Object>> list = service.searchBandItems(bandId);
			model.addAttribute(Params.RECORDS, list);
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}
		return JsonView.NAME;
	}

	
	@RequestMapping(value = "/item/load", method = { RequestMethod.GET, RequestMethod.POST })
	public String loadItem(Model model, HttpServletRequest request, @RequestParam Integer id) throws Exception {

		if (SecurityUtils.isGranted("SUPERUSER")
			|| SecurityUtils.isGranted("PRICE_LIST_VIEW")
			|| SecurityUtils.isGranted("PRICE_LIST_MAINTAIN")) {
			Map<String, Object> data = service.loadBandItem(id);

			model.addAttribute(Params.DATA, data);
			model.addAttribute(Params.SUCCESS, data != null);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	
	@RequestMapping(value = "/item/import", method = { RequestMethod.GET, RequestMethod.POST })
	public String ImportItem(Model model, HttpServletRequest request) throws Exception {

		if (SecurityUtils.isGranted("SUPERUSER")
			|| SecurityUtils.isGranted("PRICE_LIST_VIEW")
			|| SecurityUtils.isGranted("PRICE_LIST_MAINTAIN")) {

			MultipartFile multipartFile = ((MultipartHttpServletRequest) request).getFile("multipartFile");
			Assert.notNull(multipartFile, "multipartFile cannot be null!");
			Workbook wb = null;
			try {
				wb = new XSSFWorkbook(multipartFile.getInputStream());
			} catch (final OfficeXmlFileException oe) {
				logger.warn("wb is xlsx, ignored");
			}
			Assert.notNull(wb, "Workbook cannot be null!");


			model.addAttribute(Params.SUCCESS, service.importDataFromExcel(wb));
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}
	@RequestMapping(value = "/item/set-orderIdx", method = { RequestMethod.GET, RequestMethod.POST })
	public String setOrderIdx(Model model, HttpServletRequest request) throws Exception {

		if (SecurityUtils.isGranted("SUPERUSER")
			|| SecurityUtils.isGranted("PRICE_LIST_VIEW")
			|| SecurityUtils.isGranted("PRICE_LIST_MAINTAIN")) {

			List<Map<String, Integer>> id_orderIdx = (List<Map<String, Integer>>) ServletRequestUtils.getJsonListParameter(request, "id_orderIdx");
			
			for(Map<String, Integer> item: id_orderIdx){
				service.updateItemOrderIdx(item.get("id"), item.get("orderIdx"));
			}

			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

}
