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

import java.util.ArrayList;
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.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.BooleanUtils;
import com.ffii.core.utils.CriteriaUtils;
import com.ffii.core.utils.JsonUtils;
import com.ffii.core.utils.Params;
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.user.Group;
import com.ffii.tbms.user.service.GroupService;
import com.ffii.tbms.user.service.AuthService;

@Controller
@RequestMapping(value = "/user/group")
public class GroupController extends AbstractController {

	@Autowired
	private GroupService groupService;

	@Autowired
	private AuthService authService;

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

		Group instance;
		if (id > 0) {
			instance = groupService.find(id);
		} else {
			instance = new Group();
		}

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

		// Handle Group User
		if (userUpdatedRecordsData != null) {
			List<Map<String, Object>> userUpdatedRecords = JsonUtils.fromJsonStringAsListOfMap(userUpdatedRecordsData);

			List<Map<String, Object>> userBatchInsertValues = new ArrayList<Map<String, Object>>();
			List<Map<String, Object>> userBatchDeleteValues = new ArrayList<Map<String, Object>>();

			for (Map<String, Object> record : userUpdatedRecords) {
				Map<String, Object> batchValue = new HashMap<String, Object>(2);
				batchValue.put("groupId", id);
				batchValue.put("userId", record.get("id"));

				if (BooleanUtils.isTrue(record.get("v"))) {
					userBatchInsertValues.add(batchValue);
				} else {
					userBatchDeleteValues.add(batchValue);
				}
			}

			if (userBatchInsertValues.size() > 0)
				groupService.addGroupUser(userBatchInsertValues.toArray((Map<String, Object>[]) new Map[0]));
			if (userBatchDeleteValues.size() > 0)
				groupService.removeGroupUser(userBatchDeleteValues.toArray((Map<String, Object>[]) new Map[0]));
		}

		// Handle Group Authority
		if (authUpdatedRecordsData != null) {
			List<Map<String, Object>> authUpdatedRecords = JsonUtils.fromJsonStringAsListOfMap(authUpdatedRecordsData);

			List<Map<String, Object>> authBatchInsertValues = new ArrayList<Map<String, Object>>();
			List<Map<String, Object>> authBatchDeleteValues = new ArrayList<Map<String, Object>>();

			for (Map<String, Object> record : authUpdatedRecords) {
				Map<String, Object> batchValue = new HashMap<String, Object>(2);
				batchValue.put("groupId", id);
				batchValue.put("authority", record.get("authority"));

				if (BooleanUtils.isTrue(record.get("v"))) {
					authBatchInsertValues.add(batchValue);
				} else {
					authBatchDeleteValues.add(batchValue);
				}
			}

			if (authBatchInsertValues.size() > 0)
				groupService.addGroupAuth(authBatchInsertValues.toArray((Map<String, Object>[]) new Map[0]));
			if (authBatchDeleteValues.size() > 0)
				groupService.removeGroupAuth(authBatchDeleteValues.toArray((Map<String, Object>[]) new Map[0]));
		}

		model.addAttribute(Params.ID, id);

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

		return JsonView.NAME;
	}

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

			// find, mark delete, and save
			Group instance = groupService.find(id);
			groupService.delete(instance);

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

		return JsonView.NAME;
	}



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

		Map<String, Object> data = groupService.queryForMap(id);

		model.addAttribute(Params.DATA, data);
		model.addAttribute(Params.SUCCESS, data != null);

		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);

		List<Map<String, Object>> records = groupService.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 {

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

		CriteriaUtils.addInteger(request, args, Params.ID);
		CriteriaUtils.addStringLike(request, args, Params.NAME);
		CriteriaUtils.addInteger(request, args, "userId");
		

		List<Map<String, Object>> records = groupService.search(args);

		model.addAttribute(Params.RECORDS, records);

		return JsonView.NAME;
	}


	/**
	 * @param id groupId
	 */
	@RequestMapping(value = "/user.json", method = { RequestMethod.GET, RequestMethod.POST })
	public String jsonUser(Model model, HttpServletRequest request, @RequestParam(defaultValue = "-1") Integer id)
			throws Exception {

		if (id > 0) {
			List<Map<String, Object>> records = groupService.listGroupUser(id);

			model.addAttribute(Params.RECORDS, records);
			model.addAttribute(Params.SUCCESS, records != null);
		} else
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		return JsonView.NAME;
	}

	@RequestMapping(value = "/auth.json", method = { RequestMethod.GET, RequestMethod.POST })
	public String jsonAuth(Model model, HttpServletRequest request) throws Exception {
		// Map<String, Object> args = new HashMap<String, Object>();
		int groupId = ServletRequestUtils.getIntParameter(request, Params.ID, 0);

		List<Map<String, Object>> records = groupService.listGroupAuth(groupId);

		model.addAttribute(Params.RECORDS, records);
		model.addAttribute(Params.SUCCESS, records != null);
		return JsonView.NAME;
	}

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

		List<Map<String, Object>> records = authService.list();

		model.addAttribute(Params.RECORDS, records);

		return JsonView.NAME;
	}
}
