package models

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/codinl/go-logger"
	orm "go-admin/common/global"
	"regexp"
	"text/template"
	"time"
)

const (
	AnnouncementMessageType = 1 // 公告消息
	BusinessMessageType     = 2 // 业务消息

	TargetTypeByAll  = 1 // 接收对象类型：1=全员
	TargetTypeByRole = 2 // 接收对象类型：2=角色
	TargetTypeByUser = 3 // 接收对象类型：3=用户

	MessageStatusOnDraft   = 0 // 草稿
	MessageStatusOnStart   = 1 // 启用
	MessageStatusOnDisable = 2 // 禁用
	MessageStatusOnExpire  = 3 // 已过期

	MessageStart = 1 // 启用
	MessageStop  = 2 // 禁用

	BizTypeOnAllot = "stock_transfer" // 库存调拨
	EventOnAllot   = "wait_receive"   //待收货
)

// SystemMessageConfig 消息配置主表（公告 + 业务统一）
type SystemMessageConfig struct {
	Model

	MessageType     uint8      `json:"message_type"`         // 消息类型：1=公告，2=业务
	Title           string     `json:"title"`                // 消息标题
	ContentTemplate string     `json:"content_template"`     // 消息模板内容，支持{{变量}}
	Level           uint8      `json:"level"`                // 消息等级：1=普通，2=重要，3=紧急
	DisplayMode     uint8      `json:"display_mode"`         // 展示方式：1=弹窗，2=滚动，3=弹窗+滚动
	StartTime       *time.Time `json:"start_time,omitempty"` // 公告生效时间
	EndTime         *time.Time `json:"end_time,omitempty"`   // 公告失效时间
	BizType         string     `json:"biz_type,omitempty"`   // 业务类型
	Event           string     `json:"event,omitempty"`      // 事件类型
	Status          uint8      `json:"status"`               // 状态：0=草稿，1=启用，2=禁用，3=已过期
}

// SystemMessageTarget 接收对象配置表（支持角色/部门/用户/全员）
type SystemMessageTarget struct {
	Model

	MessageConfigID uint  `json:"message_config_id"`   // 对应消息配置 ID
	TargetType      uint8 `json:"target_type"`         // 接收对象类型：1=全员，2=角色，3=用户
	TargetID        int64 `json:"target_id,omitempty"` // 对象ID（角色ID/用户ID）
}

// SystemEventRegistry 业务事件注册表（用于事件枚举管理）
type SystemEventRegistry struct {
	Model

	BizType           string `json:"biz_type"`           // 业务类型
	Event             string `json:"event"`              // 事件名
	BizName           string `json:"biz_name"`           // 业务名称（展示用）
	EventName         string `json:"event_name"`         // 事件名称（展示用）
	Description       string `json:"description"`        // 说明
	TemplateVariables string `json:"template_variables"` // 可用变量 JSON 字符串
	IsEnabled         bool   `json:"is_enabled"`         // 是否启用
}

type TemplateVarItem struct {
	Key  string `json:"key"`
	Desc string `json:"desc"`
}

// SystemUserMessage 用户收到的消息记录表（实际发送记录）
type SystemUserMessage struct {
	Model

	UserID          int64      `json:"user_id"`             // 接收用户ID
	MessageConfigID uint       `json:"message_config_id"`   // 对应消息配置ID，可为空（被删时保留记录）
	MessageType     uint8      `json:"message_type"`        // 消息类型：1=公告，2=业务
	Title           string     `json:"title"`               // 消息标题快照
	Content         string     `json:"content"`             // 渲染后内容
	IsRead          bool       `json:"is_read"`             // 是否阅读
	ReadTime        *time.Time `json:"read_time,omitempty"` // 阅读时间
	IsVisible       bool       `json:"is_visible"`          // 是否展示给用户
}

// SysMessageCreateReq 新增公告请求结构体
type SysMessageCreateReq struct {
	Title           string  `json:"title" binding:"required"`                    // 消息标题
	ContentTemplate string  `json:"content_template" binding:"required"`         // 消息内容
	Level           uint8   `json:"level" binding:"required,oneof=1 2 3"`        // 消息等级：1=普通，2=重要，3=紧急
	DisplayMode     uint8   `json:"display_mode" binding:"required,oneof=1 2 3"` // 展示方式：1=弹窗，2=滚动，3=弹窗+滚动
	StartTime       string  `json:"start_time,omitempty"`                        // 公告生效时间
	EndTime         string  `json:"end_time,omitempty"`                          // 公告失效时间
	Status          uint8   `json:"status"`                                      // 状态：0=草稿，1=启用
	TargetType      uint8   `json:"target_type" binding:"required,oneof=1 2 3"`  // 接收对象类型：1=全员，2=角色，3=用户
	TargetID        []int64 `json:"target_id,omitempty"`                         // 对象ID（角色ID/用户ID）
}

// SysMessageCreateResp 创建成功响应
type SysMessageCreateResp struct {
	ID uint32 `json:"id"`
}

// SysMessageEditReq 编辑公告消息-入参
type SysMessageEditReq struct {
	ID              uint    `json:"id" binding:"required"`                       // 公告ID（必须）
	Title           string  `json:"title" binding:"required"`                    // 标题
	ContentTemplate string  `json:"content_template" binding:"required"`         // 内容模板
	Level           uint8   `json:"level" binding:"required,oneof=1 2 3"`        // 重要等级
	DisplayMode     uint8   `json:"display_mode" binding:"required,oneof=1 2 3"` // 展示模式
	StartTime       string  `json:"start_time"`                                  // 生效时间（可空）
	EndTime         string  `json:"end_time"`                                    // 失效时间（可空）
	Status          uint8   `json:"status"`                                      // 状态：0 草稿、1 启用
	TargetType      uint8   `json:"target_type" binding:"required,oneof=1 2 3"`  // 接收对象类型：1=全员，2=角色，3=用户
	TargetID        []int64 `json:"target_id,omitempty"`                         // 接收对象ID
}

// SysMessageListReq 公告消息列表-入参
type SysMessageListReq struct {
	Title       string `form:"title"`                // 消息标题
	Level       uint8  `form:"level"`                // 消息等级：1=普通，2=重要，3=紧急
	DisplayMode uint8  `form:"display_mode"`         // 展示方式：1=弹窗，2=滚动，3=弹窗+滚动
	Status      uint8  `form:"status"`               // 状态：0=草稿，1=启用，2=禁用，3=已过期
	TargetType  uint8  `form:"target_type"`          // 从接收对象配置表中筛选
	Page        int    `form:"page_index,default=1"` // 页码
	PageSize    int    `form:"page_size,default=10"` // 每页条数
}

// SysMessageListResp 公告消息列表-出参
type SysMessageListResp struct {
	List     []SysAnnouncementItem `json:"list"`
	Total    int64                 `json:"total"`      // 总条数
	Page     int                   `json:"page_index"` // 页码
	PageSize int                   `json:"page_size"`  // 每页条数
}

// SysAnnouncementItem 公告消息展示结构体
type SysAnnouncementItem struct {
	ID              uint32     `json:"id"`
	CreatedAt       time.Time  `json:"created_at"`
	UpdatedAt       time.Time  `json:"updated_at"`
	Title           string     `json:"title"`                // 消息标题
	ContentTemplate string     `json:"content_template"`     // 消息内容
	Level           uint8      `json:"level"`                // 消息等级：1=普通，2=重要，3=紧急
	DisplayMode     uint8      `json:"display_mode"`         // 展示方式：1=弹窗，2=滚动，3=弹窗+滚动
	StartTime       *time.Time `json:"start_time,omitempty"` // 公告生效时间
	EndTime         *time.Time `json:"end_time,omitempty"`   // 公告失效时间
	Status          uint8      `json:"status"`               // 状态：0=草稿，1=启用，2=禁用，3=已过期
	TargetType      uint8      `json:"target_type"`          // 接收对象类型：1=全员，2=角色，3=用户
	TargetID        []int64    `json:"target_id,omitempty"`  // 对象ID（角色ID/用户ID）
}

// SysMessageSetStatusReq 设置公告消息状态
type SysMessageSetStatusReq struct {
	ID     uint  `json:"id" binding:"required"`
	Status uint8 `json:"status" binding:"required"` // 目标状态：1=启用，2=禁用
}

// SysMessageDeleteReq 删除公告消息
type SysMessageDeleteReq struct {
	ID uint `json:"id" binding:"required"`
}

// SysMessageDetailReq 公告详情请求
type SysMessageDetailReq struct {
	ID uint `json:"id" binding:"required"`
}

// SysMessageDetailResp 公告详情响应
type SysMessageDetailResp struct {
	ID          uint       `json:"id"`
	CreatedAt   time.Time  `json:"created_at"`
	UpdatedAt   time.Time  `json:"updated_at"`
	Title       string     `json:"title"`                // 消息标题
	Content     string     `json:"content"`              // 消息内容
	Level       uint8      `json:"level"`                // 消息等级：1=普通，2=重要，3=紧急
	DisplayMode uint8      `json:"display_mode"`         // 展示方式：1=弹窗，2=滚动，3=弹窗+滚动
	Status      uint8      `json:"status"`               // 状态：0=草稿，1=启用，2=禁用，3=已过期
	StartTime   *time.Time `json:"start_time,omitempty"` // 公告生效时间
	EndTime     *time.Time `json:"end_time,omitempty"`   // 公告失效时间
	TargetType  uint8      `json:"target_type"`          // 接收对象类型：1=全员，2=角色，3=用户
	TargetID    []int64    `json:"target_id,omitempty"`  // 对象ID（角色ID/用户ID）
}

// UserMessageListReq 用户消息列表-入参
type UserMessageListReq struct {
	IsRead   int `json:"is_read"`    // 0-全部；1-已读；2-未读
	Page     int `json:"page_index"` // 页码
	PageSize int `json:"page_size"`  // 每页数量
}

// UserMessageListResp 用户消息列表-出参
type UserMessageListResp struct {
	List     []UserMessageDetailRespItem `json:"list"`
	Total    int64                       `json:"total"`
	Page     int                         `json:"page_index"`
	PageSize int                         `json:"page_size"`
}

type UserMessageDetailRespItem struct {
	ID              uint       `json:"id"`
	CreatedAt       time.Time  `json:"created_at"`             // 接收时间
	UserID          int64      `json:"user_id"`                // 接收用户ID
	MessageConfigID uint       `json:"message_config_id"`      // 对应消息配置ID，可为空（被删时保留记录）
	MessageType     uint8      `json:"message_type"`           // 消息类型：1=公告，2=业务
	Title           string     `json:"title"`                  // 消息标题快照
	Content         string     `json:"content"`                // 渲染后内容
	IsRead          bool       `json:"is_read"`                // 是否阅读
	ReadTime        *time.Time `json:"read_time,omitempty"`    // 阅读时间
	IsVisible       bool       `json:"is_visible"`             // 是否展示给用户
	Level           uint8      `json:"level,omitempty"`        // 公告消息字段，消息等级：1=普通，2=重要，3=紧急
	DisplayMode     uint8      `json:"display_mode,omitempty"` // 公告消息字段，展示方式：1=弹窗，2=滚动，3=弹窗+滚动
	StartTime       *time.Time `json:"start_time,omitempty"`   // 公告消息字段，公告生效时间
	EndTime         *time.Time `json:"end_time,omitempty"`     // 公告消息字段，公告失效时间
}

// UserMessageSetStatusReq 用户阅读消息-入参
type UserMessageSetStatusReq struct {
	ID      []uint `json:"id"`       // 消息ID（可选，read_all 为 false 时必传）
	ReadAll bool   `json:"read_all"` // 是否设为全部已读
}

// BusMessageCreateReq 新增业务消息-入参
type BusMessageCreateReq struct {
	Title           string  `json:"title" binding:"required"`            // 消息标题
	ContentTemplate string  `json:"content_template" binding:"required"` // 消息模板
	BizType         string  `json:"biz_type" binding:"required"`         // 业务类型
	Event           string  `json:"event" binding:"required"`            // 事件类型
	RoleID          []int64 `json:"role_id" binding:"required"`          // 接收对象：角色ID列表
	Status          uint8   `json:"status" binding:"required"`           // 消息状态：1启用，2禁用
}

// BusMessageCreateResp 新增业务消息-出参
type BusMessageCreateResp struct {
	ID uint `json:"id"`
}

// BusMessageListReq 业务消息列表 - 入参
type BusMessageListReq struct {
	BizType  string  `json:"biz_type"`   // 业务类型
	Event    string  `json:"event"`      // 事件类型
	Status   uint8   `json:"status"`     // 状态：1启用，2禁用
	RoleID   []int64 `json:"role_id"`    // 角色ID
	Page     int     `json:"page_index"` // 页码
	PageSize int     `json:"page_size"`  // 每页条数
}

// BusMessageListResp 业务消息列表 - 出参
type BusMessageListResp struct {
	List     []BusMessageItem `json:"list"`
	Total    int64            `json:"total"`
	Page     int              `json:"page_index"`
	PageSize int              `json:"page_size"`
}

// BusMessageItem 单条业务消息展示项
type BusMessageItem struct {
	ID              uint32    `json:"id"`
	CreatedAt       time.Time `json:"created_at"`
	UpdatedAt       time.Time `json:"updated_at"`
	Title           string    `json:"title"`            // 消息标题
	ContentTemplate string    `json:"content_template"` // 消息模版
	BizType         string    `json:"biz_type"`         // 业务类型
	BizName         string    `json:"biz_name"`         // 业务名称
	Event           string    `json:"event"`            // 事件类型
	EventName       string    `json:"event_name"`       // 事件名称
	Status          uint8     `json:"status"`           // 状态：1启用，2禁用
	RoleID          []int64   `json:"role_id"`          // 角色ID
}

// BusMessageEditReq 编辑业务消息 - 入参
type BusMessageEditReq struct {
	ID              uint32  `json:"id" binding:"required"`               // 消息ID
	Title           string  `json:"title" binding:"required"`            // 消息标题
	BizType         string  `json:"biz_type" binding:"required"`         // 业务类型
	Event           string  `json:"event" binding:"required"`            // 事件类型
	ContentTemplate string  `json:"content_template" binding:"required"` // 消息模版
	Status          uint8   `json:"status" binding:"required"`           // 状态：1启用，2禁用
	RoleID          []int64 `json:"role_id" binding:"required"`          // 接收对象：角色ID列表
}

// BusMessageSetStatusReq 设置业务消息状态
type BusMessageSetStatusReq struct {
	ID     uint  `json:"id" binding:"required"`
	Status uint8 `json:"status" binding:"required"` // 目标状态：1=启用，2=禁用
}

// BusMessageDeleteReq 删除业务消息
type BusMessageDeleteReq struct {
	ID uint `json:"id" binding:"required"`
}

// BusMessageDetailReq 业务消息详情 - 入参
type BusMessageDetailReq struct {
	ID uint64 `json:"id" binding:"required"` // 业务消息ID
}

// BizTypeListReq 查询业务类型列表 - 入参
type BizTypeListReq struct {
	Page     int `json:"page_index"`
	PageSize int `json:"page_size"`
}

// BizTypeListResp 查询业务类型列表 - 出参
type BizTypeListResp struct {
	List     []BizTypeItem `json:"list"`       // 业务类型列表
	Total    int64         `json:"total"`      // 总数
	Page     int           `json:"page_index"` // 当前页
	PageSize int           `json:"page_size"`  // 页大小
}

// BizTypeItem 单条业务类型展示项
type BizTypeItem struct {
	BizType string `json:"biz_type"` // 业务类型编码
	BizName string `json:"biz_name"` // 业务名称
}

// EventListReq 查询事件类型列表 - 入参
type EventListReq struct {
	BizType  string `json:"biz_type" binding:"required"`
	Page     int    `json:"page_index"`
	PageSize int    `json:"page_size"`
}

// EventListResp 查询事件类型列表 - 出参
type EventListResp struct {
	List     []EventItem `json:"list"`
	Total    int64       `json:"total"`
	Page     int         `json:"page_index"`
	PageSize int         `json:"page_size"`
}

// EventItem 单条事件类型展示项
type EventItem struct {
	Event     string `json:"event"`      // 事件类型编码
	EventName string `json:"event_name"` // 业务类型编码
}

// TemplateVarReq 查询模板变量字段列表 - 入参
type TemplateVarReq struct {
	BizType  string `json:"biz_type" binding:"required"` // 业务类型
	Event    string `json:"event" binding:"required"`    // 事件类型
	Page     int    `json:"page_index"`                  // 当前页
	PageSize int    `json:"page_size"`                   // 每页大小
}

// TemplateVarListResp 查询模板变量字段列表 - 出参
type TemplateVarListResp struct {
	List     []TemplateVariable `json:"list"`       // 模板变量列表
	Total    int64              `json:"total"`      // 总数
	Page     int                `json:"page_index"` // 当前页
	PageSize int                `json:"page_size"`  // 每页条数
}

// TemplateVariable 模板变量项
type TemplateVariable struct {
	Key  string `json:"key"`  // 模板变量键
	Desc string `json:"desc"` // 模板变量描述
}

// UserMessageDeleteReq 用户消息-删除 请求参数
type UserMessageDeleteReq struct {
	IDs       []uint `json:"ids"`        // 消息ID列表（DeleteAll=false时必填）
	DeleteAll bool   `json:"delete_all"` // 是否删除全部
}

// ValidateBizEventAndTemplate 校验业务类型、事件类型以及模板变量是否合法
func ValidateBizEventAndTemplate(bizType, event, contentTemplate string) error {
	var registry SystemEventRegistry
	err := orm.Eloquent.Where("biz_type = ? AND event = ? AND is_enabled = ?", bizType, event, true).First(&registry).Error
	if err != nil {
		return errors.New("业务类型或事件类型无效")
	}

	// 支持结构体数组格式：[{"key":"user_name","desc":"用户名"}]
	var allowedItems []TemplateVarItem
	if err := json.Unmarshal([]byte(registry.TemplateVariables), &allowedItems); err != nil {
		return errors.New("事件注册表中变量格式非法")
	}

	// 提取合法 key
	allowedMap := make(map[string]bool)
	for _, item := range allowedItems {
		allowedMap[item.Key] = true
	}

	// 提取模板中的变量名
	varRegex := regexp.MustCompile(`\{\{\s*(\w+)\s*\}\}`)
	matches := varRegex.FindAllStringSubmatch(contentTemplate, -1)
	for _, match := range matches {
		varName := match[1]
		if !allowedMap[varName] {
			return fmt.Errorf("模板中使用了未注册变量：%s", varName)
		}
	}

	return nil
}

// TriggerBizEvent 业务消息-触发消息模版
func TriggerBizEvent(bizType, event string, inputVars map[string]interface{}, optionalReceivers ...uint32) error {
	// 1. 查找启用的消息配置
	var cfg SystemMessageConfig
	err := orm.Eloquent.Where("message_type = ? AND biz_type = ? AND event = ? AND status = 1",
		BusinessMessageType, bizType, event).Find(&cfg).Error
	if err != nil {
		return nil // 无需发送
	}

	// 2. 渲染模板内容
	content, err := RenderTemplate(cfg.ContentTemplate, inputVars)
	if err != nil {
		return fmt.Errorf("模板渲染失败: %w", err)
	}

	// 查找门店ID
	var storeId uint32
	if len(optionalReceivers) > 0 {
		if event == EventOnAllot { // 库存调拨-待收货消息
			storeId = optionalReceivers[0]
		}
	} else {
		fmt.Println("没有传入 optionalReceivers，使用默认配置")
	}

	// 3. 查找接收用户
	receiverIDs, err := GetTargetUserIds(cfg.ID, storeId)
	if err != nil {
		return fmt.Errorf("获取接收人失败: %w", err)
	}

	// 4. 写入 user_message 表
	var msgs []SystemUserMessage
	for _, uid := range receiverIDs {
		msgs = append(msgs, SystemUserMessage{
			UserID:          uid,
			MessageConfigID: uint(cfg.ID),
			MessageType:     BusinessMessageType,
			Title:           cfg.Title,
			Content:         content,
			IsRead:          false,
			IsVisible:       true,
		})
	}

	return orm.Eloquent.Create(&msgs).Error
}

// GetTargetUserIds 获取接收用户函数模板（支持角色）
func GetTargetUserIds(configID uint32, storeId uint32) ([]int64, error) {
	// 1.查询角色绑定
	var targets []SystemMessageTarget
	err := orm.Eloquent.Where("message_config_id = ? AND target_type = ?", configID, TargetTypeByRole).
		Find(&targets).Error
	if err != nil {
		return nil, err
	}

	// 2.查询该模版配置的所有角色
	var roleIDs []int64
	for _, t := range targets {
		roleIDs = append(roleIDs, t.TargetID)
	}

	// 3.查询该角色下的用户（包含字段 uid, store_data）
	var users []SysUser
	err = orm.Eloquent.Table("sys_user").
		Where("role_id IN ? AND deleted_at IS NULL", roleIDs).
		Find(&users).Error
	if err != nil {
		return nil, err
	}

	// 如果 storeId == 0，直接返回所有 uid
	if storeId == 0 {
		var allUserIDs []int64
		for _, user := range users {
			allUserIDs = append(allUserIDs, int64(user.Uid))
		}
		return allUserIDs, nil
	}

	// 4.筛选出门店有效用户
	now := time.Now()
	var validUserIDs []int64

	for _, user := range users {
		var storeList []StoreInfo
		if err := json.Unmarshal([]byte(user.StoreData), &storeList); err != nil {
			continue
		}

		for _, store := range storeList {
			// 解析时间
			expireTime, err := time.Parse(StoreDateTimeFormat, store.ExpireTime)
			if err != nil {
				continue
			}
			// 包含当天有效时间
			expireTime = expireTime.Add(24*time.Hour - time.Second)
			if store.StoreID == int(storeId) && expireTime.After(now) {
				validUserIDs = append(validUserIDs, int64(user.UserId))
				break
			}
		}
	}

	return validUserIDs, nil
}

// RenderTemplate 渲染模版内容
func RenderTemplate(templateStr string, data map[string]interface{}) (string, error) {
	// 创建模板实例
	tmpl, err := template.New("msg").Option("missingkey=zero").Parse(templateStr)
	if err != nil {
		return "", err
	}

	// 渲染
	var buf bytes.Buffer
	err = tmpl.Execute(&buf, data)
	if err != nil {
		return "", err
	}

	return buf.String(), nil
}

// CheckExpiredSystemMessages 检查公告消息是否过期，如果过期则更新状态为3
func CheckExpiredSystemMessages() {
	now := time.Now()

	// 查询所有状态为启用（1）、类型为公告（1）、且 EndTime 不为空、已过期的消息
	var expiredMessages []SystemMessageConfig
	err := orm.Eloquent.
		Table("system_message_config").
		Where("message_type = ? AND status = ? AND end_time IS NOT NULL AND end_time < ?",
			AnnouncementMessageType, MessageStatusOnStart, now).
		Find(&expiredMessages).Error

	if err != nil {
		logger.Errorf("Failed to query expired messages: %v", err)
		return
	}

	if len(expiredMessages) == 0 {
		logger.Info("No expired announcements found.")
		return
	}

	// 遍历并更新状态
	for _, msg := range expiredMessages {
		err := orm.Eloquent.
			Table("system_message_config").
			Where("id = ?", msg.ID).
			Update("status", MessageStatusOnExpire).Error
		if err != nil {
			logger.Errorf("Failed to update status for message ID %d: %v", msg.ID, err)
		} else {
			logger.Infof("Message ID %d marked as expired.", msg.ID)
		}
	}
}
