package billing

import (
	"context"
	"errors"

	"cloud.google.com/go/bigquery"
	"go.uber.org/zap"
	"google.golang.org/api/iterator"
	"google.golang.org/api/option"

	. "github.com/tidbcloud/devtier-store-service/utils"
)

type DevtierTenantNum struct {
	Num int64 `bigquery:"num"`
}

type ServerlessCloudTenants struct {
	TenantId           string `bigquery:"tenant_id"`
	TenantName         string `bigquery:"tenant_name"`
	TenantRegion       string `bigquery:"tenant_region"`
	TenantInternalUser string `bigquery:"tenant_internal_user"`
	TenantCreatedAt    string `bigquery:"tenant_created_at"`
}

func getGcpClient(logger *zap.Logger) (*bigquery.Client, error) {
	if Env != "prod" {
		return nil, errors.New("only support prod env")
	}

	//logger := otelzap.L().Ctx(ctx)
	secret, err := GetAwsSecret(logger, "gcp-digital-bi-readonly-v2matc5", "us-west-2")
	if err != nil {
		logger.Error("GetAwsSecret failed", zap.Error(err))
		return nil, err
	}
	client, err := bigquery.NewClient(context.TODO(), "gcp-digital-bi", option.WithCredentialsJSON([]byte(secret)))
	if err != nil {
		logger.Error("bigquery.NewClient", zap.Error(err))
		return nil, err
	}
	return client, nil
}
func GetServerlessClusterNumFromGCP(logger *zap.Logger, date string) int64 {
	logger.Info("GetServerlessClusterNumFromGCP start...")
	defer logger.Info("GetServerlessClusterNumFromGCP end...")
	cli, err := getGcpClient(logger)
	if err != nil {
		logger.Error("getGcpClient failed", zap.Error(err))
		return -1
	}
	defer cli.Close()

	num := getClusterCounts(logger, cli, date)
	logger.Info("bigquery and results", zap.Any(date, num))
	return num
}

func getClusterCounts(logger *zap.Logger, client *bigquery.Client, date string) int64 {
	//logger := otelzap.L().Ctx(ctx)
	query := client.Query(
		`SELECT
		COUNT(*) as num
	  	FROM (
			SELECT
			tenant_id,
			FROM gcp-digital-bi.metadb.dbaas_clusters
			WHERE
			deploy_type = "shared"
			AND free = 1
			AND created_at < "` + date + ` 23:59:59"
			AND (deleted_time > "` + date + ` 00:00:00"
				OR deleted_time IS NULL)
			GROUP BY
			tenant_id 
		)`)
	rows, err := query.Read(context.TODO())
	if err != nil {
		logger.Error("error iterating through results", zap.Error(err))
		return -1
	}
	var row DevtierTenantNum
	if err = rows.Next(&row); err == iterator.Done {
		return -1
	} else if err != nil {
		logger.Error("error get rows", zap.Error(err))
		return -1
	}
	return row.Num
}

func GetNewTenantsFromGCP(logger *zap.Logger, date string) ([]ServerlessCloudTenants, error) {
	logger.Info("GetNewTenantsFromGCP start...")
	defer logger.Info("GetNewTenantsFromGCP end...")
	gcpCli, err := getGcpClient(logger)
	if err != nil {
		return nil, err
	}
	defer gcpCli.Close()
	return getNewTenants(logger, gcpCli, date)
}

func getNewTenants(logger *zap.Logger, client *bigquery.Client, date string) ([]ServerlessCloudTenants, error) {
	//logger := otelzap.L().Ctx(ctx)
	query := client.Query(
		`SELECT
		tenant_id,
		tenant_name,
		COALESCE(tenant_region, 'null') AS tenant_region,
		CAST(tenant_internal_user AS STRING) AS tenant_internal_user,
		FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', tenant_created_at) as tenant_created_at
		FROM
		gcp-digital-bi.model_tidbcloud.dwm_cloud_tenants
		WHERE
		tenant_created_at >= "` + date + ` 00:00:00"`)
	rows, err := query.Read(context.TODO())
	if err != nil {
		logger.Error("error iterating through", zap.Error(err))
		return nil, err
	}
	var result []ServerlessCloudTenants
	var tenant ServerlessCloudTenants
	for {
		err := rows.Next(&tenant)
		if err == iterator.Done {
			break
		}
		if err != nil {
			logger.Error("error get row", zap.Error(err))
			continue
		}
		result = append(result, tenant)
	}
	logger.Info("getNewTenants from bigquery date, num", zap.Any(date, len(result)))
	return result, nil
}

/*
func getBetweenDates(sdate, edate string) (d []string) {
	timeFormatTpl := "2006-01-02 15:04:05"
	if len(timeFormatTpl) != len(sdate) {
		timeFormatTpl = timeFormatTpl[0:len(sdate)]
	}
	date, err := time.Parse(timeFormatTpl, sdate)
	if err != nil {
		return d
	}
	date2, err := time.Parse(timeFormatTpl, edate)
	if err != nil {
		return d
	}
	if date2.Before(date) {
		return d
	}
	timeFormatTpl = "2006-01-02"
	date2Str := date2.Format(timeFormatTpl)
	d = append(d, date.Format(timeFormatTpl))
	for {
		date = date.AddDate(0, 0, 1)
		dateStr := date.Format(timeFormatTpl)
		d = append(d, dateStr)
		if dateStr == date2Str {
			break
		}
	}
	return d
}

func main() {
	dates := getBetweenDates("2022-07-01", "2022-07-10")
	//dates := getBetweenDates("2022-01-01", "2022-07-10")
	for _, date := range dates {
		GetGcpDevtierClusterNum(date)
	}
}
*/
