package common

import (
	"context"
	"fmt"
	"time"

	"github.com/tidbcloud/infra-provider/pkg/deploy"
	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/common/utils"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/internet/task"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

type Trigger struct {
	*task.BaseTask
}

func NewTrigger(ctx *task.Context) *Trigger {
	return &Trigger{BaseTask: &task.BaseTask{Context: ctx}}
}

func (t *Trigger) Name() string {
	return "Trigger"
}

func (t *Trigger) Create(ctx context.Context) deploy.Result {
	appRoutes := &v1alpha1.APPRouteList{}
	if err := t.APPRouteRW.List(ctx, appRoutes, client.MatchingLabels{
		v1alpha1.VPCNameKey: t.VPC.Name,
	}); err != nil {
		return deploy.Panic(err).WithRequeuAfter(30 * time.Second)
	}

	if t.Internet.Annotations == nil {
		t.Internet.Annotations = make(map[string]string)
	}
	for _, secondaryCidr := range t.VPC.Spec.SecondaryCidrs {
		secondaryCidrName := v1alpha1.SecondaryCidrNamePrefix + utils.SanitizeCidr(secondaryCidr)
		if _, ok := t.Internet.Annotations[secondaryCidrName]; !ok {
			t.Logger.Info("secondary cidr not found on internet annotations, will retry later", "secondaryCidr", secondaryCidr)
			continue
		}
		if t.Internet.Annotations[secondaryCidrName] == v1alpha1.SecondaryCidrStatusFailed {
			t.Logger.Error(fmt.Errorf("secondary cidr already failed: %s", secondaryCidr), "secondaryCidr", secondaryCidr)
			return deploy.Panic(fmt.Errorf("secondary cidr already failed: %s", secondaryCidr)).WithRequeuAfter(30 * time.Second)
		}

		for _, appRoute := range appRoutes.Items {
			if err := t.APPRouteRW.Get(ctx, client.ObjectKey{
				Namespace: appRoute.Namespace,
				Name:      appRoute.Name,
			}, &appRoute); err != nil {
				return deploy.Panic(err).WithRequeuAfter(30 * time.Second)
			}

			if appRoute.GetAnnotations() == nil {
				appRoute.Annotations = make(map[string]string)
			}
			if appRoute.Annotations[secondaryCidrName] == v1alpha1.SecondaryCidrStatusReady {
				t.Logger.Info("secondary cidr already ready on app route annotations, skip", "secondaryCidr", secondaryCidr)
				continue
			}
			appRoute.Annotations[secondaryCidrName] = v1alpha1.SecondaryCidrStatusPending
			if err := t.APPRouteRW.Update(ctx, &appRoute); err != nil {
				return deploy.Panic(err).WithRequeuAfter(30 * time.Second)
			}
		}
		t.Internet.Annotations[secondaryCidrName] = v1alpha1.SecondaryCidrStatusReady
		if err := t.InternetRW.Update(ctx, t.Internet); err != nil {
			return deploy.Panic(err).WithRequeuAfter(30 * time.Second)
		}
	}

	return deploy.Done()
}
