package metadbcli

import (
	"context"
	"database/sql"
	"fmt"
	"time"

	k8sresourceent "github.com/tidbcloud/devops/entity/k8sresource"
)

type ListK8SResourceReq struct {
	BeginTime time.Time `json:"begin_time"`
	EndTime   time.Time `json:"end_time"`

	ClusterId string `json:"cluster_id"`
	Namespace string `json:"namespace"`
	Region    string `json:"region"`

	Page    int `json:"page"`
	PerPage int `json:"per_page"`
}

type Client interface {
	ListK8SResource(ctx context.Context, req *ListK8SResourceReq) ([]*k8sresourceent.K8SResource, int64, error)
}

type client struct {
	dbClient *sql.DB
}

func NewClient(dsn string) (Client, error) {
	dbClient, err := sql.Open("mysql", dsn)
	if err != nil {
		return nil, fmt.Errorf("failed to connect to database: %w", err)
	}

	return &client{dbClient: dbClient}, nil
}

func (c *client) ListK8SResource(ctx context.Context, req *ListK8SResourceReq) ([]*k8sresourceent.K8SResource, int64, error) {
	query := `
	SELECT id, type, namespace, name, tenant_id, project_id, cluster_id, region, source, timestamp, data, snap_id FROM k8s_resource
	WHERE cluster_id = ? AND namespace = ? AND region = ?
	AND timestamp >= ? AND timestamp <= ?
	LIMIT ? OFFSET ?`

	rows, err := c.dbClient.Query(query, req.ClusterId, req.Namespace, req.Region, req.BeginTime, req.EndTime, req.PerPage, (req.Page-1)*req.PerPage)
	if err != nil {
		return nil, 0, fmt.Errorf("failed to query k8s resources: %w", err)
	}
	defer rows.Close()
	var resources []*k8sresourceent.K8SResource
	for rows.Next() {
		var resource k8sresourceent.K8SResource
		if err := rows.Scan(&resource.ID, &resource.Type, &resource.Namespace, &resource.Name, &resource.TenantId, &resource.ProjectId, &resource.ClusterId, &resource.Region, &resource.Source, &resource.Timestamp, &resource.Data, &resource.SnapId); err != nil {
			return nil, 0, fmt.Errorf("failed to scan k8s resource: %w", err)
		}
		resources = append(resources, &resource)
	}

	if err := rows.Err(); err != nil {
		return nil, 0, fmt.Errorf("error occurred during row iteration: %w", err)
	}
	var total int64
	countQuery := `
	SELECT COUNT(*) FROM k8s_resource
	WHERE cluster_id = ? AND namespace = ? AND region = ?
	AND timestamp >= ? AND timestamp <= ?`
	err = c.dbClient.QueryRowContext(ctx, countQuery, req.ClusterId, req.Namespace, req.Region, req.BeginTime, req.EndTime).Scan(&total)
	if err != nil {
		return nil, 0, fmt.Errorf("failed to count k8s resources: %w", err)
	}
	return resources, total, nil
}
