package aws

import (
	"context"
	"fmt"

	coremodel "security-center-backend/internal/model"
	"security-center-backend/internal/modules/caasm/collector"
	model "security-center-backend/internal/modules/caasm/model"

	"github.com/aws/aws-sdk-go-v2/service/redshift"
)

func (c *AWSCollector) collectRedshift(ctx context.Context, region string, result *collector.AssetResult) error {
	svc := redshift.NewFromConfig(c.cfg, func(o *redshift.Options) {
		o.Region = region
	})

	paginator := redshift.NewDescribeClustersPaginator(svc, &redshift.DescribeClustersInput{})
	for paginator.HasMorePages() {
		resp, err := paginator.NextPage(ctx)
		if err != nil {
			return fmt.Errorf("failed to describe Redshift clusters: %v", err)
		}
		for _, cluster := range resp.Clusters {
			if cluster.ClusterIdentifier == nil {
				continue
			}

			clusterID := *cluster.ClusterIdentifier

			// Build cluster ARN (format: arn:aws:redshift:region:account:cluster:cluster-name)
			clusterArn := fmt.Sprintf("arn:aws:redshift:%s::cluster:%s", region, clusterID)
			if cluster.ClusterNamespaceArn != nil {
				clusterArn = *cluster.ClusterNamespaceArn
			}

			// Extract endpoint
			endpoint := ""
			port := uint32(5439) // Default Redshift port

			if cluster.Endpoint != nil {
				if cluster.Endpoint.Address != nil {
					endpoint = *cluster.Endpoint.Address
				}
				if cluster.Endpoint.Port != nil {
					port = uint32(*cluster.Endpoint.Port)
				}
			}

			// Extract security groups
			securityGroupIds := make([]string, 0)
			if cluster.VpcSecurityGroups != nil {
				for _, sg := range cluster.VpcSecurityGroups {
					if sg.VpcSecurityGroupId != nil {
						securityGroupIds = append(securityGroupIds, *sg.VpcSecurityGroupId)
					}
				}
			}

			// Check if publicly accessible (CRITICAL security check)
			publiclyAccessible := false
			if cluster.PubliclyAccessible != nil {
				publiclyAccessible = *cluster.PubliclyAccessible
			}

			// Extract cluster details
			nodeType := ""
			if cluster.NodeType != nil {
				nodeType = *cluster.NodeType
			}

			numberOfNodes := int32(0)
			if cluster.NumberOfNodes != nil {
				numberOfNodes = *cluster.NumberOfNodes
			}

			encrypted := false
			if cluster.Encrypted != nil {
				encrypted = *cluster.Encrypted
			}

			clusterStatus := ""
			if cluster.ClusterStatus != nil {
				clusterStatus = *cluster.ClusterStatus
			}

			// Create Redshift cluster asset
			asset := c.newBaseAsset(clusterArn, clusterID, string(model.AssetTypeDatabase), clusterStatus, region)
			c.setService(&asset, "redshift")

			meta := map[string]interface{}{
				"cluster_identifier":                  clusterID,
				"cluster_arn":                         clusterArn,
				"node_type":                           nodeType,
				"number_of_nodes":                     numberOfNodes,
				"endpoint":                            endpoint,
				"port":                                port,
				"publicly_accessible":                 publiclyAccessible, // ⚠️ CRITICAL
				"encrypted":                           encrypted,
				"security_groups":                     securityGroupIds,
				"vpc_id":                              cluster.VpcId,
				"availability_zone":                   cluster.AvailabilityZone,
				"preferred_maintenance_window":        cluster.PreferredMaintenanceWindow,
				"cluster_version":                     cluster.ClusterVersion,
				"allow_version_upgrade":               cluster.AllowVersionUpgrade,
				"automated_snapshot_retention_period": cluster.AutomatedSnapshotRetentionPeriod,
			}

			if cluster.ClusterCreateTime != nil {
				meta["created_at"] = cluster.ClusterCreateTime
			}

			if cluster.DBName != nil {
				meta["database_name"] = *cluster.DBName
			}

			if cluster.MasterUsername != nil {
				meta["master_username"] = *cluster.MasterUsername
			}

			asset.Metadata = coremodel.JSONB(meta)
			result.Assets = append(result.Assets, asset)

			// Add endpoint as domain asset
			if endpoint != "" {
				domainAsset := model.DomainAsset{
					Asset:       model.Asset{NativeID: asset.NativeID},
					DomainName:  endpoint,
					DomainClass: model.DomainClassServiceHostname,
					Registrar:   "redshift",
				}
				setServiceEndpointDomainDefaults(&domainAsset, "redshift", publiclyAccessible)
				c.setService(&domainAsset.Asset, "redshift")
				result.DomainAssets = append(result.DomainAssets, domainAsset)

				result.Ports = append(result.Ports, model.IPPortIndex{
					Asset:             model.Asset{NativeID: asset.NativeID},
					IPAddress:         endpoint,
					Port:              port,
					Protocol:          "tcp",
					ObservationSource: model.PortObservationSourceServiceEndpoint,
					ServiceName:       "redshift",
					Exposure:          endpointExposure(publiclyAccessible),
					Status:            "open",
				})
			}
		}
	}

	return nil
}
