package com.usoftchina.qywx.sdk.dto;

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

/**
 * @author yingp
 */
public class UpdateUserReq {
    /**
     * 成员UserID。对应管理端的帐号，企业内必须唯一。不区分大小写，长度为1~64个字节。只能由数字、字母和“_-@.”四种字符组成，且第一个字符必须是数字或字母。
     */
    private String userId;
    /**
     * 成员名称。长度为1~64个utf8字符
     */
    private String name;
    /**
     * 成员别名。长度1~32个utf8字符
     */
    private String alias;
    /**
     * 手机号码。企业内必须唯一。若成员已激活企业微信，则需成员自行修改（此情况下该参数被忽略，但不会报错）
     */
    private String mobile;
    /**
     * 成员所属部门列表,不超过20个
     */
    private List<Department> department;
    /**
     * 职务信息。长度为0~128个字符
     */
    private String position;
    /**
     * 对外职务，如果设置了该值，则以此作为对外展示的职务，否则以position来展示。长度12个汉字内
     */
    private String externalPosition;
    /**
     * 性别。1表示男性，2表示女性
     */
    private Gender gender;
    /**
     * 邮箱。长度不超过64个字节，且为有效的email格式。企业内必须唯一。若是绑定了腾讯企业邮的企业微信，则需要在腾讯企业邮中修改邮箱（此情况下该参数被忽略，但不会报错）
     */
    private String email;
    /**
     * 座机。32字节以内，由纯数字或’-‘号组成
     */
    private String telephone;
    /**
     * 成员头像的mediaid，通过素材管理接口上传图片获得的mediaid
     */
    private String avatarMediaId;
    /**
     * 启用/禁用成员。1表示启用成员，0表示禁用成员
     */
    private Boolean enable;
    /**
     * 地址。长度最大128个字符
     */
    private String address;

    public UpdateUserReq userId(String userId) {
        this.userId = userId;
        return this;
    }

    public UpdateUserReq name(String name) {
        this.name = name;
        return this;
    }

    public UpdateUserReq alias(String alias) {
        this.alias = alias;
        return this;
    }

    public UpdateUserReq mobile(String mobile) {
        this.mobile = mobile;
        return this;
    }

    public UpdateUserReq email(String email) {
        this.email = email;
        return this;
    }

    public UpdateUserReq department(List<Department> department) {
        this.department = department;
        return this;
    }

    public UpdateUserReq position(String position) {
        this.position = position;
        return this;
    }

    public UpdateUserReq externalPosition(String externalPosition) {
        this.externalPosition = externalPosition;
        return this;
    }

    public UpdateUserReq gender(Gender gender) {
        this.gender = gender;
        return this;
    }

    public UpdateUserReq telephone(String telephone) {
        this.telephone = telephone;
        return this;
    }

    public UpdateUserReq avatar(String avatarMediaId) {
        this.avatarMediaId = avatarMediaId;
        return this;
    }

    public UpdateUserReq address(String address) {
        this.address = address;
        return this;
    }

    public UpdateUserReq enable(boolean enable) {
        this.enable = enable;
        return this;
    }

    public Map<String, Object> build() {
        Map<String, Object> data = new HashMap<>(8);
        data.put("userid", userId);
        if (null != name) {
            data.put("name", name);
        }
        if (null != alias) {
            data.put("alias", alias);
        }
        if (null != mobile) {
            data.put("mobile", mobile);
        }
        if (null != email) {
            data.put("email", email);
        }
        if (null != department) {
            List<Integer> idList = new ArrayList<>(department.size());
            List<Integer> orderList = new ArrayList<>(department.size());
            List<Integer> leaderList = new ArrayList<>(department.size());
            department.forEach(dept -> {
                idList.add(dept.id);
                orderList.add(dept.order);
                leaderList.add(dept.leader ? 1 : 0);
            });
            data.put("department", idList);
            data.put("order", orderList);
            data.put("is_leader_in_dept", leaderList);
        }
        if (null != gender) {
            data.put("gender", gender.code);
        }
        if (null != telephone) {
            data.put("telephone", telephone);
        }
        if (null != avatarMediaId) {
            data.put("avatar_mediaid", avatarMediaId);
        }
        if (null != enable) {
            data.put("enable", enable ? 1 : 0);
        }
        if (null != address) {
            data.put("address", address);
        }
        if (null != position) {
            data.put("position", position);
        }
        if (null != externalPosition) {
            data.put("external_position", externalPosition);
        }
        return data;
    }

    public enum Gender {
        MALE("1"), FEMALE("2");
        private final String code;

        Gender(String code) {
            this.code = code;
        }

        public String getCode() {
            return code;
        }

        public static Gender of(String code) {
            for (Gender value : values()) {
                if (value.code.equals(code)) {
                    return value;
                }
            }
            return MALE;
        }
    }

    public static class Department {
        /**
         * 成员所属部门id
         */
        private Integer id;
        /**
         * 部门内的排序值，默认为0，成员次序以创建时间从小到大排列，数值越大排序越前面。有效的值范围是[0, 2^32)
         */
        private Integer order;
        /**
         * 表示在所在的部门内是否为上级。1表示为上级，0表示非上级。在审批等应用里可以用来标识上级审批人
         */
        private boolean leader;

        public Department(Integer id, Integer order, boolean leader) {
            this.id = id;
            this.order = order;
            this.leader = leader;
        }
    }
}
