package api

import (
	"net/http"

	"github.com/gin-gonic/gin"

	"oci-portal/internal/oci"
)

// @Summary  实例形状列表
// @Tags     租户配置
// @Param    id path int true "配置 ID"
// @Success  200 {array} oci.ComputeShape
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/shapes [get]
func (h *ociConfigHandler) shapes(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	shapes, err := h.svc.Shapes(c.Request.Context(), id, c.Query("region"), c.Query("availabilityDomain"))
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, shapes)
}

// @Summary  镜像列表
// @Tags     租户配置
// @Param    id path int true "配置 ID"
// @Success  200 {array} oci.Image
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/images [get]
func (h *ociConfigHandler) images(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	images, err := h.svc.Images(c.Request.Context(), id, oci.ImagesQuery{
		Region:          c.Query("region"),
		OperatingSystem: c.Query("operatingSystem"),
		Shape:           c.Query("shape"),
	})
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, images)
}

// @Summary  镜像详情
// @Tags     租户配置
// @Param    id path int true "配置 ID"
// @Param    imageId path string true "imageId"
// @Success  200 {object} oci.Image
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/images/{imageId} [get]
func (h *ociConfigHandler) getImage(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	image, err := h.svc.Image(c.Request.Context(), id, c.Query("region"), c.Param("imageId"))
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, image)
}

// ---- VCN ----

type createVCNRequest struct {
	Region        string `json:"region"`
	CompartmentID string `json:"compartmentId"` // 为空时建在租户根
	DisplayName   string `json:"displayName" binding:"required"`
	CidrBlock     string `json:"cidrBlock" binding:"required"`
	DnsLabel      string `json:"dnsLabel"`
	EnableIPv6    *bool  `json:"enableIpv6"` // 缺省默认启用
}

type renameRequest struct {
	Region      string `json:"region"`
	DisplayName string `json:"displayName" binding:"required"`
}

// @Summary  VCN 列表
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Success  200 {array} oci.VCN
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/vcns [get]
func (h *ociConfigHandler) listVCNs(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	vcns, err := h.svc.VCNs(c.Request.Context(), id, c.Query("region"), c.Query("compartmentId"))
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, vcns)
}

// @Summary  创建 VCN
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Param    body body createVCNRequest true "请求体"
// @Success  201 {object} oci.VCN
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/vcns [post]
func (h *ociConfigHandler) createVCN(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	var req createVCNRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	vcn, err := h.svc.CreateVCN(c.Request.Context(), id, oci.CreateVCNInput{
		Region:        req.Region,
		CompartmentID: req.CompartmentID,
		DisplayName:   req.DisplayName,
		CidrBlock:     req.CidrBlock,
		DnsLabel:      req.DnsLabel,
		EnableIPv6:    req.EnableIPv6 == nil || *req.EnableIPv6,
	})
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusCreated, vcn)
}

// @Summary  VCN 详情
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Param    vcnId path string true "vcnId"
// @Success  200 {object} oci.VCN
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/vcns/{vcnId} [get]
func (h *ociConfigHandler) getVCN(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	vcn, err := h.svc.VCN(c.Request.Context(), id, c.Query("region"), c.Param("vcnId"))
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, vcn)
}

// @Summary  更新 VCN
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Param    vcnId path string true "vcnId"
// @Param    body body renameRequest true "请求体"
// @Success  200 {object} oci.VCN
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/vcns/{vcnId} [put]
func (h *ociConfigHandler) updateVCN(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	var req renameRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	vcn, err := h.svc.UpdateVCN(c.Request.Context(), id, req.Region, c.Param("vcnId"), req.DisplayName)
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, vcn)
}

// @Summary  删除 VCN
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Param    vcnId path string true "vcnId"
// @Success  204 "无内容"
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/vcns/{vcnId} [delete]
func (h *ociConfigHandler) deleteVCN(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	if err := h.svc.DeleteVCN(c.Request.Context(), id, c.Query("region"), c.Param("vcnId")); err != nil {
		respondError(c, err)
		return
	}
	c.Status(http.StatusNoContent)
}

type enableIPv6Request struct {
	Region string `json:"region"`
}

// @Summary  VCN 启用 IPv6
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Param    vcnId path string true "vcnId"
// @Param    body body enableIPv6Request true "请求体"
// @Success  200 {object} ipv6StepsResponse
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/vcns/{vcnId}/enable-ipv6 [post]
func (h *ociConfigHandler) enableVCNIPv6(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	var req enableIPv6Request
	if err := c.ShouldBindJSON(&req); err != nil && c.Request.ContentLength > 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	steps, err := h.svc.EnableVCNIPv6(c.Request.Context(), id, req.Region, c.Param("vcnId"))
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, gin.H{"steps": steps})
}

// ---- Subnet ----

type createSubnetRequest struct {
	Region           string `json:"region"`
	VcnID            string `json:"vcnId" binding:"required"`
	DisplayName      string `json:"displayName" binding:"required"`
	CidrBlock        string `json:"cidrBlock" binding:"required"`
	DnsLabel         string `json:"dnsLabel"`
	Ipv6CidrBlock    string `json:"ipv6CidrBlock"`
	ProhibitPublicIP bool   `json:"prohibitPublicIp"`
}

// @Summary  子网列表
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Success  200 {array} oci.Subnet
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/subnets [get]
func (h *ociConfigHandler) listSubnets(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	subnets, err := h.svc.Subnets(c.Request.Context(), id, c.Query("region"), c.Query("vcnId"), c.Query("compartmentId"))
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, subnets)
}

// @Summary  创建子网
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Param    body body createSubnetRequest true "请求体"
// @Success  201 {object} oci.Subnet
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/subnets [post]
func (h *ociConfigHandler) createSubnet(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	var req createSubnetRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	subnet, err := h.svc.CreateSubnet(c.Request.Context(), id, oci.CreateSubnetInput{
		Region:           req.Region,
		VcnID:            req.VcnID,
		DisplayName:      req.DisplayName,
		CidrBlock:        req.CidrBlock,
		DnsLabel:         req.DnsLabel,
		Ipv6CidrBlock:    req.Ipv6CidrBlock,
		ProhibitPublicIP: req.ProhibitPublicIP,
	})
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusCreated, subnet)
}

// @Summary  子网详情
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Param    subnetId path string true "subnetId"
// @Success  200 {object} oci.Subnet
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/subnets/{subnetId} [get]
func (h *ociConfigHandler) getSubnet(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	subnet, err := h.svc.Subnet(c.Request.Context(), id, c.Query("region"), c.Param("subnetId"))
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, subnet)
}

// @Summary  更新子网
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Param    subnetId path string true "subnetId"
// @Param    body body renameRequest true "请求体"
// @Success  200 {object} oci.Subnet
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/subnets/{subnetId} [put]
func (h *ociConfigHandler) updateSubnet(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	var req renameRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	subnet, err := h.svc.UpdateSubnet(c.Request.Context(), id, req.Region, c.Param("subnetId"), req.DisplayName)
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, subnet)
}

// @Summary  删除子网
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Param    subnetId path string true "subnetId"
// @Success  204 "无内容"
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/subnets/{subnetId} [delete]
func (h *ociConfigHandler) deleteSubnet(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	if err := h.svc.DeleteSubnet(c.Request.Context(), id, c.Query("region"), c.Param("subnetId")); err != nil {
		respondError(c, err)
		return
	}
	c.Status(http.StatusNoContent)
}

// ---- Security List ----

type createSecurityListRequest struct {
	Region       string             `json:"region"`
	VcnID        string             `json:"vcnId" binding:"required"`
	DisplayName  string             `json:"displayName" binding:"required"`
	IngressRules []oci.SecurityRule `json:"ingressRules"`
	EgressRules  []oci.SecurityRule `json:"egressRules"`
}

type updateSecurityListRequest struct {
	Region       string              `json:"region"`
	DisplayName  string              `json:"displayName"`
	IngressRules *[]oci.SecurityRule `json:"ingressRules"`
	EgressRules  *[]oci.SecurityRule `json:"egressRules"`
}

// @Summary  安全列表清单
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Success  200 {array} oci.SecurityList
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/security-lists [get]
func (h *ociConfigHandler) listSecurityLists(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	lists, err := h.svc.SecurityLists(c.Request.Context(), id, c.Query("region"), c.Query("vcnId"), c.Query("compartmentId"))
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, lists)
}

// @Summary  创建安全列表
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Param    body body createSecurityListRequest true "请求体"
// @Success  201 {object} oci.SecurityList
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/security-lists [post]
func (h *ociConfigHandler) createSecurityList(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	var req createSecurityListRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	list, err := h.svc.CreateSecurityList(c.Request.Context(), id, oci.CreateSecurityListInput{
		Region:       req.Region,
		VcnID:        req.VcnID,
		DisplayName:  req.DisplayName,
		IngressRules: req.IngressRules,
		EgressRules:  req.EgressRules,
	})
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusCreated, list)
}

// @Summary  安全列表详情
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Param    securityListId path string true "securityListId"
// @Success  200 {object} oci.SecurityList
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/security-lists/{securityListId} [get]
func (h *ociConfigHandler) getSecurityList(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	list, err := h.svc.SecurityList(c.Request.Context(), id, c.Query("region"), c.Param("securityListId"))
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, list)
}

// @Summary  更新安全列表
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Param    securityListId path string true "securityListId"
// @Param    body body updateSecurityListRequest true "请求体"
// @Success  200 {object} oci.SecurityList
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/security-lists/{securityListId} [put]
func (h *ociConfigHandler) updateSecurityList(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	var req updateSecurityListRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	list, err := h.svc.UpdateSecurityList(c.Request.Context(), id, c.Param("securityListId"), oci.UpdateSecurityListInput{
		Region:       req.Region,
		DisplayName:  req.DisplayName,
		IngressRules: req.IngressRules,
		EgressRules:  req.EgressRules,
	})
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, list)
}

// @Summary  删除安全列表
// @Tags     网络
// @Param    id path int true "配置 ID"
// @Param    securityListId path string true "securityListId"
// @Success  204 "无内容"
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/security-lists/{securityListId} [delete]
func (h *ociConfigHandler) deleteSecurityList(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	if err := h.svc.DeleteSecurityList(c.Request.Context(), id, c.Query("region"), c.Param("securityListId")); err != nil {
		respondError(c, err)
		return
	}
	c.Status(http.StatusNoContent)
}
