package service

import (
	"context"
	"encoding/json"
	"fmt"
)

// VersionSnapshot 版本快照结构
type VersionSnapshot struct {
	BasicInfo        *BasicInfo        `json:"basic_info"`
	DeployBusiness   *DeployBusiness   `json:"deploy_business"`
	DeployEnv        *DeployEnv        `json:"deploy_env"`
	DeployMiddleware *DeployMiddleware `json:"deploy_middleware"`
}

// BasicInfo 基本信息
type BasicInfo struct {
	Province        string `json:"province"`
	City            string `json:"city"`
	IndustryContact string `json:"industry_contact"`
	IndustryPhone   string `json:"industry_phone"`
	ProjectNature   string `json:"project_nature"`
}

// DeployBusiness 部署业务信息
type DeployBusiness struct {
	DeployerName    string `json:"deployer_name"`
	DeployerPhone   string `json:"deployer_phone"`
	DeployStartTime string `json:"deploy_start_time"`
	DeployEndTime   string `json:"deploy_end_time"`
	SystemVersion   string `json:"system_version"`
	SystemType      string `json:"system_type"`
	MainEntrance    string `json:"main_entrance"`
	AdminUsername   string `json:"admin_username"`
	AdminPassword   string `json:"admin_password"` // 加密存储
}

// DeployEnv 部署环境信息
type DeployEnv struct {
	Hosts          []HostInfo `json:"hosts"`
	NetworkType    string     `json:"network_type"`
	MainPublicIP   string     `json:"main_public_ip"`
	DomainURL      string     `json:"domain_url"`
	SSLEnabled     bool       `json:"ssl_enabled"`
	ManagementType string     `json:"management_type"`
	ManagementURL  string     `json:"management_url"`
	ManagementUser string     `json:"management_user"`
	ManagementPwd  string     `json:"management_pwd"` // 加密存储
	HostCount      int        `json:"host_count"`
	TotalCPU       int        `json:"total_cpu"`
	CPUModel       string     `json:"cpu_model"`
	TotalMemory    int        `json:"total_memory"`
	TotalStorage   int        `json:"total_storage"`
}

// HostInfo 主机信息
type HostInfo struct {
	Hostname        string `json:"hostname"`
	InternalIP      string `json:"internal_ip"`
	PublicIP        string `json:"public_ip"`
	CanAccessPublic bool   `json:"can_access_public"`
	SSHPort         int    `json:"ssh_port"`
	SSHUser         string `json:"ssh_user"`
	SSHPwd          string `json:"ssh_pwd"` // 加密存储
	Role            string `json:"role"`    // master/worker/storage
}

// DeployMiddleware 部署中间件信息
type DeployMiddleware struct {
	MySQL        MiddlewareInfo `json:"mysql"`
	Redis        MiddlewareInfo `json:"redis"`
	EMQX         MiddlewareInfo `json:"emqx"`
	MinIO        MiddlewareInfo `json:"minio"`
	InfluxDB     MiddlewareInfo `json:"influxdb"`
	Nacos        MiddlewareInfo `json:"nacos"`
	K8SDashboard MiddlewareInfo `json:"k8s_dashboard"`
}

// MiddlewareInfo 中间件信息
type MiddlewareInfo struct {
	PublicIP     string `json:"public_ip"`
	PublicPort   int    `json:"public_port"`
	InternalIP   string `json:"internal_ip"`
	InternalPort int    `json:"internal_port"`
	K8SAddress   string `json:"k8s_address"`
	K8SPort      int    `json:"k8s_port"`
	AdminUser    string `json:"admin_user"`
	AdminPwd     string `json:"admin_pwd"` // 加密存储
	Version      string `json:"version"`
}

// DiffResult 差异结果
type DiffResult struct {
	Module     string      `json:"module"`
	FieldDiffs []FieldDiff `json:"field_diffs"`
}

// FieldDiff 字段差异
type FieldDiff struct {
	FieldPath  string      `json:"field_path"`
	FieldName  string      `json:"field_name"`
	OldValue   interface{} `json:"old_value"`
	NewValue   interface{} `json:"new_value"`
	ChangeType string      `json:"change_type"` // add/modify/delete
}

// VersionService 版本服务
type VersionService struct {
	repo     VersionRepository
	fieldMap map[string]string // 字段路径到中文名的映射
}

// NewVersionService 创建版本服务
func NewVersionService(repo VersionRepository) *VersionService {
	return &VersionService{
		repo:     repo,
		fieldMap: initFieldNameMap(),
	}
}

// initFieldNameMap 初始化字段名映射
func initFieldNameMap() map[string]string {
	return map[string]string{
		"basic_info.province":           "省份",
		"basic_info.city":               "城市",
		"basic_info.industry_contact":   "行业组人员",
		"basic_info.industry_phone":     "行业组电话",
		"basic_info.project_nature":     "项目性质",
		"deploy_business.deployer_name": "部署人姓名",
		"deploy_business.system_version": "系统版本",
		"deploy_env.host_count":         "主机台数",
		"deploy_env.main_public_ip":     "主公网IP",
		"deploy_env.domain_url":         "域名URL",
		// ... 更多字段映射
	}
}

// CompareVersions 比较两个版本的差异
func (s *VersionService) CompareVersions(
	ctx context.Context,
	baseVersion, targetVersion *VersionSnapshot,
) ([]DiffResult, error) {
	var results []DiffResult

	modules := []struct {
		Name   string
		Base   interface{}
		Target interface{}
	}{
		{"基本信息", baseVersion.BasicInfo, targetVersion.BasicInfo},
		{"部署业务", baseVersion.DeployBusiness, targetVersion.DeployBusiness},
		{"部署环境", baseVersion.DeployEnv, targetVersion.DeployEnv},
		{"部署中间件", baseVersion.DeployMiddleware, targetVersion.DeployMiddleware},
	}

	for _, m := range modules {
		diffs := s.diffJSON(m.Name, m.Base, m.Target)
		if len(diffs) > 0 {
			results = append(results, DiffResult{
				Module:     m.Name,
				FieldDiffs: diffs,
			})
		}
	}
	return results, nil
}

// diffJSON 对比两个结构体的差异
func (s *VersionService) diffJSON(moduleName string, base, target interface{}) []FieldDiff {
	var diffs []FieldDiff

	baseBytes, _ := json.Marshal(base)
	targetBytes, _ := json.Marshal(target)

	var baseMap, targetMap map[string]interface{}
	json.Unmarshal(baseBytes, &baseMap)
	json.Unmarshal(targetBytes, &targetMap)

	// 遍历目标版本的字段
	for key, newVal := range targetMap {
		oldVal, exists := baseMap[key]
		fieldPath := fmt.Sprintf("%s.%s", moduleName, key)

		if !exists {
			// 新增字段
			diffs = append(diffs, FieldDiff{
				FieldPath:  fieldPath,
				FieldName:  s.getFieldName(fieldPath),
				OldValue:   nil,
				NewValue:   newVal,
				ChangeType: "add",
			})
		} else if !equalValues(oldVal, newVal) {
			// 修改字段
			diffs = append(diffs, FieldDiff{
				FieldPath:  fieldPath,
				FieldName:  s.getFieldName(fieldPath),
				OldValue:   oldVal,
				NewValue:   newVal,
				ChangeType: "modify",
			})
		}
	}

	// 检查删除的字段
	for key, oldVal := range baseMap {
		if _, exists := targetMap[key]; !exists {
			fieldPath := fmt.Sprintf("%s.%s", moduleName, key)
			diffs = append(diffs, FieldDiff{
				FieldPath:  fieldPath,
				FieldName:  s.getFieldName(fieldPath),
				OldValue:   oldVal,
				NewValue:   nil,
				ChangeType: "delete",
			})
		}
	}

	return diffs
}

// getFieldName 获取字段中文名
func (s *VersionService) getFieldName(fieldPath string) string {
	if name, ok := s.fieldMap[fieldPath]; ok {
		return name
	}
	return fieldPath
}

// equalValues 比较两个值是否相等
func equalValues(a, b interface{}) bool {
	aBytes, _ := json.Marshal(a)
	bBytes, _ := json.Marshal(b)
	return string(aBytes) == string(bBytes)
}

// CreateOfficialVersion 创建正式版本（审批通过时调用）
func (s *VersionService) CreateOfficialVersion(
	ctx context.Context,
	projectID string,
	snapshot *VersionSnapshot,
	committerID int64,
	committerName string,
	commitMessage string,
) error {
	// 1. 获取当前版本号
	currentVersion, err := s.repo.GetCurrentVersion(ctx, projectID)
	if err != nil {
		return fmt.Errorf("get current version failed: %w", err)
	}

	// 2. 序列化快照
	snapshotData, err := json.Marshal(snapshot)
	if err != nil {
		return fmt.Errorf("marshal snapshot failed: %w", err)
	}

	// 3. 创建新版本记录
	newVersion := &ProjectVersion{
		ProjectID:     projectID,
		Version:       currentVersion + 1,
		VersionType:   VersionTypeOfficial,
		SnapshotData:  snapshotData,
		CommitMessage: commitMessage,
		CommitterID:   committerID,
		CommitterName: committerName,
	}

	// 4. 事务中插入版本并更新项目当前版本号
	return s.repo.CreateVersionAndUpdateProject(ctx, newVersion)
}

// GetVersionHistory 获取版本历史
func (s *VersionService) GetVersionHistory(
	ctx context.Context,
	projectID string,
	page, pageSize int,
) ([]*VersionHistory, int64, error) {
	return s.repo.GetVersionHistory(ctx, projectID, page, pageSize)
}

// VersionHistory 版本历史记录
type VersionHistory struct {
	Version       int    `json:"version"`
	VersionType   string `json:"version_type"`
	CommitMessage string `json:"commit_message"`
	CommitterID   int64  `json:"committer_id"`
	CommitterName string `json:"committer_name"`
	WorkflowID    string `json:"workflow_id"`
	CreatedAt     string `json:"created_at"`
	ChangeSummary string `json:"change_summary"`
}

// VersionRepository 版本仓储接口
type VersionRepository interface {
	GetCurrentVersion(ctx context.Context, projectID string) (int, error)
	CreateVersionAndUpdateProject(ctx context.Context, version *ProjectVersion) error
	GetVersionHistory(ctx context.Context, projectID string, page, pageSize int) ([]*VersionHistory, int64, error)
	GetVersionByNumber(ctx context.Context, projectID string, version int) (*ProjectVersion, error)
}

// ProjectVersion 项目版本实体（简化版）
type ProjectVersion struct {
	ProjectID     string
	Version       int
	VersionType   string
	BaseVersion   int
	UserID        int64
	WorkflowID    string
	SnapshotData  []byte
	CommitMessage string
	CommitterID   int64
	CommitterName string
}
