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

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

import javax.servlet.http.HttpServletRequest;

import com.ffii.core.utils.CriteriaUtils;
import com.ffii.core.utils.DateUtils;
import com.ffii.core.utils.MapUtils;
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.meeting.Meeting;
import com.ffii.tbms.meeting.service.MeetingService;

import org.springframework.beans.factory.annotation.Autowired;
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;

@Controller
@RequestMapping(value = "/meeting")
public class MeetingController extends AbstractController {

	@Autowired
	private MeetingService meetingService;

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

		if (SecurityUtils.isGranted("MEETING_MAINTAIN")) {
			Meeting instance;
			if (id > 0) {
				instance = meetingService.find(id);
			} else {
				instance = new Meeting();
			}

			ServletRequestUtils.doBind(request, instance, null);
			id = meetingService.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("MEETING_MAINTAIN") && SecurityUtils.isGranted("MEETING_DELETE")) {

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

			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("MEETING_MAINTAIN")) {
			Map<String, Object> data = meetingService.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 = "/list.json", method = { RequestMethod.GET, RequestMethod.POST })
	public String listJson(Model model, HttpServletRequest request) throws Exception {

		if (SecurityUtils.isGranted("MEETING_MAINTAIN") || SecurityUtils.isGranted("CALENDAR_VIEW")
			|| 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.addInteger(request, args, "custId");
			CriteriaUtils.addInteger(request, args, "orderId");
			CriteriaUtils.addDate(request, args, "fromDate");
			CriteriaUtils.addDateTo(request, args, "toDate");
			CriteriaUtils.addDate(request, args, "meetingDate");
			CriteriaUtils.addBoolean(request, args, "isDESC");

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

			List<Map<String, Object>> records = meetingService.search(args);
			Map<String, Object> count = meetingService.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 = "/calendar.json", method = { RequestMethod.GET, RequestMethod.POST })
	public String calendarsJson(Model model, HttpServletRequest request, @RequestParam int month,
			@RequestParam int year) throws Exception {

		Calendar monthCalendar = Calendar.getInstance();
		monthCalendar.setTime(DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH));
		monthCalendar.set(Calendar.DAY_OF_MONTH, 1);
		monthCalendar.set(Calendar.MONTH, month - 1);
		monthCalendar.set(Calendar.YEAR, year);

		Date firstDateOfMonth = DateUtils.getFirstDateOfMonthByYearAndMonth(year, month);
		Date lastDateOfMonth = DateUtils.getLastDateOfMonthByYearAndMonth(year, month);

		List<Map<String, Object>> meetingData = meetingService
				.searchForCalendar(MapUtils.toHashMap("fromDate", firstDateOfMonth, "toDate", lastDateOfMonth));

		logger.info("meetingData:"+meetingData);

		List<Map<String, Object>> monthRecord = new ArrayList<>();
		int weekIdx = 1; // row index
		while (monthCalendar.getTime().before(lastDateOfMonth)) {
			Map<String, Object> weekRecord = new HashMap<>();

			for (int i = 1; i <= 7; i++) { // column index
				Integer day = null;
				if (monthCalendar.get(Calendar.DAY_OF_WEEK) == i && monthCalendar.get(Calendar.MONTH) < month
						&& monthCalendar.get(Calendar.YEAR) == year) {
					day = monthCalendar.get(Calendar.DAY_OF_MONTH);

					for (Map<String, Object> data : meetingData) {
						Date meetingDate = (Date) data.get("date");
						if (meetingDate.equals(monthCalendar.getTime())) {
							weekRecord.put("col_" + i + "_commission", data.get("commission"));
							weekRecord.put("col_" + i + "_fitting", data.get("fitting"));
							weekRecord.put("col_" + i + "_pickup", data.get("pickup"));
							weekRecord.put("col_" + i + "_new", data.get("new"));
						}
					}

					weekRecord.put("col_" + i, monthCalendar.getTime());
					weekRecord.put("col_" + i + "_clickable", true);
					monthCalendar.add(Calendar.DAY_OF_MONTH, 1);
				} else {
					weekRecord.put("col_" + i, null);
					weekRecord.put("col_" + i + "_clickable", false);
				}
				weekRecord.put("col_" + i + "_day", day);
			}
			weekRecord.put("id", weekIdx++);
			monthRecord.add(weekRecord);
		}

		model.addAttribute(Params.SUCCESS, Boolean.TRUE);

		model.addAttribute(Params.RECORDS, monthRecord);
		return JsonView.NAME;
	}

	@RequestMapping(value = "/calendar-type", method = { RequestMethod.GET, RequestMethod.POST })
	public String requestMethodName(Model model, HttpServletRequest request, @RequestParam int param,
			@RequestParam int year) {

		return JsonView.NAME;
	}

}
