/*******************************************************************************
 * 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.customer.web;

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

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.StandardPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.ffii.core.utils.CriteriaUtils;
import com.ffii.core.utils.NumberUtils;
import com.ffii.core.utils.Params;
import com.ffii.core.utils.SecurityUtils;
import com.ffii.core.utils.web.ServletRequestUtils;
import com.ffii.core.web.AbstractController;
import com.ffii.core.web.view.json.JsonView;
import com.ffii.tbms.customer.Customer;
import com.ffii.tbms.customer.service.CustomerService;
import com.ffii.tbms.file.FileRefType;
import com.ffii.tbms.file.service.FileService;
import com.ffii.tbms.log.LogUtils;
import com.ffii.tbms.order.Order;
import com.ffii.tbms.order.service.OrderService;

@Controller
@RequestMapping(value = "/customer")
public class CustomerController extends AbstractController {

	@Autowired
	private CustomerService customerService;

	@Autowired
	private FileService fileService;

	@Autowired
	private OrderService orderService;

	@Autowired
	private StandardPasswordEncoder passwordEncoder;

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

		if (SecurityUtils.isGranted("CUSTOMER_MAINTAIN")) {
			Customer instance;
			if (id > 0) {
				instance = customerService.find(id);
			} else {
				instance = new Customer();
			}

			ServletRequestUtils.doBind(request, instance, null);
			id = customerService.saveOrUpdate(instance);

			model.addAttribute(Params.ID, id);

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

		return JsonView.NAME;
	}

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

		if (SecurityUtils.isGranted("CUSTOMER_MAINTAIN") && SecurityUtils.isGranted("CUSTOMER_DELETE")) {

			// find, mark delete, and save
			Customer instance = customerService.find(id);
			instance.setDeleted(true);
			customerService.saveOrUpdate(instance);

			List<Map<String, Object>> orderList = customerService.getRelatedOrder(id);
			for(Map<String, Object> o : orderList){
				orderService.deletedOrder(NumberUtils.intValue(o.get("id"), 0));
			}


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

		return JsonView.NAME;
	}

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

		if (SecurityUtils.isGranted("CUSTOMER_MAINTAIN")) {
			Map<String, Object> data = customerService.queryForMap(id);

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

		return JsonView.NAME;
	}

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

		Map<String, Object> args = new HashMap<String, Object>();

		CriteriaUtils.addInteger(request, args, Params.ID);
		CriteriaUtils.addStringLike(request, args, Params.QUERY);
		CriteriaUtils.addInteger(request, args, "deptId");

		List<Map<String, Object>> records = customerService.searchForCombo(args);

		model.addAttribute(Params.RECORDS, records);

		return JsonView.NAME;
	}

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

		if (SecurityUtils.isGranted("CUSTOMER_MAINTAIN")) {
			Map<String, Object> args = new HashMap<String, Object>();

			CriteriaUtils.addStringLike(request, args, Params.QUERY);

			CriteriaUtils.addInteger(request, args, Params.ID);
			CriteriaUtils.addString(request, args, "surname");
			CriteriaUtils.addString(request, args, "firstName");
			CriteriaUtils.addString(request, args, "nameCh");
			CriteriaUtils.addStringLike(request, args, "contact");
			CriteriaUtils.addStringLike(request, args, "email");
			CriteriaUtils.addBoolean(request, args, "onHand");
			CriteriaUtils.addBoolean(request, args, "balance");
			CriteriaUtils.addString(request, args, "orderType");
			CriteriaUtils.addStringLike(request, args, "orderCode");
			CriteriaUtils.addDate(request, args, "fromDate");
			CriteriaUtils.addDateTo(request, args, "toDate");
			CriteriaUtils.addString(request, args, "tag");

			CriteriaUtils.addInteger(request, args, "start");
			CriteriaUtils.addInteger(request, args, "limit");

			if(args.containsKey("surname")){
				args.put("_surname", args.get("surname"));
				args.put("surname", "%"+args.get("surname")+"%");
			}

			if(args.containsKey("firstName")){
				args.put("_firstName", args.get("firstName"));
				args.put("firstName", "%"+args.get("firstName")+"%");
			}

			if(args.containsKey("nameCh")){
				args.put("_nameCh", args.get("nameCh"));
				args.put("nameCh", "%"+args.get("nameCh")+"%");
			}

			args.put("today", new Date());

			if(args.containsKey("tag")){
				String str = args.get("tag").toString().trim();
				List<String> strList = Arrays.asList(str.split(""));
				if(strList != null && strList.size()>0){
					for(String s: strList){
						
					}
				}else{
					args.remove("tag");	
				}
			}

			List<Map<String, Object>> records = customerService.search(args);
			Map<String, Object> count = customerService.countSearch(args);

			model.addAttribute(Params.RECORDS, records);
			model.addAttribute("total", NumberUtils.intValue(count.get("count")));
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

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

		if (SecurityUtils.isGranted("CUSTOMER_MAINTAIN")) {
			Map<String, Object> args = new HashMap<String, Object>();
			args.put("refType", FileRefType.CUSTOMER);
			args.put("refId", id);

			List<Map<String, Object>> records = fileService.searchFiles(args);

			model.addAttribute(Params.RECORDS, records);
			model.addAttribute("title", "Customer Photo");
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}
		return JsonView.NAME;
	}

	@RequestMapping(value = "/order-list", method = { RequestMethod.GET, RequestMethod.POST })
	public String orderListJson(Model model, HttpServletRequest request, @RequestParam Integer custId) throws Exception {

		if (SecurityUtils.isGranted("CUSTOMER_MAINTAIN")) {
			Map<String, Object> args = new HashMap<String, Object>();
			args.put("custId", custId);
			CriteriaUtils.addInteger(request, args, "ignoreOrderId");

			Map<String, Object> records = customerService.getOrderIds(args);

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

	@RequestMapping(value = "/get-auth", method = { RequestMethod.POST })
	public String getDeleteAuth(Model model, HttpServletRequest request, @RequestParam String v) throws Exception {

		if (SecurityUtils.isGranted("CUSTOMER_MAINTAIN")) {
			
			if(passwordEncoder.matches(v, SecurityUtils.getUser().getPassword()))
				model.addAttribute(Params.SUCCESS, Boolean.TRUE);
			else
				model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}
		return JsonView.NAME;
	}

}
