using Google.Protobuf.WellKnownTypes;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace OASystem.Domain.ViewModels.QiYeWeChat
{
    /// <summary>
    /// 企业微信 审批 View
    /// </summary>
    public class ApprovalDataView : ResponseBase
    {
        /// <summary>
        /// 拉取的审批单个数,最大值为100,当total参数大于100时,可运用next_spnum参数进行多次拉取
        /// </summary>
        public int Count { get; set; }

        /// <summary>
        /// 时间段内的总审批单个数
        /// </summary>
        public int total { get; set; }

        /// <summary>
        /// 拉取列表的最后一个审批单号
        /// </summary>
        public long next_spnum { get; set; }

        /// <summary>
        /// 审批Data
        /// </summary>
        public List<Sp_Info>? data { get; set; }
    }

    /// <summary>
    /// 批量获取审批单号 View
    /// </summary>
    public class ApprovalInfoView : ResponseBase
    {
        /// <summary>
        /// 审批单号列表,包含满足条件的审批申请
        /// </summary>
        public List<string>? sp_no_list { get; set; }

        /// <summary>
        /// 后续请求查询的游标,当返回结果没有该字段时表示审批单已经拉取完
        /// </summary>
        public string? new_next_cursor { get; set; }
    }

    /// <summary>
    /// 审批申请详情 View
    /// </summary>
    public class ApprovalDetailView : ResponseBase
    {
        /// <summary>
        /// 审批申请详情
        /// </summary>
        public Sp_Detail? info { get; set; }
    }


    /// <summary>
    /// 申请人信息
    /// </summary>
    public class Applyer
    {
        /// <summary>
        /// 申请人userid
        /// </summary>
        public string userid { get; set; }
        /// <summary>
        /// 申请人所在部门id
        /// </summary>
        public string partyid { get; set; }
    }

    /// <summary>
    /// 分支审批人
    /// </summary>
    public class Approver
    {
        /// <summary>
        /// 分支审批人userid
        /// </summary>
        public string userid { get; set; }
    }

    /// <summary>
    /// 审批节点详情,一个审批节点有多个审批人
    /// </summary>
    public class DetailsItem
    {
        /// <summary>
        /// 分支审批人
        /// </summary>
        public Approver approver { get; set; }
        /// <summary>
        /// 审批意见
        /// </summary>
        public string speech { get; set; }
        /// <summary>
        /// 分支审批人审批状态:1-审批中;2-已同意;3-已驳回;4-已转审;11-已退回;12-已加签;13-已同意并加签
        /// </summary>
        public int sp_status { get; set; }
        /// <summary>
        /// 节点分支审批人审批操作时间戳,0表示未操作
        /// </summary>
        public int sptime { get; set; }
        /// <summary>
        /// 节点分支审批人审批意见附件,media_id具体使用请参考:文档-获取临时素材
        /// </summary>
        public List<string> media_id { get; set; }
    }

    /// <summary>
    /// 审批流程信息,可能有多个审批节点。
    /// </summary>
    public class Sp_recordItem
    {
        /// <summary>
        /// 审批节点状态:1-审批中;2-已同意;3-已驳回;4-已转审;11-已退回;12-已加签;13-已同意并加签
        /// </summary>
        public int sp_status { get; set; }
        /// <summary>
        /// 节点审批方式:1-或签;2-会签
        /// </summary>
        public int approverattr { get; set; }
        /// <summary>
        /// 审批节点详情,一个审批节点有多个审批人
        /// </summary>
        public List<DetailsItem> details { get; set; }
    }

    /// <summary>
    /// 抄送信息,可能有多个抄送节点
    /// </summary>
    public class NotifyerItem
    {
        /// <summary>
        /// 节点抄送人userid
        /// </summary>
        public string userid { get; set; }
    }

    /// <summary>
    /// 控件标题
    /// </summary>
    public class TitleItem
    {
        /// <summary>
        /// 文本值 中文
        /// </summary>
        public string text { get; set; }
        /// <summary>
        /// 文本值 英文值
        /// </summary>
        public string lang { get; set; }
    }

    /// <summary>
    /// 用户所选选项
    /// </summary>
    public class OptionsItem
    {
        /// <summary>
        /// 选项key,选项的唯一id,可通过“获取审批模板详情”接口获得
        /// </summary>
        public string key { get; set; }
        /// <summary>
        /// 选项值,若配置了多语言则会包含中英文的选项值
        /// </summary>
        public List<TitleItem> value { get; set; }
    }

    /// <summary>
    /// 请假类型,所选选项与假期管理关联,为假期管理中的假期类型
    /// </summary>
    public class Selector
    {
        /// <summary>
        /// 选择类型:single-单选;multi-多选,在假勤控件中固定为单选
        /// </summary>
        public string type { get; set; }
        /// <summary>
        /// 用户所选选项
        /// </summary>
        public List<OptionsItem> options { get; set; }
    }

    /// <summary>
    /// 假勤组件时间选择范围
    /// </summary>
    public class Date_range
    {
        /// <summary>
        /// 时间展示类型:halfday-日期;hour-日期+时间
        /// </summary>
        public string type { get; set; }
        /// <summary>
        /// 开始时间
        /// </summary>
        public long new_begin { get; set; }

        /// <summary>
        /// 开始时间 
        /// </summary>
        public DateTime new_begin_dt
        {
            get
            {
                return new DateTime(new_begin * 10000000 + 621355968000000000L).ToLocalTime();
            }
        }

        /// <summary>
        /// 结束时间
        /// </summary>
        public long new_end { get; set; }

        /// <summary>
        /// 开始时间 
        /// </summary>
        public DateTime new_end_dt
        {
            get
            {
                return new DateTime(new_end * 10000000 + 621355968000000000L).ToLocalTime();
            }
        }

        /// <summary>
        /// 请假时长
        /// </summary>
        public int new_duration { get; set; }
    }

    /// <summary>
    /// 每一天的分片时长信息
    /// </summary>
    public class Day_itemsItem
    {
        /// <summary>
        /// 日期的00:00:00时间戳,Unix时间
        /// </summary>
        public long daytime { get; set; }

        public DateTime daytimeDt
        {
            get
            {
                return new DateTime(daytime * 10000000 + 621355968000000000L).ToLocalTime();
            }
        }
        ///// <summary>
        ///// 
        ///// </summary>
        //public List<string> time_sections { get; set; }
        /// <summary>
        /// 分隔当前日期的时长秒数
        /// </summary>
        public long duration { get; set; }
    }

    /// <summary>
    /// 时长支持按天分片信息, 2020/10/01之前的历史表单不支持时长分片
    /// </summary>
    public class Slice_info
    {
        /// <summary>
        /// 每一天的分片时长信息
        /// </summary>
        public List<Day_itemsItem> day_items { get; set; }
        /// <summary>
        /// 时长计算来源类型: 1--系统自动计算;2--用户修改
        /// </summary>
        public int state { get; set; }
        /// <summary>
        /// 总时长,单位是秒
        /// </summary>
        public long duration { get; set; }
    }

    /// <summary>
    /// 假勤组件
    /// </summary>
    public class Attendance
    {
        /// <summary>
        /// 假勤组件时间选择范围
        /// </summary>
        public Date_range date_range { get; set; }
        /// <summary>
        /// 假勤组件类型:1-请假;2-补卡;3-出差;4-外出;5-加班
        /// </summary>
        public int type { get; set; }
        /// <summary>
        /// 时长支持按天分片信息, 2020/10/01之前的历史表单不支持时长分片
        /// </summary>
        public Slice_info slice_info { get; set; }
    }

    /// <summary>
    /// 假内容,即申请人在此组件内选择的请假信息
    /// </summary>
    public class Vacation
    {
        /// <summary>
        /// 请假类型,所选选项与假期管理关联,为假期管理中的假期类型
        /// </summary>
        public Selector selector { get; set; }
        /// <summary>
        /// 假勤组件
        /// </summary>
        public Attendance attendance { get; set; }
    }

    /// <summary>
    /// 控件值 ,包含了申请人在各种类型控件中输入的值,不同控件有不同的值,具体说明详见附录
    /// </summary>
    public class Value
    {
        public string? text { get; set; }

        /// <summary>
        /// 此控件不显示在审批详情中,故value为空
        /// </summary>
        public object? tips { get; set; }
        /// <summary>
        /// 成员内容,即申请人在此控件选择的成员,多选模式下可能有多个
        /// </summary>
        public List<Member> members { get; set; }
        /// <summary>
        /// 部门内容,即申请人在此控件选择的部门,多选模式下可能有多个
        /// </summary>
        public List<Department> departments { get; set; }
        /// <summary>
        /// 文件内容,即申请人在此控件上传的文件内容,可能有多个
        /// </summary>
        public List<File_Info> files { get; set; }
        /// <summary>
        /// 明细内容,一个明细控件可能包含多个子明细
        /// </summary>
        public List<Children> children { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public List<string> stat_field { get; set; }
        /// <summary>
        /// 请假内容,即申请人在此组件内选择的请假信息
        /// </summary>
        public Vacation vacation { get; set; }
        ///// <summary>
        ///// 
        ///// </summary>
        //public List<string> sum_field { get; set; }

        /// <summary>
        /// 补卡类型模板值
        /// </summary>
        public Punch_Correction punch_correction { get; set; }

        /// <summary>
        /// 关联审批单的模板
        /// </summary>
        public List<Related_Approval> related_approval { get; set; }

        public Attendance attendance { get; set; }

        ///// <summary>
        ///// 
        ///// </summary>
        //public List<string> students { get; set; }
        ///// <summary>
        ///// 
        ///// </summary>
        //public List<string> classes { get; set; }
        ///// <summary>
        ///// 
        ///// </summary>
        //public List<string> docs { get; set; }
        ///// <summary>
        ///// 
        ///// </summary>
        //public List<string> wedrive_files { get; set; }
    }

    /// <summary>
    /// 补卡模板 值
    /// </summary>
    public class Punch_Correction
    {
        /// <summary>
        /// 异常状态说明 状态 未打卡 
        /// </summary>
        public string state { get; set; }

        /// <summary>
        /// 补卡时间 
        /// </summary>
        public long time { get; set; }

        /// <summary>
        /// 开始时间 
        /// </summary>
        public DateTime time_dt
        {
            get
            {
                return new DateTime(time * 10000000 + 621355968000000000L).ToLocalTime();
            }
        }

        /// <summary>
        /// ?
        /// </summary>
        public long date { get; set; }
    }

    /// <summary>
    /// 部门内容,即申请人在此控件选择的部门,多选模式下可能有多个
    /// </summary>
    public class Department 
    {
        /// <summary>
        /// 部门id
        /// </summary>
        public string openapi_id { get; set; }

        /// <summary>
        /// 部门名
        /// </summary>
        public string name { get; set; }
    }

    /// <summary>
    /// 成员内容,即申请人在此控件选择的成员,多选模式下可能有多个
    /// </summary>
    public class Member
    {
        /// <summary>
        /// 成员的userid
        /// </summary>
        public string userid { get; set; }

        /// <summary>
        /// 成员名
        /// </summary>
        public string name { get; set; }
    }

    /// <summary>
    /// 文件内容,即申请人在此控件上传的文件内容,可能有多个
    /// </summary>
    public class File_Info
    {
        /// <summary>
        /// 文件的media_id
        /// </summary>
        public string file_id { get; set; }

    }

    /// <summary>
    /// 明细内容,一个明细控件可能包含多个子明细
    /// </summary>
    public class Children
    {
        public List<ListInfo> list { get; set; }
    }

    public class ListInfo
    {
        public string control { get; set; }

        public string id { get; set; }

        public List<TitleItem> title { get; set; }

        public ValueText value { get; set; }
    }

    public class ValueText
    {
        public string text { get; set; }
    }

    /// <summary>
    /// 关联审批单的模板
    /// </summary>
    public class Related_Approval
    {
        /// <summary>
        /// 关联审批单的模板名
        /// </summary>
        public List<TitleItem> template_names { get; set; }

        /// <summary>
        /// 关联审批单的审批单号
        /// </summary>
        public string sp_no { get; set; }

        /// <summary>
        /// 关联审批单的状态
        /// </summary>
        public int sp_status { get; set; }

        /// <summary>
        /// 关联审批单的提单时间
        /// </summary>
        public long create_time { get; set; }

        /// <summary>
        /// 关联审批单的提单者
        /// </summary>
        public string name { get; set; }
    }


    /// <summary>
    /// 审批申请详情,由多个表单控件及其内容组成
    /// </summary>
    public class ContentsItem
    {
        /// <summary>
        /// 控件类型:
        /// Text-文本;Textarea-多行文本;Number-数字;Money-金额;Date-日期/日期+时间;
        /// Selector-单选/多选;;Contact-成员/部门;Tips-说明文字;File-附件;Table-明细;
        /// Attendance-假勤;Vacation-请假;PunchCorrection-补卡;DateRange-时长
        /// </summary>
        public string control { get; set; }
        /// <summary>
        /// 控件id
        /// </summary>
        public string id { get; set; }
        /// <summary>
        /// 控件名称 ,若配置了多语言则会包含中英文的控件名称
        /// </summary>
        public List<TitleItem> title { get; set; }
        /// <summary>
        /// 控件值 ,包含了申请人在各种类型控件中输入的值,不同控件有不同的值,具体说明详见附录
        /// </summary>
        public Value value { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public int display { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public int require { get; set; }
    }

    /// <summary>
    /// 审批申请数据
    /// </summary>
    public class Apply_data
    {
        /// <summary>
        /// 审批申请详情,由多个表单控件及其内容组成
        /// </summary>
        public List<ContentsItem> contents { get; set; }
    }

    /// <summary>
    /// 审批详情
    /// </summary>
    public class Sp_Detail
    {
        /// <summary>
        /// 审批编号
        /// </summary>
        public string sp_no { get; set; }
        /// <summary>
        /// 审批申请类型名称(审批模板名称)
        /// </summary>
        public string sp_name { get; set; }
        /// <summary>
        /// 申请单状态:1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付
        /// </summary>
        public int sp_status { get; set; }
        /// <summary>
        /// 审批模板id。可在“获取审批申请详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面链接中获得。
        /// </summary>
        public string template_id { get; set; }
        /// <summary>
        /// 审批申请提交时间,Unix时间戳
        /// </summary>
        public long apply_time { get; set; }

        /// <summary>
        /// 开始时间 
        /// </summary>
        public DateTime apply_time_dt
        {
            get
            {
                return new DateTime(apply_time * 10000000 + 621355968000000000L).ToLocalTime();
            }
        }

        /// <summary>
        /// 申请人信息
        /// </summary>
        public Applyer applyer { get; set; }
        /// <summary>
        /// 审批流程信息,可能有多个审批节点。
        /// </summary>
        public List<Sp_recordItem> sp_record { get; set; }
        /// <summary>
        /// 抄送信息,可能有多个抄送节点
        /// </summary>
        public List<NotifyerItem> notifyer { get; set; }
        /// <summary>
        /// 审批申请数据
        /// </summary>
        public Apply_data apply_data { get; set; }
        /// <summary>
        /// 审批申请备注信息,可能有多个备注节点
        /// </summary>
        public List<Comment> comments { get; set; }
    }


    /// <summary>
    /// 审批申请备注信息
    /// </summary>
    public class Comment
    {
        /// <summary>
        /// userid
        /// </summary>
        public Approver commentUserInfo { get; set; }

        /// <summary>
        /// unix时间戳
        /// </summary>
        public long commenttime { get; set; }

        /// <summary>
        /// 备注信息
        /// </summary>
        public string commentcontent { get; set; }

        /// <summary>
        /// 	备注id
        /// </summary>
        public string commentid { get; set; }

        /// <summary>
        /// 备注附件id,可能有多个,media_id具体使用请参考:文档-获取临时素材
        /// </summary>
        public List<string> media_id { get; set; }
    }


    #region 审批详情 (旧版)


    /// <summary>
    /// 审批基本信息
    /// </summary>
    public class Sp_Info 
    {
        /// <summary>
        /// 审批名称(请假,报销,自定义审批名称)
        /// </summary>
        public string? spname { get; set; }

        /// <summary>
        /// 申请人姓名
        /// </summary>
        public string? apply_name { get; set; }

        /// <summary>
        /// 申请人部门
        /// </summary>
        public string? apply_org { get; set; }

        /// <summary>
        /// 审批人姓名
        /// </summary>
        public List<string>? approval_name { get; set; }

        /// <summary>
        /// 抄送人姓名
        /// </summary>
        public List<string>? notify_name { get; set; }

        /// <summary>
        /// 审批状态:1审批中;2 已通过;3已驳回;4已取消;6通过后撤销;10已支付
        /// </summary>
        public int sp_status { get; set; }

        /// <summary>
        /// 审批单号
        /// </summary>
        public long sp_num { get; set; }

        /// <summary>
        /// 请假类型(只有请假模板审批记录有此数据项)
        /// </summary>
        public Leave? leave { get; set; }

        /// <summary>
        /// 审批模板信息
        /// </summary>
        public Comm? comm { get; set; }

        ///// <summary>
        ///// 补卡时间
        ///// 打卡补卡 筛选使用
        ///// </summary>
        //public DateTime? comm_applydata_dt
        //{
        //    get
        //    {
        //        DateTime? dt = null;
        //        if (comm == null) return dt;

        //        if (comm.FillingDt != null)
        //        {
        //            dt = comm.FillingDt;
        //        }
        //        return dt;
        //    }
        //}


        /// <summary>
        /// 审批的附件media_id,可使用media/get获取附件
        /// </summary>
        public List<string>? mediaids { get; set; }

        /// <summary>
        /// 审批单提交时间 
        /// Unix时间戳
        /// </summary>
        public uint apply_time { get; set; }

        /// <summary>
        /// 审批单提交时间 
        /// datetime
        /// </summary>
        public DateTime apply_time_dt
        {
            get
            {
                return new DateTime(long.Parse(apply_time.ToString()) * 10000000 + 621355968000000000L).ToLocalTime();
            }
        }

        /// <summary>
        /// 审批单提交者的userid
        /// </summary>
        public string? apply_user_id { get; set; }

    }

    /// <summary>
    /// 审批类型
    /// </summary>
    public class Leave
    {
        /// <summary>
        /// 请假时间单位:0半天;1小时
        /// </summary>
        public int timeunit { get; set; }

        /// <summary>
        /// 请假类型
        /// 1年假;2事假;3病假;4调休假;5婚假;6产假;7陪产假;8其他
        /// </summary>
        public int leave_type { get; set; }

        /// <summary>
        /// 请假开始时间,unix时间
        /// </summary>
        public uint start_time { get; set; }

        /// <summary>
        /// 请假开始时间,datetime时间
        /// </summary>
        public DateTime start_time_dt
        {
            get
            {
                return new DateTime(long.Parse(start_time.ToString()) * 10000000 + 621355968000000000L).ToLocalTime();
            }
        }

        /// <summary>
        /// 请假结束时间,unix时间
        /// </summary>
        public uint end_time { get; set; }

        /// <summary>
        /// 请假开始时间,datetime时间
        /// </summary>
        public DateTime end_time_dt
        {
            get
            {
                return new DateTime(long.Parse(end_time.ToString()) * 10000000 + 621355968000000000L).ToLocalTime();
            }
        }


        /// <summary>
        /// 请假时长,单位小时
        /// </summary>
        public int duration { get; set; }

        /// <summary>
        /// 请假事由
        /// </summary>
        public string? reason { get; set; }

    }

    /// <summary>
    /// 审批模板信息
    /// </summary>
    public class Comm
    {
        /// <summary>
        /// 模板数据
        /// </summary>
        public string? apply_data { get; set; }

        public List<ApplyInfo>? applydata
        {
            get
            {
                List<ApplyInfo> applyInfos = new List<ApplyInfo>();

                if (!string.IsNullOrEmpty(apply_data)) 
                {
                    applyInfos = JsonConvert.DeserializeObject<List<ApplyInfo>>(apply_data);

                }
                return applyInfos;
            }
        }

        /// <summary>
        /// 补卡时间
        /// 筛选使用
        /// </summary>
        public DateTime? FillingDt {

            get 
            {
                DateTime? dt = null;
                if (applydata != null && applydata.Count > 0)
                {
                    ApplyInfo applyInfo = applydata.Where(it => it.id == "checkin-time").FirstOrDefault();
                    if (applyInfo != null)
                    {
                        dt = applyInfo.valueDt;

                    }
                }

                return dt;

            }

        }
    }

    /// <summary>
    /// 
    /// </summary>
    public class ApplyInfo
    {
        public string? id { get; set; }

        public string? title { get; set; }

        public string? type { get; set; }

        public object? value { get; set; }

        public DateTime? valueDt
        {
            get
            {
                if (id == "checkin-time" && value != null)
                {
                    long timeSpan = long.Parse(value.ToString()) / 1000;
                    return new DateTime(timeSpan * 10000000 + 621355968000000000L).ToLocalTime();
                }

                return null;
            }
        } 

    }

    #endregion
}