package service

import (
	"context"
	"fmt"
	"strings"

	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/common"
	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/constant"
	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/log"
	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/prometheus"
	"go.uber.org/zap"
)

// func GetClusterInfo(ctx context.Context, clusterID string) (*model.Cluster, error) {
// 	dao := NewCommonDAO()
// 	var out model.Cluster
// 	err := dao.GetEntity(ctx, ComFilter{
// 		ModelFilters: model.Cluster{
// 			ClusterID: clusterID,
// 		},
// 	}, &out)
// 	if err != nil {
// 		log.Info(ctx, "get cluster failed: %v", zap.Error(err))
// 		return nil, err
// 	}
// 	return &out, nil
// }

// removeLeadingComments 去除 SQL 开头的注释（块注释 /* */ 和行注释 --）
// 重复去除直到遇到非注释内容
func removeLeadingComments(sql string) string {
	s := strings.TrimSpace(sql)

	for {
		changed := false

		// 去除开头的块注释 /* ... */
		if strings.HasPrefix(s, "/*") {
			end := strings.Index(s, "*/")
			if end != -1 {
				s = strings.TrimSpace(s[end+2:])
				changed = true
			}
		}

		// 去除开头的行注释 -- ...
		if strings.HasPrefix(s, "--") {
			// 查找换行符或结束位置
			end := strings.Index(s, "\n")
			if end != -1 {
				s = strings.TrimSpace(s[end+1:])
			} else {
				// 整行都是注释
				s = ""
			}
			changed = true
		}

		// 如果没有变化，说明已经去除完所有开头的注释
		if !changed {
			break
		}
	}

	return s
}

func ShouldKeep(query string) bool {
	// 去除开头的注释后再判断
	query = removeLeadingComments(query)
	queryLower := strings.ToLower(query)
	// Query contains "read_from_storage(tiflash"
	if strings.Contains(queryLower, "read_from_storage(tiflash") && !strings.Contains(queryLower, "/*+ read_from_storage(tiflash") {
		return false
	}
	// Query contains "force index"
	if strings.Contains(queryLower, "force index") {
		return false
	}

	// SQL starting with analyze (case-insensitive)
	if strings.HasPrefix(queryLower, "analyze") {
		return false
	}
	// Exclude DDL statements (CREATE, ALTER, DROP, TRUNCATE, etc.)
	ddlKeywords := []string{"create", "alter", "drop", "truncate", "rename"}
	for _, keyword := range ddlKeywords {
		if strings.HasPrefix(queryLower, keyword) {
			return false
		}
	}
	// SQL not starting with select (case-insensitive)
	if !strings.HasPrefix(queryLower, "select") {
		return false
	}
	return true
}

func BuildInClause(values []string) (string, []any) {
	placeholders := make([]string, len(values))
	args := make([]any, len(values))
	for i, v := range values {
		placeholders[i] = "?"
		args[i] = v
	}
	return strings.Join(placeholders, ", "), args
}

func BuildInValuesLiteral(values []string) string {
	if len(values) == 0 {
		return ""
	}
	lits := make([]string, len(values))
	for i, v := range values {
		vv := strings.ReplaceAll(v, "'", "''")
		lits[i] = fmt.Sprintf("'%s'", vv)
	}
	return strings.Join(lits, ", ")
}
func BuildPrometheusClinetReq(ctx context.Context, clusterId string) (prometheus.CreatePrometheusClientReq, error) {

	cluster, _ := common.GetCluster(ctx, clusterId)

	if cluster == nil {
		log.Error(ctx, "cluster not found in db", zap.String("clusterId", clusterId))
		return prometheus.CreatePrometheusClientReq{}, fmt.Errorf("cluster not found in db")
	}

	req := prometheus.CreatePrometheusClientReq{
		Region:    cluster.Region,
		Provider:  cluster.Provider,
		TenantID:  cluster.OrgID,
		ProjectID: cluster.ProjectID,
		ClusterID: cluster.ClusterID,
	}
	req.DeployType = cluster.DeployType
	if req.DeployType == "" {
		req.DeployType = constant.DeployTypeDedicated
	}
	return req, nil
}
