package mermaid

import (
	"fmt"
	"strings"
)

// DiagramResponse 流程图响应
type DiagramResponse struct {
	MermaidCode string        `json:"mermaid_code"`
	CurrentNode string        `json:"current_node"`
	Nodes       []DiagramNode `json:"nodes"`
}

// DiagramNode 节点信息
type DiagramNode struct {
	ID          string `json:"id"`
	Label       string `json:"label"`
	Status      string `json:"status"` // completed / current / pending / error
	Assignee    string `json:"assignee"`
	CompletedAt string `json:"completed_at"`
}

// DiagramGenerator 流程图生成器
type DiagramGenerator struct{}

// NewDiagramGenerator 创建生成器
func NewDiagramGenerator() *DiagramGenerator {
	return &DiagramGenerator{}
}

// Generate 根据工单类型生成流程图
func (g *DiagramGenerator) Generate(workflowType, currentStatus string, nodes []DiagramNode) *DiagramResponse {
	switch workflowType {
	case "user_registration":
		return g.generateUserRegistration(currentStatus, nodes)
	case "user_management":
		return g.generateUserManagement(currentStatus, nodes)
	case "project_detail":
		return g.generateProjectDetail(currentStatus, nodes)
	case "microservice_update":
		return g.generateMicroserviceUpdate(currentStatus, nodes)
	default:
		return g.generateDefault(currentStatus, nodes)
	}
}

// generateUserRegistration 生成用户注册流程图
func (g *DiagramGenerator) generateUserRegistration(currentStatus string, nodes []DiagramNode) *DiagramResponse {
	var sb strings.Builder

	sb.WriteString("stateDiagram-v2\n")
	sb.WriteString("    direction LR\n\n")
	sb.WriteString("    [*] --> created: 用户注册\n\n")
	sb.WriteString("    created --> pending_review: 自动提交审核\n")
	sb.WriteString("    created --> revoked: 用户撤销\n\n")
	sb.WriteString("    pending_review --> approved: 超管审批通过\n")
	sb.WriteString("    pending_review --> rejected: 超管审批拒绝\n")
	sb.WriteString("    pending_review --> revoked: 用户撤销\n\n")
	sb.WriteString("    rejected --> pending_review: 用户修改后重新提交\n")
	sb.WriteString("    rejected --> revoked: 用户撤销\n\n")
	sb.WriteString("    approved --> closed: 关闭工单\n")
	sb.WriteString("    rejected --> closed: 关闭工单\n")
	sb.WriteString("    revoked --> closed: 关闭工单\n\n")
	sb.WriteString("    closed --> [*]\n\n")

	g.appendStyles(&sb, currentStatus)

	return &DiagramResponse{
		MermaidCode: sb.String(),
		CurrentNode: currentStatus,
		Nodes:       nodes,
	}
}

// generateUserManagement 生成用户管理流程图
func (g *DiagramGenerator) generateUserManagement(currentStatus string, nodes []DiagramNode) *DiagramResponse {
	var sb strings.Builder

	sb.WriteString("stateDiagram-v2\n")
	sb.WriteString("    direction LR\n\n")
	sb.WriteString("    [*] --> created: 发起管理操作\n\n")
	sb.WriteString("    created --> pending_review: 提交审核\n")
	sb.WriteString("    created --> revoked: 用户撤销\n")
	sb.WriteString("    created --> closed: 用户关闭\n\n")
	sb.WriteString("    pending_review --> approved: 超管审批通过\n")
	sb.WriteString("    pending_review --> rejected: 超管审批拒绝\n")
	sb.WriteString("    pending_review --> returned: 超管打回\n")
	sb.WriteString("    pending_review --> revoked: 用户撤销\n\n")
	sb.WriteString("    returned --> pending_review: 重新提交\n")
	sb.WriteString("    returned --> revoked: 用户撤销\n")
	sb.WriteString("    returned --> closed: 用户关闭\n\n")
	sb.WriteString("    rejected --> closed: 关闭工单\n")
	sb.WriteString("    approved --> closed: 关闭工单\n")
	sb.WriteString("    revoked --> closed: 关闭工单\n\n")
	sb.WriteString("    closed --> [*]\n\n")

	g.appendStyles(&sb, currentStatus)

	return &DiagramResponse{
		MermaidCode: sb.String(),
		CurrentNode: currentStatus,
		Nodes:       nodes,
	}
}

// generateProjectDetail 生成项目详情工单流程图
func (g *DiagramGenerator) generateProjectDetail(currentStatus string, nodes []DiagramNode) *DiagramResponse {
	var sb strings.Builder

	sb.WriteString("stateDiagram-v2\n")
	sb.WriteString("    direction LR\n\n")
	sb.WriteString("    [*] --> created: 创建项目\n")
	sb.WriteString("    created --> assigned: 分配填写人\n\n")
	sb.WriteString("    assigned --> in_progress: 用户开始填写\n")
	sb.WriteString("    assigned --> assigned: 重新分配\n\n")
	sb.WriteString("    in_progress --> draft_saved: 保存草稿\n")
	sb.WriteString("    draft_saved --> in_progress: 继续填写\n")
	sb.WriteString("    in_progress --> pending_review: 提交审核\n")
	sb.WriteString("    in_progress --> assigned: 重新分配\n\n")
	sb.WriteString("    pending_review --> approved: 审批通过\n")
	sb.WriteString("    pending_review --> returned: 审批打回\n\n")
	sb.WriteString("    returned --> in_progress: 用户重新填写\n")
	sb.WriteString("    returned --> pending_review: 重新提交\n\n")
	sb.WriteString("    approved --> closed: 项目认证完成\n\n")
	sb.WriteString("    closed --> [*]\n\n")

	g.appendStyles(&sb, currentStatus)

	return &DiagramResponse{
		MermaidCode: sb.String(),
		CurrentNode: currentStatus,
		Nodes:       nodes,
	}
}

// generateMicroserviceUpdate 生成微服务更新流程图
func (g *DiagramGenerator) generateMicroserviceUpdate(currentStatus string, nodes []DiagramNode) *DiagramResponse {
	var sb strings.Builder

	sb.WriteString("stateDiagram-v2\n")
	sb.WriteString("    direction LR\n\n")
	sb.WriteString("    [*] --> created: 发起更新请求\n\n")
	sb.WriteString("    created --> pending_review: 提交审核\n")
	sb.WriteString("    created --> revoked: 用户撤销\n\n")
	sb.WriteString("    pending_review --> approved: 审批通过\n")
	sb.WriteString("    pending_review --> returned: 审批打回\n")
	sb.WriteString("    pending_review --> rejected: 审批拒绝\n")
	sb.WriteString("    pending_review --> revoked: 用户撤销\n\n")
	sb.WriteString("    returned --> pending_review: 修改后重新提交\n")
	sb.WriteString("    returned --> revoked: 用户撤销\n\n")
	sb.WriteString("    approved --> executing: 开始执行\n\n")
	sb.WriteString("    executing --> monitoring: 更新成功\n")
	sb.WriteString("    executing --> rollbacked: 更新失败回滚\n\n")
	sb.WriteString("    monitoring --> closed: 运行正常\n")
	sb.WriteString("    monitoring --> rollbacked: 运行异常回滚\n\n")
	sb.WriteString("    rollbacked --> closed: 记录失败信息\n")
	sb.WriteString("    rejected --> closed: 关闭工单\n")
	sb.WriteString("    revoked --> closed: 关闭工单\n\n")
	sb.WriteString("    closed --> [*]\n\n")

	g.appendStyles(&sb, currentStatus)

	return &DiagramResponse{
		MermaidCode: sb.String(),
		CurrentNode: currentStatus,
		Nodes:       nodes,
	}
}

// generateDefault 生成默认流程图
func (g *DiagramGenerator) generateDefault(currentStatus string, nodes []DiagramNode) *DiagramResponse {
	var sb strings.Builder

	sb.WriteString("stateDiagram-v2\n")
	sb.WriteString("    direction LR\n\n")
	sb.WriteString("    [*] --> created: 工单创建\n\n")
	sb.WriteString("    created --> pending: 提交\n")
	sb.WriteString("    created --> assigned: 自动分配\n\n")
	sb.WriteString("    pending --> assigned: 分配\n\n")
	sb.WriteString("    assigned --> in_progress: 接单\n\n")
	sb.WriteString("    in_progress --> pending_review: 完成\n\n")
	sb.WriteString("    pending_review --> approved: 通过\n")
	sb.WriteString("    pending_review --> rejected: 拒绝\n")
	sb.WriteString("    pending_review --> returned: 打回\n\n")
	sb.WriteString("    returned --> in_progress: 重新提交\n\n")
	sb.WriteString("    approved --> closed: 关闭\n")
	sb.WriteString("    rejected --> closed: 关闭\n\n")
	sb.WriteString("    closed --> [*]\n\n")

	g.appendStyles(&sb, currentStatus)

	return &DiagramResponse{
		MermaidCode: sb.String(),
		CurrentNode: currentStatus,
		Nodes:       nodes,
	}
}

// appendStyles 添加样式定义
func (g *DiagramGenerator) appendStyles(sb *strings.Builder, currentStatus string) {
	sb.WriteString("    classDef completed fill:#4caf50,color:#fff\n")
	sb.WriteString("    classDef current fill:#ff9800,color:#fff,stroke-width:3px\n")
	sb.WriteString("    classDef pending fill:#e0e0e0,color:#666\n")
	sb.WriteString("    classDef error fill:#f44336,color:#fff\n\n")
	sb.WriteString(fmt.Sprintf("    class %s current\n", currentStatus))
}

// InjectNodeStyles 根据节点状态注入样式
func (g *DiagramGenerator) InjectNodeStyles(mermaidCode string, nodes []DiagramNode) string {
	var sb strings.Builder
	sb.WriteString(mermaidCode)
	sb.WriteString("\n")

	for _, node := range nodes {
		switch node.Status {
		case "completed":
			sb.WriteString(fmt.Sprintf("    class %s completed\n", node.ID))
		case "current":
			sb.WriteString(fmt.Sprintf("    class %s current\n", node.ID))
		case "error":
			sb.WriteString(fmt.Sprintf("    class %s error\n", node.ID))
		}
	}

	return sb.String()
}
