package model

import (
	"errors"
	"fmt"
	"github.com/fonchain_enterprise/fonchain-approval/api/approval"
	m2 "github.com/fonchain_enterprise/fonchain-approval/pkg/m"
	"github.com/jinzhu/copier"
	"gorm.io/plugin/soft_delete"
	"strconv"
	"time"
)

type ApprovalOA struct {
	ID         uint64                `gorm:"primaryKey;column:id" json:"id"`       // ID
	DeletedAt  soft_delete.DeletedAt `gorm:"column:deleted_at" json:"deletedAt"`   // 删除时间
	CreatedAt  time.Time             `gorm:"column:created_at" json:"createdAt"`   // 创建时间
	UpdatedAt  time.Time             `gorm:"column:updated_at" json:"updatedAt"`   // 更新时间
	ApprovalID uint64                `gorm:"column:approval_id" json:"approvalID"` // 申请的id
	LeaveApply LeaveApply            `json:"leaveApply" gorm:"column:leave_apply;type:json;comment:假期余额申请"`
	OutWork    OutWorkApply          `json:"outWork" gorm:"column:out_work;type:json;comment:外勤"`
	MakeUp     MakeUpApply           `json:"makeUp" gorm:"column:make_up;type:json;comment:加班"`
	Turnover   TurnoverApply         `json:"turnover" gorm:"column:turnover;type:json;comment:离职"`
	OverTime   OverTimeApply         `json:"overTime" gorm:"column:over_time;type:json;comment:加班"`
	Leave      Leave                 `json:"leave" gorm:"column:leave;type:json;comment:请假"`
}

// LeaveApply
// 假期额度申请
type LeaveApply struct {
	UUID          string        `json:"UUID" gorm:"column:uuid,type:varchar(255),primaryKey"`
	StaffUID      string        `json:"staffUID" gorm:"column:staff_uid;type:varchar(255);comment:员工UID"`   // 员工UID
	StaffNum      string        `json:"staffNum" gorm:"column:staff_num;type:varchar(255);comment:员工编号"`    // 员工编号
	StaffName     string        `json:"staffName" gorm:"column:staff_name;type:varchar(255);comment:员工姓名"`  // 员工姓名
	DepartmentUID string        `json:"departmentUID" gorm:"column:department_uid;type:text;comment:部门UID"` // 部门UID
	ApplyType     string        `json:"applyType" gorm:"column:apply_type;type:varchar(255);comment:审批|请假类型"`
	ActionTime    string        `json:"actionTime" gorm:"column:action_time;type:varchar(255);comment:操作|申请时间"`
	ApprovalID    string        `json:"approvalID" gorm:"column:approval_id;type:varchar(255);comment:审批系统中的approvalID"`
	Reason        string        `json:"reason" gorm:"column:reason;type:varchar(255);comment:理由"`
	Status        int32         `json:"status" gorm:"column:status;type:int;comment:状态(目前和审批系统状态同步)"`
	VerifyFile    VerifyFiles   `json:"verifyFile" gorm:"column:verify_file;type:json;comment:证明文件(图片|pdf)"`
	ApprovalUsers ApprovalUsers `json:"approvalUsers" gorm:"column:approval_users;type:json;comment:审批人"`
	CopyUsers     CopyUsers     `json:"copyUsers" gorm:"column:copy_users;type:json;comment:抄送人"`
}

// OutWorkApply
// 外勤申请
type OutWorkApply struct {
	UUID           string        `json:"UUID" gorm:"column:uuid,type:varchar(255),primaryKey"`
	StaffUID       string        `json:"staffUID" gorm:"column:staff_uid;type:varchar(255);comment:员工UID"`   // 员工UID
	StaffNum       string        `json:"staffNum" gorm:"column:staff_num;type:varchar(255);comment:员工编号"`    // 员工编号
	StaffName      string        `json:"staffName" gorm:"column:staff_name;type:varchar(255);comment:员工姓名"`  // 员工姓名
	DepartmentUID  string        `json:"departmentUID" gorm:"column:department_uid;type:text;comment:部门UID"` // 部门UID
	ApplyType      string        `json:"applyType" gorm:"column:apply_type;type:varchar(255);comment:审批|请假类型"`
	ActionTime     string        `json:"actionTime" gorm:"column:action_time;type:varchar(255);comment:操作|申请时间"`
	ApplyTimes     ApplyTimes    `json:"applyTimes" gorm:"column:apply_times;type:json;comment:时间"`
	Hours          float32       `json:"hours" gorm:"column:hours;type:decimal(10,2);comment:时长(小时)"`
	OutWorkAddress string        `json:"outWorkAddress" gorm:"column:out_work_address;type:varchar(255);comment:外勤地址"`
	Vehicle        string        `json:"vehicle" gorm:"column:vehicle;type:varchar(255);comment:交通工具"`
	Reason         string        `json:"reason" gorm:"column:reason;type:varchar(255);comment:理由"`
	ApprovalID     string        `json:"approvalID" gorm:"column:approval_id;type:varchar(255);comment:审批系统中的approvalID"`
	Status         int32         `json:"status" gorm:"column:status;type:int;comment:状态(目前和审批系统状态同步)"`
	ApprovalUsers  ApprovalUsers `json:"approvalUsers" gorm:"column:approval_users;type:json;comment:审批人"`
	CopyUsers      CopyUsers     `json:"copyUsers" gorm:"column:copy_users;type:json;comment:抄送人"`
}

// MakeUpApply
// 补卡申请
type MakeUpApply struct {
	UUID          string        `json:"UUID" gorm:"column:uuid,type:varchar(255),primaryKey"`
	StaffUID      string        `json:"staffUID" gorm:"column:staff_uid;type:varchar(255);comment:员工UID"`   // 员工UID
	StaffNum      string        `json:"staffNum" gorm:"column:staff_num;type:varchar(255);comment:员工编号"`    // 员工编号
	StaffName     string        `json:"staffName" gorm:"column:staff_name;type:varchar(255);comment:员工姓名"`  // 员工姓名
	DepartmentUID string        `json:"departmentUID" gorm:"column:department_uid;type:text;comment:部门UID"` // 部门UID
	ApplyType     string        `json:"applyType" gorm:"column:apply_type;type:varchar(255);comment:审批|请假类型"`
	ActionTime    string        `json:"actionTime" gorm:"column:action_time;type:varchar(255);comment:操作|申请时间"`
	ApplyTimes    ApplyTimes    `json:"applyTimes" gorm:"column:apply_times;type:json;comment:时间"`
	Reason        string        `json:"reason" gorm:"column:reason;type:varchar(255);comment:理由"`
	ApprovalID    string        `json:"approvalID" gorm:"column:approval_id;type:varchar(255);comment:审批系统中的approvalID"`
	Status        int32         `json:"status" gorm:"column:status;type:int;comment:状态(目前和审批系统状态同步)"`
	ApprovalUsers ApprovalUsers `json:"approvalUsers" gorm:"column:approval_users;type:json;comment:审批人"`
	CopyUsers     CopyUsers     `json:"copyUsers" gorm:"column:copy_users;type:json;comment:抄送人"`
}

// TurnoverApply
// 离职申请
type TurnoverApply struct {
	UUID          string        `json:"UUID" gorm:"column:uuid,type:varchar(255),primaryKey"`
	StaffUID      string        `json:"staffUID" gorm:"column:staff_uid;type:varchar(255);comment:员工UID"`   // 员工UID
	StaffNum      string        `json:"staffNum" gorm:"column:staff_num;type:varchar(255);comment:员工编号"`    // 员工编号
	StaffName     string        `json:"staffName" gorm:"column:staff_name;type:varchar(255);comment:员工姓名"`  // 员工姓名
	DepartmentUID string        `json:"departmentUID" gorm:"column:department_uid;type:text;comment:部门UID"` // 部门UID
	ApplyType     string        `json:"applyType" gorm:"column:apply_type;type:varchar(255);comment:审批|请假类型"`
	ActionTime    string        `json:"actionTime" gorm:"column:action_time;type:varchar(255);comment:操作|申请时间"`
	Reason        string        `json:"reason" gorm:"column:reason;type:varchar(255);comment:理由"`
	HandoverUID   string        `json:"handoverUID" gorm:"column:handover_uid;type:varchar(255);comment:交接人"`
	HandoverName  string        `json:"handoverName" gorm:"column:handover_name;type:varchar(255);comment:交接人姓名"`
	ApplyTimes    ApplyTimes    `json:"applyTimes" gorm:"column:apply_times;type:json;comment:时间"`
	ApprovalID    string        `json:"approvalID" gorm:"column:approval_id;type:varchar(255);comment:审批系统中的approvalID"`
	Status        int32         `json:"status" gorm:"column:status;type:int;comment:状态(目前和审批系统状态同步)"`
	ApprovalUsers ApprovalUsers `json:"approvalUsers" gorm:"column:approval_users;type:json;comment:审批人"`
	CopyUsers     CopyUsers     `json:"copyUsers" gorm:"column:copy_users;type:json;comment:抄送人"`
}

// OverTimeApply
// 加班申请
type OverTimeApply struct {
	UUID          string        `json:"UUID" gorm:"column:uuid,type:varchar(255),primaryKey"`
	StaffUID      string        `json:"staffUID" gorm:"column:staff_uid;type:varchar(255);comment:员工UID"`   // 员工UID
	StaffNum      string        `json:"staffNum" gorm:"column:staff_num;type:varchar(255);comment:员工编号"`    // 员工编号
	StaffName     string        `json:"staffName" gorm:"column:staff_name;type:varchar(255);comment:员工姓名"`  // 员工姓名
	DepartmentUID string        `json:"departmentUID" gorm:"column:department_uid;type:text;comment:部门UID"` // 部门UID
	ApplyType     string        `json:"applyType" gorm:"column:apply_type;type:varchar(255);comment:审批|请假类型"`
	ApprovalID    string        `json:"approvalID" gorm:"column:approval_id;type:varchar(255);comment:审批系统中的approvalID"`
	ActionTime    string        `json:"actionTime" gorm:"column:action_time;type:varchar(255);comment:操作|申请时间"`
	ApplyTimes    ApplyTimes    `json:"applyTimes" gorm:"column:apply_times;type:json;comment:时间"`
	Reason        string        `json:"reason" gorm:"column:reason;type:varchar(255);comment:理由"`
	Hours         float32       `json:"hours" gorm:"column:hours;type:decimal(10,2);comment:时长(小时)"`
	Status        int32         `json:"status" gorm:"column:status;type:int;comment:状态(目前和审批系统状态同步)"`
	ApprovalUsers ApprovalUsers `json:"approvalUsers" gorm:"column:approval_users;type:json;comment:审批人"`
	CopyUsers     CopyUsers     `json:"copyUsers" gorm:"column:copy_users;type:json;comment:抄送人"`
}

// Leave
// 请假
type Leave struct {
	UUID          string        `json:"UUID" gorm:"column:uuid,type:varchar(255),primaryKey"`
	StaffUID      string        `json:"staffUID" gorm:"column:staff_uid;type:varchar(255);comment:员工UID"`   // 员工UID
	StaffNum      string        `json:"staffNum" gorm:"column:staff_num;type:varchar(255);comment:员工编号"`    // 员工编号
	StaffName     string        `json:"staffName" gorm:"column:staff_name;type:varchar(255);comment:员工姓名"`  // 员工姓名
	DepartmentUID string        `json:"departmentUID" gorm:"column:department_uid;type:text;comment:部门UID"` // 部门UID
	ApplyType     string        `json:"applyType" gorm:"column:apply_type;type:varchar(255);comment:审批|请假类型"`
	ActionTime    string        `json:"actionTime" gorm:"column:action_time;type:varchar(255);comment:操作|申请时间"`
	ApprovalID    string        `json:"approvalID" gorm:"column:approval_id;type:varchar(255);comment:审批系统中的approvalID"`
	ApplyTimes    ApplyTimes    `json:"applyTimes" gorm:"column:apply_times;type:json;comment:时间"`
	Reason        string        `json:"reason" gorm:"column:reason;type:varchar(255);comment:理由"`
	Hours         float32       `json:"hours" gorm:"column:hours;type:decimal(10,2);comment:时长(小时)"`
	Days          float32       `json:"days" gorm:"column:days;type:decimal(10,2);comment:时长(天)"`
	Status        int32         `json:"status" gorm:"column:status;type:int;comment:状态(目前和审批系统状态同步)"`
	ApprovalUsers ApprovalUsers `json:"approvalUsers" gorm:"column:approval_users;type:json;comment:审批人"`
	CopyUsers     CopyUsers     `json:"copyUsers" gorm:"column:copy_users;type:json;comment:抄送人"`
}

type VerifyFiles []string

type ApplyTime struct {
	Date string `json:"date"` // 日期 2023-05-08
	Hour string `json:"hour"` // 时间 09:00
	M    string `json:"m"`    // 上午|下午
}

type ApplyTimes []ApplyTime

var sonMap = map[string]string{
	"leave":            "leave", // 事假
	"sick":             "leave", // 病假
	"annualLeave":      "leave", // 年假
	"dayOff":           "leave", // 调休
	"maritalLeave":     "leave", // 婚假
	"matingCheckLeave": "leave", // 孕检假
	"maternityLeave":   "leave", // 产假
	"paternityLeave":   "leave", // 陪产假
	"parentalLeave":    "leave", // 育儿假
	"nursingLeave":     "leave", // 独生子女护理假
	"funeralLeave":     "leave", // 丧假

	"makeUp":   "makeUp",   // 补卡
	"overTime": "overTime", // 加班
	"outWork":  "outWork",  // 外勤
	"turnover": "turnover", // 离职

	"annualLeaveApply":      "leaveApply", // 年假申请
	"maritalLeaveApply":     "leaveApply", // 婚假申请
	"matingCheckLeaveApply": "leaveApply", // 孕检假申请
	"maternityLeaveApply":   "leaveApply", // 产假申请
	"paternityLeaveApply":   "leaveApply", // 陪产假申请
	"parentalLeaveApply":    "leaveApply", // 育儿假申请
	"nursingLeaveApply":     "leaveApply", // 独生子女护理假申请
}

func GetSonMapValue(k string) string {
	return sonMap[k]
}

// TableName get sql table name.获取数据库表名
func (oa *ApprovalOA) TableName() string {
	return "approval_oa"
}

func (oa *ApprovalOA) GetApproval(id uint64) (*Approval, error) {

	var entity *Approval
	if err := DB.
		Preload("ApprovalWorkFlows").
		Preload("ApprovalType").
		Preload("ApprovalOA").
		First(&entity, id).Error; err != nil {
		return entity, err
	}

	return entity, nil
}

func (oa *ApprovalOA) SaveApprovalContent(in *approval.CreateRequest, a *Approval) error {
	fmt.Println("保存 approval_oa 信息 ")

	fmt.Println("approval info :", a.CopyUsers)
	fmt.Println("approval info :", a.ApprovalUsers)

	approvalOA, err := copyOAToModel(in, a)
	if err != nil {
		return err
	}

	fmt.Println("存入 数据库 approval_oa 信息 ")

	return DB.Create(&approvalOA).Error
}

func copyOAToModel(in *approval.CreateRequest, a *Approval) (approvalOA *ApprovalOA, err error) {
	approvalOA = new(ApprovalOA)
	copier.CopyWithOption(&approvalOA, in.ApprovalOA, copier.Option{DeepCopy: true})
	approvalOA.ApprovalID = a.ID

	fmt.Println("============== 打印 审批内容  1.0 ========== 开始 =========")
	fmt.Printf("approval_oa info is : %+v\n", approvalOA)
	fmt.Printf("approval_oa info is : %+v\n", approvalOA.Leave)
	fmt.Println("a CopyUsers info is : ", a.CopyUsers)
	fmt.Println("a ApprovalUsers info is : ", a.ApprovalUsers)
	fmt.Println("============== 打印 审批内容 ========== 结束 =========")

	if err := addOtherInfoToModel(a, approvalOA); err != nil {
		return nil, err
	}

	fmt.Println("============== 打印 审批内容  2.0 ========== 开始 =========")
	fmt.Printf("approval_oa info is : %+v\n", approvalOA)
	fmt.Printf("approval_oa info is : %+v\n", approvalOA.Leave)
	fmt.Println("a CopyUsers info is : ", a.CopyUsers)
	fmt.Println("a ApprovalUsers info is : ", a.ApprovalUsers)
	fmt.Println("============== 打印 审批内容 ========== 结束 =========")

	return approvalOA, nil
}

func addOtherInfoToModel(a *Approval, approvalOA *ApprovalOA) error {
	fmt.Println("============== 打印 审批内容  5.0 ========== 开始 =========")
	fmt.Printf("approval_oa info is : %+v\n", approvalOA)
	fmt.Printf("approval_oa info is : %+v\n", approvalOA.Leave)
	fmt.Printf("a info is : %+v\n", a)
	fmt.Println("============== 打印 审批内容 ========== 结束 =========")

	fmt.Println(sonMap[a.Type])

	v := GetSonMapValue(a.Type)
	switch v {
	case "leave":
		copier.CopyWithOption(&approvalOA.Leave.ApprovalUsers, a.ApprovalUsers, copier.Option{DeepCopy: true})
		fmt.Println("============== 打印 审批内容  3.0 ========== 开始 =========")
		fmt.Printf("approval_oa info is : %+v\n", approvalOA)
		fmt.Printf("approval_oa info is : %+v\n", approvalOA.Leave)
		fmt.Println("a ApprovalUsers info is : ", a.ApprovalUsers)
		fmt.Println("============== 打印 审批内容 ========== 结束 =========")

		copier.CopyWithOption(&approvalOA.Leave.CopyUsers, a.CopyUsers, copier.Option{DeepCopy: true})
		fmt.Println("============== 打印 审批内容  4.0 ========== 开始 =========")
		fmt.Printf("approval_oa info is : %+v\n", approvalOA)
		fmt.Printf("approval_oa info is : %+v\n", approvalOA.Leave)
		fmt.Println("a CopyUsers info is : ", a.CopyUsers)
		fmt.Println("============== 打印 审批内容 ========== 结束 =========")

		if approvalOA.Leave.ApplyType == "" {
			approvalOA.Leave.ApplyType = a.Type
		}
		approvalOA.Leave.ApprovalID = strconv.FormatUint(a.ID, 10)
		approvalOA.Leave.Status = int32(a.Status)

	case "makeUp":
		approvalOA.MakeUp.ApprovalUsers = a.ApprovalUsers
		approvalOA.MakeUp.CopyUsers = a.CopyUsers
		approvalOA.MakeUp.ApplyType = a.Type
		approvalOA.MakeUp.ApprovalID = strconv.FormatUint(a.ID, 10)
		approvalOA.MakeUp.Status = int32(a.Status)

	case "overTime":
		approvalOA.OverTime.ApprovalUsers = a.ApprovalUsers
		approvalOA.OverTime.CopyUsers = a.CopyUsers
		approvalOA.OverTime.ApplyType = a.Type
		approvalOA.OverTime.ApprovalID = strconv.FormatUint(a.ID, 10)
		approvalOA.OverTime.Status = int32(a.Status)

	case "outWork":
		approvalOA.OutWork.ApprovalUsers = a.ApprovalUsers
		approvalOA.OutWork.CopyUsers = a.CopyUsers
		approvalOA.OutWork.ApplyType = a.Type
		approvalOA.OutWork.ApprovalID = strconv.FormatUint(a.ID, 10)
		approvalOA.OutWork.Status = int32(a.Status)

	case "turnover":
		approvalOA.Turnover.ApprovalUsers = a.ApprovalUsers
		approvalOA.Turnover.CopyUsers = a.CopyUsers
		approvalOA.Turnover.ApplyType = a.Type
		approvalOA.Turnover.ApprovalID = strconv.FormatUint(a.ID, 10)
		approvalOA.Turnover.Status = int32(a.Status)

	case "leaveApply":
		approvalOA.LeaveApply.ApprovalUsers = a.ApprovalUsers
		approvalOA.LeaveApply.CopyUsers = a.CopyUsers
		approvalOA.LeaveApply.ApplyType = a.Type
		approvalOA.LeaveApply.ApprovalID = strconv.FormatUint(a.ID, 10)
		approvalOA.LeaveApply.Status = int32(a.Status)

	default:
		return errors.New("未找到相关审批类型")
	}

	return nil
}

func (oa *ApprovalOA) UpdateApprovalContent(in *approval.CreateRequest, a *Approval) error {

	var entity *ApprovalOA

	if err := DB.Where(&ApprovalOA{ApprovalID: a.ID}).First(&entity).Error; err != nil {
		return errors.New(m2.ErrorNotFound)
	}

	oa.ID = entity.ID

	approvalOA, err := copyOAToModel(in, a)
	if err != nil {
		return err
	}

	return DB.Model(&oa).Updates(approvalOA).Error
}

func (oa *ApprovalOA) BuildResContent(a *Approval, request *approval.CreateRequest) {
	if err := oa.copyOAToRpc(a, request); err != nil {
		return
	}
}

func (oa *ApprovalOA) copyOAToRpc(a *Approval, in *approval.CreateRequest) error {
	copier.CopyWithOption(&in.ApprovalOA, a, copier.Option{DeepCopy: true})

	//if err := oa.addOtherInfoToRpc(a, in); err != nil {
	//	return err
	//}

	return nil
}

/*func (oa *ApprovalOA) addOtherInfoToRpc(a *Approval, in *approval.CreateRequest) error {
	if oa.Leave != nil {
		copier.CopyWithOption(&a.ApprovalOA.Leave.ApplyTimes, in.ApprovalOA.Leave.ApplyTimes, copier.Option{DeepCopy: true})
	}

	if oa.MakeUp != nil {
		copier.CopyWithOption(&a.ApprovalOA.MakeUp.ApplyTimes, in.ApprovalOA.MakeUp.ApplyTimes, copier.Option{DeepCopy: true})
	}

	if oa.Turnover != nil {
		copier.CopyWithOption(&a.ApprovalOA.Turnover.ApplyTimes, in.ApprovalOA.Turnover.ApplyTimes, copier.Option{DeepCopy: true})
	}

	if oa.OverTime != nil {
		copier.CopyWithOption(&a.ApprovalOA.OverTime.ApplyTimes, in.ApprovalOA.OverTime.ApplyTimes, copier.Option{DeepCopy: true})
	}

	if oa.OutWork != nil {
		copier.CopyWithOption(&a.ApprovalOA.OutWork.ApplyTimes, in.ApprovalOA.OutWork.ApplyTimes, copier.Option{DeepCopy: true})
	}

	return nil
}
*/
func (oa *ApprovalOA) DeleteApproval(p *Approval) error {
	return DB.Where(&ApprovalOA{ApprovalID: p.ID}).Delete(&ApprovalOA{}).Error
}