package store

// 数据库映射模型。表名经 GORM NamingStrategy 统一加 sundynix_ 前缀 + 单数：
//   User → sundynix_user，Task → sundynix_task。
// 约定：均嵌入 BaseModel（雪花字符串 id + created_at/updated_at + 软删 deleted_at）；
// 建表/改表一律走 AutoMigrate，不手写 DDL。

// User 是平台用户（Users）。
type User struct {
	BaseModel
	Email        string `gorm:"uniqueIndex;size:255"`
	Name         string `gorm:"size:64"`
	PasswordHash string `gorm:"size:255" json:"-"` // bcrypt；绝不出 JSON
}

// Task 是一次提交的 Agent 编排任务（DSL）。
// 业务 id（task_xxx，用于 NATS subject/stream）单列 TaskID，主键统一雪花。
type Task struct {
	BaseModel
	TenantID string `gorm:"size:64;index"`       // 多租户作用域（tenant 插件按 ctx 自动填/过滤）
	Owner    string `gorm:"size:64;index"`       // 提交者 user.id（个人工作台按此过滤"我的运行"）
	TaskID   string `gorm:"uniqueIndex;size:64"` // task_xxx
	Graph    string `gorm:"type:jsonb"`          // React Flow 导出的 DSL 原文
	Status   string `gorm:"size:32"`             // submitted / running / done / failed / timeout
	Detail   string `gorm:"type:text"`           // 失败/超时原因等（状态机回写）
	// 收尾持久化：供「运行历史复盘」永久回放（Redis 流仅 10min TTL，过期后历史任务靠这两列）。
	Output string `gorm:"type:text"` // 最终模型输出（收尾时由网关从流快照落库）
	Trace  string `gorm:"type:text"` // 执行轨迹事件 JSON 数组（存为文本，容忍空串；不在库内查它）
}

func (Task) isTenantScoped() {}

// Eval 是一次任务的自动化评测结果（dispatcher 评完经 NATS 回写，每任务一条，按 task_id upsert）。
type Eval struct {
	BaseModel
	TenantID  string  `gorm:"size:64;index"`       // 多租户作用域（SaveEval 从对应 task 复制）
	Owner     string  `gorm:"size:64;index"`       // 提交者 user.id（从对应 task 复制）
	TaskID    string  `gorm:"uniqueIndex;size:64"`
	Overall   float64 // 综合分 [0,1]
	Rule      float64 // 规则分
	LLM       float64 // LLM 质量分
	Faithful  float64 // RAG 忠实度分（0=无来源未评）
	Level     string  `gorm:"size:16"`   // ok / warn / poor
	Flags     string  `gorm:"type:text"` // 命中问题（JSON 数组字符串）
	Reason    string  `gorm:"type:text"` // 评语
	Sources   int     // 检索来源数
	Corrected bool    // 是否经低分自动纠偏重生成后采纳（恒温器闭环）
}

func (Eval) TableName() string { return "sundynix_eval" }
func (Eval) isTenantScoped()   {}

// AuditLog 是一条敏感操作留痕（改模型/密钥/激活 prompt/审批 等）。
// 由 Audit 中间件在请求收尾时 best-effort 写入；只增不改，供运维溯源。
type AuditLog struct {
	BaseModel
	Actor  string `gorm:"size:64;index"` // 操作者 uid（未登录/系统留空）
	Action string `gorm:"size:8"`        // HTTP 方法：POST / PUT / DELETE
	Route  string `gorm:"size:128"`      // 路由模式，如 /api/v1/admin/models/:id
	Path   string `gorm:"size:256"`      // 实际请求路径
	Status int    // HTTP 响应状态码
	IP     string `gorm:"size:64"`
	Detail string `gorm:"type:text"` // 备注（可选，如目标名/关键参数）
}

func (AuditLog) TableName() string { return "sundynix_audit_log" }

// GuardrailEvent 是一次输入护栏命中（硬拦截 blocked / 灰区 suspect）。
// 由 Guardrail 中间件命中时 best-effort 写入；供安全溯源"谁触发多少次护栏"。
type GuardrailEvent struct {
	BaseModel
	Actor   string `gorm:"size:64;index"` // 操作者 uid（未登录留空）
	Kind    string `gorm:"size:16;index"` // blocked（硬拦）/ suspect（灰区放行）
	Reason  string `gorm:"size:256"`      // 拦截原因（blocked）
	Signals string `gorm:"type:text"`     // 命中软信号 JSON 数组（suspect）
	Method  string `gorm:"size:8"`
	Path    string `gorm:"size:256"`
	IP      string `gorm:"size:64"`
}

func (GuardrailEvent) TableName() string { return "sundynix_guardrail_event" }

// Tenant 是多租户的计费/隔离单位（组织/账户）。个人用户 = 一个单人默认租户；团队/企业 = 多成员。
type Tenant struct {
	BaseModel
	Name               string `gorm:"size:128"`
	Slug               string `gorm:"size:64;uniqueIndex"`    // 唯一短标识（默认租户用 default-<uid>）
	Plan               string `gorm:"size:32;default:free"`   // free / pro / enterprise
	Status             string `gorm:"size:16;default:active"` // active / suspended
	CreditBalanceMicro int64  `gorm:"column:credit_balance_micro"` // 物化积分余额 ×10⁻⁶（= credit_ledger 之和；用量扣、充值增）
}

func (Tenant) TableName() string { return "sundynix_tenant" }

// TenantMember 是用户与租户的成员关系（带角色）。一个用户可属多个租户。
type TenantMember struct {
	BaseModel
	TenantID string `gorm:"size:64;uniqueIndex:idx_tenant_user;index"`
	UserID   string `gorm:"size:64;uniqueIndex:idx_tenant_user;index"`
	Role     string `gorm:"size:16"`                // owner / admin / member / viewer / billing_admin
	Status   string `gorm:"size:16;default:active"` // active / invited / removed
}

func (TenantMember) TableName() string { return "sundynix_tenant_member" }
