package client

import (
	"context"
	"fmt"
	"time"

	v1 "github.com/tidbcloud/observability/api/regionalserver/resourceworker/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

// mysqlStatusWriter implements the SubResourceWriter interface for status updates
type mysqlStatusWriter struct {
	client *mysqlClient
}

func (s *mysqlStatusWriter) Create(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error {
	return s.Update(ctx, obj)
}

func (s *mysqlStatusWriter) Update(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) (err error) {
	start := time.Now()
	defer func() {
		recordOperationDuration("status_update", start, err)
	}()
	clusterID := obj.GetName()
	cluster, ok := obj.(*v1.Cluster)
	if !ok {
		return ErrTypeInvalid
	}
	log := s.client.log.WithName("[Status_Update]").WithValues("clusterID", clusterID)

	// Update the ClusterStatus record
	err = s.client.db.WithContext(ctx).Model(&ClusterStatus{}).
		Where("cluster_id = ?", clusterID).
		Updates(map[string]interface{}{
			"phase":        cluster.Status.Phase,
			"dns_name":     cluster.Status.DnsName,
			"service_name": cluster.Status.ServiceName,
			"update_at":    cluster.Status.UpdateAt,
		}).Error
	if err != nil {
		return fmt.Errorf("failed to update cluster status: %w", err)
	}
	log.Info("updated successfully", "phase", cluster.Status.Phase)

	return nil
}

// Patch in not implmeneted yet.
func (s *mysqlStatusWriter) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
	panic("not implemented")
}

// Apply is not supported by the MySQL-backed status writer because it does not
// implement server-side apply semantics.
func (s *mysqlStatusWriter) Apply(ctx context.Context, obj runtime.ApplyConfiguration, opts ...client.SubResourceApplyOption) error {
	return fmt.Errorf("apply is not implemented for mysql client status writer")
}

// mysqlSubResourceClient implements the SubResourceClient interface
type mysqlSubResourceClient struct {
	writer client.SubResourceWriter
}

func (s *mysqlSubResourceClient) Get(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceGetOption) error {
	// For status sub-resource, we would get the current status
	// This is a simplified implementation
	return fmt.Errorf("Get method not implemented for sub-resource")
}

func (s *mysqlSubResourceClient) Create(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error {
	return s.writer.Create(ctx, obj, subResource, opts...)
}

func (s *mysqlSubResourceClient) Update(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error {
	return s.writer.Update(ctx, obj, opts...)
}

func (s *mysqlSubResourceClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
	return s.writer.Patch(ctx, obj, patch, opts...)
}

func (s *mysqlSubResourceClient) Apply(ctx context.Context, obj runtime.ApplyConfiguration, opts ...client.SubResourceApplyOption) error {
	return s.writer.Apply(ctx, obj, opts...)
}
