package com.ffii.tbms.api.web;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
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.NumberUtils;
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.api.service.AuthenticationService;
import com.ffii.tbms.api.service.MeetingApiService;
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.ServletRequestBindingException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping(value = "api/meeting/")
/**
 * OrderApiController
 */
public class MeetingApiController extends AbstractController {

    @Autowired
    MeetingApiService service;

    @Autowired
    AuthenticationService authenticationService;

    @Autowired
    private MeetingService meetingService;


    @RequestMapping(value = "list.json", method = { RequestMethod.GET, RequestMethod.POST })
    public String getMeetingJson(Model model, @RequestParam String deviceId, @RequestParam String token, HttpServletRequest request) throws ServletRequestBindingException {

        Map<String, Object> userData = authenticationService.findUserByAccessToken(deviceId, token);
        if (userData == null) {
            model.addAttribute(Params.AUTH, Boolean.FALSE);
            model.addAttribute(Params.SUCCESS, Boolean.FALSE);
            return JsonView.NAME;
        }

        /*
        Calendar formMonthCalendar = Calendar.getInstance();
        formMonthCalendar.setTime(DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH));
        formMonthCalendar.set(Calendar.DAY_OF_MONTH, 1);
        formMonthCalendar.set(Calendar.MONTH, fromMonth);
        formMonthCalendar.set(Calendar.YEAR, year);

        Calendar toMonthCalendar = Calendar.getInstance();
        toMonthCalendar.setTime(DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH));
        toMonthCalendar.set(Calendar.DAY_OF_MONTH, 1);
        toMonthCalendar.set(Calendar.MONTH, toMonth);
        toMonthCalendar.set(Calendar.YEAR, year);
        */

        Map<String, Object> args = new HashMap();
        CriteriaUtils.addDate(request, args, "fromDate");
        CriteriaUtils.addDate(request, args, "toDate");
        
        //toDo remove
        CriteriaUtils.addInteger(request, args, "fromMonth");
        CriteriaUtils.addInteger(request, args, "toMonth");
        CriteriaUtils.addInteger(request, args, "year");
        
        Date firstDateOfMonth=null, lastDateOfMonth=null;

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

        if(args.containsKey("fromDate") && args.containsKey("toDate")){
            firstDateOfMonth = (Date)args.get("fromDate");
            lastDateOfMonth = (Date)args.get("toDate");
        }else if(args.containsKey("fromMonth") && args.containsKey("toMonth") && args.containsKey("year")){
            logger.info("fromMonth:"+args.get("fromMonth")+", toMonth:"+args.get("toMonth")+", year:"+args.get("year"));
            logger.info("year:"+Integer.parseInt(args.get("year").toString()));
            logger.info("fromMonth:"+Integer.parseInt(args.get("fromMonth").toString()));
            firstDateOfMonth = DateUtils.getFirstDateOfMonthByYearAndMonth(Integer.parseInt(args.get("year").toString()), Integer.parseInt(args.get("fromMonth").toString()));
            lastDateOfMonth = DateUtils.getLastDateOfMonthByYearAndMonth(Integer.parseInt(args.get("year").toString()), Integer.parseInt(args.get("toMonth").toString()));
        }else{
            model.addAttribute(Params.AUTH, Boolean.TRUE);
            model.addAttribute(Params.DATA, new HashMap<>());
            model.addAttribute(Params.SUCCESS, Boolean.TRUE);
    
            //todo remove
            model.addAttribute(Params.RECORDS, new ArrayList<>());
    
            return JsonView.NAME;
        }

        logger.info(firstDateOfMonth.getTime());
        logger.info(lastDateOfMonth.getTime());

        List<Map<String, Object>> records = new ArrayList<>();
        Map<String, Object> dayMap = new HashMap<>();
        while (DateUtils.isEarlierThan(firstDateOfMonth, lastDateOfMonth)) {
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String dateStr = dateFormat.format(firstDateOfMonth);
            List<Map<String, Object>> events = service.searchMeeting(dateStr);
            dayMap.put(dateStr, events);
            firstDateOfMonth = DateUtils.addDays(firstDateOfMonth, 1);
        }

        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String dateStr = dateFormat.format(lastDateOfMonth);
            List<Map<String, Object>> events = service.searchMeeting(dateStr);
            dayMap.put(dateStr, events);
            
        records.add(dayMap);
        model.addAttribute(Params.AUTH, Boolean.TRUE);
        model.addAttribute(Params.DATA, dayMap);
        model.addAttribute(Params.SUCCESS, Boolean.TRUE);

        //todo remove
        model.addAttribute(Params.RECORDS, records);

        return JsonView.NAME;
    }

    @RequestMapping(value = "selected-list.json", method = { RequestMethod.GET, RequestMethod.POST })
    public String getMeetingSelectedJson(Model model, @RequestParam String deviceId, @RequestParam String token, HttpServletRequest request,
            @RequestParam Date selectedDate) throws ServletRequestBindingException {

        Map<String, Object> userData = authenticationService.findUserByAccessToken(deviceId, token);
        if (userData == null) {
            model.addAttribute(Params.AUTH, Boolean.FALSE);
            model.addAttribute(Params.SUCCESS, Boolean.FALSE);
            return JsonView.NAME;
        }

        Map<String, Object> args = new HashMap<>();
        CriteriaUtils.addDate(request, args, "selectedDate");

        List<Map<String, Object>> searchMeetingByDate = service.searchMeetingByDate(args);

        model.addAttribute(Params.AUTH, Boolean.TRUE);
        model.addAttribute(Params.RECORDS, searchMeetingByDate);
        model.addAttribute(Params.SUCCESS, Boolean.TRUE);

        return JsonView.NAME;
    }

    @RequestMapping(value = "load", method = { RequestMethod.GET, RequestMethod.POST })
    public String loadMeeting(Model model, @RequestParam String deviceId, @RequestParam String token, HttpServletRequest request,
            @RequestParam int id) throws ServletRequestBindingException {

        Map<String, Object> userData = authenticationService.findUserByAccessToken(deviceId, token);
        if (userData == null) {
            model.addAttribute(Params.AUTH, Boolean.FALSE);
            model.addAttribute(Params.SUCCESS, Boolean.FALSE);
            return JsonView.NAME;
        }

        Map<String, Object> args = new HashMap<>();
        args.put("id", id);

        Map<String, Object> data = service.loadMeeting(args);

        model.addAttribute(Params.AUTH, Boolean.TRUE);
        model.addAttribute(Params.DATA, data);
        model.addAttribute(Params.SUCCESS, Boolean.TRUE);

        return JsonView.NAME;
    }

    @RequestMapping(value = "save", method = { RequestMethod.GET, RequestMethod.POST })
    public String saveMeeting(Model model, @RequestParam String deviceId, @RequestParam String token, HttpServletRequest request,
            @RequestParam(defaultValue = "-1") Integer id) {

        Map<String, Object> userData = authenticationService.findUserByAccessToken(deviceId, token);
        if (userData == null) {
            model.addAttribute(Params.AUTH, Boolean.FALSE);
            model.addAttribute(Params.SUCCESS, Boolean.FALSE);
            return JsonView.NAME;
        }

        boolean haveAuth = authenticationService.haveAuth( userData.get("id"), "MEETING_MAINTAIN");
        if (!haveAuth) {
            model.addAttribute(Params.AUTH, Boolean.FALSE);
            model.addAttribute(Params.SUCCESS, Boolean.FALSE);
            return JsonView.NAME;
        } 

        Meeting instance;
        if (id > 0) {
            instance = meetingService.find(id);
            logger.info("meeting found");
        } else {
            instance = new Meeting();
            instance.setSysGroupId(NumberUtils.toInt(userData.get("sysGroupId"),0));
        }

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

        logger.info("Meeting Save: "+request.getParameter("date"));

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

        return JsonView.NAME;
    }

    @RequestMapping(value = "delete", method = { RequestMethod.GET, RequestMethod.POST })
    public String deleteMeeting(Model model, @RequestParam String deviceId, @RequestParam String token, HttpServletRequest request,
            @RequestParam Integer id) {

        Map<String, Object> userData = authenticationService.findUserByAccessToken(deviceId, token);
        if (userData == null) {
            model.addAttribute(Params.AUTH, Boolean.FALSE);
            model.addAttribute(Params.SUCCESS, Boolean.FALSE);
            return JsonView.NAME;
        }

        boolean haveAuth = authenticationService.haveAuth( userData.get("id"), "MEETING_MAINTAIN");
        if (!haveAuth) {
            model.addAttribute(Params.AUTH, Boolean.FALSE);
            model.addAttribute(Params.SUCCESS, Boolean.FALSE);
            return JsonView.NAME;
        }

        Meeting instance = meetingService.find(id);
        instance.setDeleted(true);
        meetingService.saveOrUpdate(instance);

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

        return JsonView.NAME;
    }

}