package com.usoftchina.qywx.sdk.dto;

import org.springframework.ui.ModelMap;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author yingp
 */
public class AddScheduleReq {
    /**
     * 组织者userId
     */
    private String organizer;
    /**
     * 日程开始时间，Unix时间戳
     */
    private Long startTime;
    /**
     * 日程结束时间，Unix时间戳
     */
    private Long endTime;
    /**
     * 日程参与者列表。最多支持2000人
     */
    private List<String> attendees;
    /**
     * 日程标题。0 ~ 128 字符。不填会默认显示为“新建事件”
     */
    private String summary;
    /**
     * 日程描述。0 ~ 512 字符
     */
    private String description;
    /**
     * 日程开始（start_time）前多少秒提醒，当is_remind为1时有效。例如： 300表示日程开始前5分钟提醒。
     * 目前仅支持以下数值：
     * 0 - 事件开始时
     * 300 - 事件开始前5分钟
     * 900 - 事件开始前15分钟
     * 3600 - 事件开始前1小时
     * 86400 - 事件开始前1天
     */
    private Integer remindBeforeEventSecs;
    /**
     * 重复类型，当is_repeat为1时有效。目前支持如下类型：
     * 0 - 每日
     * 1 - 每周
     * 2 - 每月
     * 5 - 每年
     * 7 - 工作日
     */
    private RepeatType repeatType;
    /**
     * 日程地址。0 ~ 128 字符
     */
    private String location;
    /**
     * 日程所属日历ID。注意，这个日历必须是属于组织者(organizer)的日历；如果不填，那么插入到组织者的默认日历上
     */
    private String calId;

    public AddScheduleReq organizer(String organizer) {
        this.organizer = organizer;
        return this;
    }

    public AddScheduleReq during(long startTime, long endTime) {
        this.startTime = startTime;
        this.endTime = endTime;
        return this;
    }

    public AddScheduleReq attendees(List<String> attendees) {
        this.attendees = attendees;
        return this;
    }

    public AddScheduleReq summary(String summary) {
        this.summary = summary;
        return this;
    }

    public AddScheduleReq description(String description) {
        this.description = description;
        return this;
    }

    public AddScheduleReq remindBefore(int secs) {
        this.remindBeforeEventSecs = secs;
        return this;
    }

    public AddScheduleReq repeat(RepeatType type) {
        this.repeatType = type;
        return this;
    }

    public AddScheduleReq location(String location) {
        this.location = location;
        return this;
    }

    public AddScheduleReq calId(String calId) {
        this.calId = calId;
        return this;
    }

    public Map<String, Object> build() {
        Map<String, Object> data = new HashMap<>(1);
        Map<String, Object> schedule = new HashMap<>(1);
        schedule.put("organizer", organizer);
        schedule.put("start_time", startTime);
        schedule.put("end_time", endTime);
        if (null != attendees) {
            schedule.put("attendees",
                    attendees.stream().map(attendee -> new ModelMap("userid", attendee)).collect(Collectors.toList())
            );
        }
        if (null != summary) {
            schedule.put("summary", summary);
        }
        if (null != description) {
            schedule.put("description", description);
        }
        if (null != remindBeforeEventSecs || null != repeatType) {
            schedule.put("reminders", new ModelMap("is_remind", null != remindBeforeEventSecs ? 1 : 0)
                    .addAttribute("remind_before_event_secs", remindBeforeEventSecs)
                    .addAttribute("is_repeat", null != repeatType ? 1 : 0)
                    .addAttribute("repeat_type", null == repeatType ? null : repeatType.code));
        }
        if (null != location) {
            schedule.put("location", location);
        }
        if (null != calId) {
            schedule.put("cal_id", calId);
        }
        data.put("schedule", schedule);
        return data;
    }

    public enum RepeatType {
        DAY(0), WEEK(1), MONTH(2), YEAR(5), WEEKDAYS(7);

        private final int code;

        RepeatType(int code) {
            this.code = code;
        }
    }
}
