/**
 @author: xiaopengzhu
 @date: 2022/7/28
 @description:
**/

package v1

import (
	"database/sql"
	"time"

	"gorm.io/gorm"
)

type Approval struct {
	ID                uint64         `json:"id" gorm:"primary_key;AUTO_INCREMENT;column:id"`
	ApprovalType      int            `json:"approvalType" gorm:"column:approvalType"` // biz approval type
	Status            string         `json:"status" gorm:"column:status"`             // status
	Luid              string         `json:"luid" gorm:"column:luid"`                 // lark id
	InstanceCode      string         `json:"instanceCode" gorm:"column:instanceCode"` // instance code in lark
	CreatedAt         time.Time      `json:"createdAt" gorm:"column:createdAt"`
	UpdatedAt         sql.NullTime   `json:"updatedAt" gorm:"column:updatedAt"`
	DeletedAt         gorm.DeletedAt `json:"deletedAt" gorm:"column:deletedAt"`
	LarkInsShadow     string         `json:"larkInsShadow" gorm:"column:larkInsShadow"`
	RequestBodyShadow string         `json:"requestBodyShadow" gorm:"column:requestBodyShadow"`
	ManagementID      string         `json:"managementID" gorm:"column:managementID"`
}

func (u *Approval) TableName() string {
	return "cloud_approval"
}

type LarkCreateApprovalBody struct {
	ApprovalCode string `json:"approval_code"`
	UserId       string `json:"user_id,omitempty"`
	OpenId       string `json:"open_id"`
	Form         string `json:"form"`
}

// LarkCreateApprovalRes 创建飞书审批返回体.
type LarkCreateApprovalRes struct {
	InstanceCode string `json:"instance_code"` // 审批实例 Code
}

// LarkApprovalDefinition the definition of approval in lark.
type LarkApprovalDefinition struct {
	ApprovalName string `json:"approval_name"`
	Form         string `json:"form"`
	Status       string `json:"status"`
}

type ApprovalQueryParams struct {
	ApprovalType int       `json:"approvalType" ` // 审批类型
	Status       string    `json:"status"`        // 审批状态
	Luid         string    `json:"luid"`          // lark id
	StartTime    time.Time `json:"startTime"`     // 开始时间
	EndTime      time.Time `json:"EndTime"`       // 结束时间
}

// ApprovalInLark lark中审批实例.
type ApprovalInLark struct {
	ApprovalName   string      `json:"approval_name"`             // 审批名称
	StartTime      string      `json:"start_time"`                // 审批创建时间
	EndTime        string      `json:"end_time"`                  // 审批完成时间，未完成为 0
	UserId         string      `json:"user_id"`                   // 发起审批用户
	UserName       string      `json:"user_name,omitempty"`       // 发起审批用户名称
	DepartmentId   string      `json:"department_id"`             // 发起审批用户所在部门
	DepartmentName string      `json:"department_name,omitempty"` // 发起审批用户所在部门名称
	Status         string      `json:"status"`                    // 审批实例状态 pending approved rejected canceled deleted
	TaskList       []*Task     `json:"task_list,omitempty"`       // 审批任务列表
	CommentList    []*Comment  `json:"comment,omitempty"`         // 评论列表
	TimeLine       []*TimeLine `json:"time_line"`                 // 审批状态
	Revert         bool        `json:"revert"`                    // 单据是否被撤销
	Form           string      `json:"form"`
	FormVO         interface{} `json:"form_vo,omitempty"` // 审批表单数据
}

// Task 审批任务.
type Task struct {
	UserId    string `json:"user_id"`             // 审批人的用户id，自动通过、自动拒绝 时为空
	UserName  string `json:"user_name,omitempty"` // 审批人的用户名称，自动通过、自动拒绝 时为空
	Status    string `json:"status"`              // 任务状态
	Type      string `json:"type"`                // 审批方式   AND OR AUTO_PASS AUTO_REJECT SEQUENTIAL
	StartTime string `json:"start_time"`          // 开始时间
	EndTime   string `json:"end_time"`            // 结束时间
}

// Comment 评论.
type Comment struct {
	UserId     string `json:"user_id"`     // 发表评论用户
	Comment    string `json:"comment"`     // 评论内容
	CreateTime string `json:"create_time"` // 创建时间
}

// TimeLine 审批状态.
type TimeLine struct {
	Type       string    `json:"type"`         // 动态类型，不同类型 ext 内的 user_id_list 含义不一样
	CreateTime string    `json:"create_time"`  // 发生时间
	UserId     string    `json:"user_id"`      // 动态产生用户
	UserIdList []string  `json:"user_id_list"` // 被抄送人列表
	Comment    string    `json:"comment"`      // 理由
	CcUserList []*CcUser `json:"cc_user_list"` // 抄送人列表
}

// CcUser 抄送人.
type CcUser struct {
	UserId string `json:"user_id"` // 抄送人 user id
}

type LarkApprovalPartChild struct {
	Id      string      `json:"id"`
	Name    string      `json:"name"`
	Type    string      `json:"type"`
	Value   interface{} `json:"value,omitempty"`
	OpenIds interface{} `json:"open_ids,omitempty"`
	Ext     interface{} `json:"ext,omitempty"`
	Option  []Option    `json:"option,omitempty"`
}

// LarkApprovalPart is the struct corresponding to the "form" field in lark approval definition.
type LarkApprovalPart struct {
	Id       string                  `json:"id"`
	Name     string                  `json:"name"`
	Type     string                  `json:"type"`
	Value    interface{}             `json:"value,omitempty"`
	OpenIds  interface{}             `json:"open_ids,omitempty"`
	Ext      interface{}             `json:"ext,omitempty"`
	Option   []Option                `json:"option,omitempty"`
	Children []LarkApprovalPartChild `json:"children,omitempty"`
}

// Option every option in approval definition.
type Option struct {
	Value string `json:"value"`
	Text  string `json:"text"`
}

type FormItem struct {
	Id    string      `json:"id"`
	Name  string      `json:"name,omitempty"`
	Type  string      `json:"type"`
	Value interface{} `json:"value"`
}

type DepartmentValue struct {
	OpenId string `json:"open_id"`
}

// DepartmentData the department info in the lark.
type DepartmentData struct {
	HasMore   bool   `json:"has_more,omitempty"`
	Items     []Item `json:"items"`
	PageToken string `json:"page_token"`
}
type Item struct {
	DepartmentId       string `json:"department_id,omitempty"`
	Name               string `json:"name"`
	OpenDepartmentId   string `json:"open_department_id"`
	ParentDepartmentId string `json:"parent_department_id"`
	Status             Status `json:"status"`
}

type Status struct {
	IsDeleted bool `json:"is_deleted"`
}

type DepartmentNode struct {
	Name               string            `json:"name"`
	OpenDepartmentId   string            `json:"open_department_id"`
	ParentDepartmentId string            `json:"parent_department_id"`
	Children           []*DepartmentNode `json:"children"`
}

type ApprovalBody struct {
	ApprovalType int         `json:"approvalType"` // 审批类型
	Form         interface{} `json:"form"`         // 审批的表单信息
}

type NewBudgetItem struct {
	Month  string  `json:"month"`
	Budget float64 `json:"budget"`
}

type ApplyForm struct {
	Provider    string          `json:"provider"`
	Name        string          `json:"name"`
	Department  string          `json:"department"`
	Description string          `json:"description"`
	BudgetItems []NewBudgetItem `json:"budgetItems"`
}

type BudgetChangeForm struct {
	// 1 for new, 2 for change
	BudgetType   int          `json:"budgetType"`
	ManagementId string       `json:"managementId"`
	Description  string       `json:"description"`
	BudgetItems  []BudgetItem `json:"items" mapstructure:"items"`
}

type JoinForm struct {
	ManagementId string   `json:"managementId"`
	Description  string   `json:"description"`
	RoleCodes    []string `json:"roleCodes"`
}

type InviteForm struct {
	ManagementId string       `json:"managementId"`
	InviteUsers  []InviteItem `json:"inviteUsers"`
	Description  string       `json:"description"`
}

type InviteItem struct {
	Member   string `json:"member"`
	RoleCode string `json:"roleCode"`
}

type PermissionForm struct {
	ManagementId string `json:"managementId"`
	Owner        string `json:"owner"`
	Description  string `json:"description"`
}

type RemoveForm struct {
	ManagementId string   `json:"managementId"`
	Members      []string `json:"members"` // user lark id
	Description  string   `json:"description"`
}

type CloseForm struct {
	ManagementId string `json:"managementId"`
	CloseTime    string `json:"closeTime"`
	Description  string `json:"description"`
}

type BudgetItem struct {
	Month  string  `json:"month"`
	Before float64 `json:"before"`
	After  float64 `json:"after"`
}

const (
	TypeApplyAccount = iota + 1
	TypeChangeBudget
	TypeInviteUser
	TypeJoinAccount
	TypeChangePermission
	TypeRemoveUser
	TypeCloseAccount
)

var ApprovalCodeMap = map[int]string{
	TypeApplyAccount:     "26CF1F93-E6D4-4FD2-B35C-E17B56C632A9",
	TypeChangeBudget:     "A3C30A9C-843C-4B07-BBC0-8F664D2EBEFB",
	TypeInviteUser:       "8D807B9E-7AA1-4488-B8E1-7DB7375F365E",
	TypeJoinAccount:      "23B48F04-C2C2-402E-90C3-0CD8F88025B0",
	TypeChangePermission: "277A23F8-2DFD-4848-89B6-6734032C4252",
	TypeRemoveUser:       "CCC00E1D-4A5B-4ED6-A0B8-D31B59ECA2BF",
	TypeCloseAccount:     "FB6A94F2-7E72-4364-A3F8-5EE2BBA25C65",
}

// from lark approval status field
// ref: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/approval-v4/instance/get
const (
	ApprStPending  = "PENDING"
	ApprStApproved = "APPROVED"
	ApprStRejected = "REJECTED"
	ApprStCanceled = "CANCELED"
	ApprStDeleted  = "DELETED"
	ApprStReverted = "REVERTED"
)

const (
	BudgetApprTypeNew    = 1
	BudgetApprTypeChange = 2
)
