package service

import (
	"context"
	"fmt"

	"oci-portal/internal/oci"
)

// Shapes 列出租户在目标区域可用的实例规格。
func (s *OciConfigService) Shapes(ctx context.Context, id uint, region, availabilityDomain string) ([]oci.ComputeShape, error) {
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return nil, err
	}
	return s.client.ListShapes(ctx, cred, region, availabilityDomain)
}

// Images 列出可用的实例镜像。
func (s *OciConfigService) Images(ctx context.Context, id uint, q oci.ImagesQuery) ([]oci.Image, error) {
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return nil, err
	}
	return s.client.ListImages(ctx, cred, q)
}

// Image 查询单个镜像。
func (s *OciConfigService) Image(ctx context.Context, id uint, region, imageID string) (oci.Image, error) {
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return oci.Image{}, err
	}
	return s.client.GetImage(ctx, cred, region, imageID)
}

// VCNs 列出 VCN；compartmentID 为空表示租户根。
func (s *OciConfigService) VCNs(ctx context.Context, id uint, region, compartmentID string) ([]oci.VCN, error) {
	cred, err := s.credentialsInCompartment(ctx, id, compartmentID)
	if err != nil {
		return nil, err
	}
	return s.client.ListVCNs(ctx, cred, region)
}

// CreateVCN 创建 VCN；in.CompartmentID 为空时建在租户根。
func (s *OciConfigService) CreateVCN(ctx context.Context, id uint, in oci.CreateVCNInput) (oci.VCN, error) {
	if in.DisplayName == "" || in.CidrBlock == "" {
		return oci.VCN{}, fmt.Errorf("create vcn: displayName and cidrBlock are required")
	}
	cred, err := s.credentialsInCompartment(ctx, id, in.CompartmentID)
	if err != nil {
		return oci.VCN{}, err
	}
	return s.client.CreateVCN(ctx, cred, in)
}

// VCN 查询单个 VCN。
func (s *OciConfigService) VCN(ctx context.Context, id uint, region, vcnID string) (oci.VCN, error) {
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return oci.VCN{}, err
	}
	return s.client.GetVCN(ctx, cred, region, vcnID)
}

// UpdateVCN 重命名 VCN。
func (s *OciConfigService) UpdateVCN(ctx context.Context, id uint, region, vcnID, displayName string) (oci.VCN, error) {
	if displayName == "" {
		return oci.VCN{}, fmt.Errorf("update vcn: displayName is required")
	}
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return oci.VCN{}, err
	}
	return s.client.UpdateVCN(ctx, cred, region, vcnID, displayName)
}

// DeleteVCN 删除 VCN。
func (s *OciConfigService) DeleteVCN(ctx context.Context, id uint, region, vcnID string) error {
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return err
	}
	return s.client.DeleteVCN(ctx, cred, region, vcnID)
}

// EnableVCNIPv6 为 VCN 一键启用 IPv6，返回逐步执行报告。
func (s *OciConfigService) EnableVCNIPv6(ctx context.Context, id uint, region, vcnID string) ([]oci.IPv6Step, error) {
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return nil, err
	}
	return s.client.EnableVCNIPv6(ctx, cred, region, vcnID)
}

// Subnets 列出子网；vcnID 非空时按其所在 compartment 查询，
// 否则 compartmentID 为空表示租户根。
func (s *OciConfigService) Subnets(ctx context.Context, id uint, region, vcnID, compartmentID string) ([]oci.Subnet, error) {
	cred, err := s.credentialsInCompartment(ctx, id, compartmentID)
	if err != nil {
		return nil, err
	}
	return s.client.ListSubnets(ctx, cred, region, vcnID)
}

// CreateSubnet 创建子网。
func (s *OciConfigService) CreateSubnet(ctx context.Context, id uint, in oci.CreateSubnetInput) (oci.Subnet, error) {
	if in.VcnID == "" || in.DisplayName == "" || in.CidrBlock == "" {
		return oci.Subnet{}, fmt.Errorf("create subnet: vcnId, displayName and cidrBlock are required")
	}
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return oci.Subnet{}, err
	}
	return s.client.CreateSubnet(ctx, cred, in)
}

// Subnet 查询单个子网。
func (s *OciConfigService) Subnet(ctx context.Context, id uint, region, subnetID string) (oci.Subnet, error) {
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return oci.Subnet{}, err
	}
	return s.client.GetSubnet(ctx, cred, region, subnetID)
}

// UpdateSubnet 重命名子网。
func (s *OciConfigService) UpdateSubnet(ctx context.Context, id uint, region, subnetID, displayName string) (oci.Subnet, error) {
	if displayName == "" {
		return oci.Subnet{}, fmt.Errorf("update subnet: displayName is required")
	}
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return oci.Subnet{}, err
	}
	return s.client.UpdateSubnet(ctx, cred, region, subnetID, displayName)
}

// DeleteSubnet 删除子网。
func (s *OciConfigService) DeleteSubnet(ctx context.Context, id uint, region, subnetID string) error {
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return err
	}
	return s.client.DeleteSubnet(ctx, cred, region, subnetID)
}

// SecurityLists 列出安全列表；vcnID 非空时按其所在 compartment 查询，
// 否则 compartmentID 为空表示租户根。
func (s *OciConfigService) SecurityLists(ctx context.Context, id uint, region, vcnID, compartmentID string) ([]oci.SecurityList, error) {
	cred, err := s.credentialsInCompartment(ctx, id, compartmentID)
	if err != nil {
		return nil, err
	}
	return s.client.ListSecurityLists(ctx, cred, region, vcnID)
}

// CreateSecurityList 创建安全列表。
func (s *OciConfigService) CreateSecurityList(ctx context.Context, id uint, in oci.CreateSecurityListInput) (oci.SecurityList, error) {
	if in.VcnID == "" || in.DisplayName == "" {
		return oci.SecurityList{}, fmt.Errorf("create security list: vcnId and displayName are required")
	}
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return oci.SecurityList{}, err
	}
	return s.client.CreateSecurityList(ctx, cred, in)
}

// SecurityList 查询单个安全列表。
func (s *OciConfigService) SecurityList(ctx context.Context, id uint, region, securityListID string) (oci.SecurityList, error) {
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return oci.SecurityList{}, err
	}
	return s.client.GetSecurityList(ctx, cred, region, securityListID)
}

// UpdateSecurityList 更新安全列表；规则字段一经提供即整体替换。
func (s *OciConfigService) UpdateSecurityList(ctx context.Context, id uint, securityListID string, in oci.UpdateSecurityListInput) (oci.SecurityList, error) {
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return oci.SecurityList{}, err
	}
	return s.client.UpdateSecurityList(ctx, cred, securityListID, in)
}

// DeleteSecurityList 删除安全列表。
func (s *OciConfigService) DeleteSecurityList(ctx context.Context, id uint, region, securityListID string) error {
	cred, err := s.credentialsByID(ctx, id)
	if err != nil {
		return err
	}
	return s.client.DeleteSecurityList(ctx, cred, region, securityListID)
}
