package api

import (
	"net/http"

	"github.com/gin-gonic/gin"

	"oci-portal/internal/oci"
)

// ---- Federation：SAML IdP 与 sign-on 免 MFA ----

// createIdpRequest 的映射 / JIT 字段全部可缺省：布尔用指针区分「未传」，
// 缺省即控制台默认（JIT 开启建用户不更新、分配 Administrators 组、
// 名称 ID 格式无、NameID 映射用户名）。
type createIdpRequest struct {
	Name        string `json:"name" binding:"required"`
	Metadata    string `json:"metadata" binding:"required"`
	Description string `json:"description"`
	IconURL     string `json:"iconUrl"`

	NameIDFormat       string `json:"nameIdFormat"`
	AssertionAttribute string `json:"assertionAttribute"`
	UserStoreAttribute string `json:"userStoreAttribute"`

	JitEnabled          *bool `json:"jitEnabled"`
	JitCreate           *bool `json:"jitCreate"`
	JitUpdate           *bool `json:"jitUpdate"`
	JitAssignAdminGroup *bool `json:"jitAssignAdminGroup"`
	JitMapEmail         bool  `json:"jitMapEmail"`
}

func boolOr(v *bool, def bool) bool {
	if v == nil {
		return def
	}
	return *v
}

// @Summary  身份提供商列表
// @Tags     租户 IAM
// @Param    id path int true "配置 ID"
// @Param    domainId query string false "身份域 OCID(缺省 Default 域)"
// @Success  200 {array} oci.IdentityProviderInfo
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/identity-providers [get]
func (h *ociConfigHandler) listIdentityProviders(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	idps, err := h.svc.IdentityProviders(c.Request.Context(), id, c.Query("domainId"))
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, idps)
}

// @Summary  创建身份提供商(SAML)
// @Tags     租户 IAM
// @Param    id path int true "配置 ID"
// @Param    domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param    body body createIdpRequest true "请求体"
// @Success  201 {object} oci.IdentityProviderInfo
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/identity-providers [post]
func (h *ociConfigHandler) createIdentityProvider(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	var req createIdpRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	idp, err := h.svc.CreateIdentityProvider(c.Request.Context(), id, c.Query("domainId"), oci.CreateIdpInput{
		Name:                req.Name,
		Metadata:            req.Metadata,
		Description:         req.Description,
		IconURL:             req.IconURL,
		NameIDFormat:        req.NameIDFormat,
		AssertionAttribute:  req.AssertionAttribute,
		UserStoreAttribute:  req.UserStoreAttribute,
		JitEnabled:          boolOr(req.JitEnabled, true),
		JitCreate:           boolOr(req.JitCreate, true),
		JitUpdate:           boolOr(req.JitUpdate, false),
		JitAssignAdminGroup: boolOr(req.JitAssignAdminGroup, true),
		JitMapEmail:         req.JitMapEmail,
	})
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusCreated, idp)
}

// @Summary  激活身份提供商
// @Tags     租户 IAM
// @Param    id path int true "配置 ID"
// @Param    domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param    idpId path string true "idpId"
// @Param    body body object true "请求体(见接口说明)"
// @Success  200 {object} oci.IdentityProviderInfo
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/identity-providers/{idpId}/activate [post]
func (h *ociConfigHandler) activateIdentityProvider(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	var req struct {
		Enabled *bool `json:"enabled" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	idp, err := h.svc.SetIdentityProviderEnabled(c.Request.Context(), id, c.Query("domainId"), c.Param("idpId"), *req.Enabled)
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, idp)
}

// @Summary  删除身份提供商
// @Tags     租户 IAM
// @Param    id path int true "配置 ID"
// @Param    domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param    idpId path string true "idpId"
// @Success  204 "无内容"
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/identity-providers/{idpId} [delete]
func (h *ociConfigHandler) deleteIdentityProvider(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	if err := h.svc.DeleteIdentityProvider(c.Request.Context(), id, c.Query("domainId"), c.Param("idpId")); err != nil {
		respondError(c, err)
		return
	}
	c.Status(http.StatusNoContent)
}

// @Summary  下载 SAML 元数据
// @Tags     租户 IAM
// @Param    id path int true "配置 ID"
// @Param    domainId query string false "身份域 OCID(缺省 Default 域)"
// @Success  200 {file} file "SAML 元数据 XML(附件下载)"
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/saml-metadata [get]
func (h *ociConfigHandler) downloadSamlMetadata(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	metadata, err := h.svc.DomainSamlMetadata(c.Request.Context(), id, c.Query("domainId"))
	if err != nil {
		respondError(c, err)
		return
	}
	c.Header("Content-Disposition", `attachment; filename="oci-domain-saml-metadata.xml"`)
	c.Data(http.StatusOK, "application/xml", metadata)
}

// @Summary  单点登录规则列表
// @Tags     租户 IAM
// @Param    id path int true "配置 ID"
// @Param    domainId query string false "身份域 OCID(缺省 Default 域)"
// @Success  200 {array} oci.SignOnRuleInfo
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/sign-on-rules [get]
func (h *ociConfigHandler) listSignOnRules(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	rules, err := h.svc.ConsoleSignOnRules(c.Request.Context(), id, c.Query("domainId"))
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusOK, rules)
}

// @Summary  创建 MFA 豁免规则
// @Tags     租户 IAM
// @Param    id path int true "配置 ID"
// @Param    domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param    body body object true "请求体(见接口说明)"
// @Success  201 {object} oci.SignOnRuleInfo
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/sign-on-exemptions [post]
func (h *ociConfigHandler) createMfaExemption(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	var req struct {
		IdentityProviderID string `json:"identityProviderId" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	rule, err := h.svc.CreateMfaExemption(c.Request.Context(), id, c.Query("domainId"), req.IdentityProviderID)
	if err != nil {
		respondError(c, err)
		return
	}
	c.JSON(http.StatusCreated, rule)
}

// @Summary  删除 MFA 豁免规则
// @Tags     租户 IAM
// @Param    id path int true "配置 ID"
// @Param    domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param    ruleId path string true "ruleId"
// @Success  204 "无内容"
// @Security BearerAuth
// @Router   /api/v1/oci-configs/{id}/sign-on-exemptions/{ruleId} [delete]
func (h *ociConfigHandler) deleteMfaExemption(c *gin.Context) {
	id, ok := pathID(c)
	if !ok {
		return
	}
	if err := h.svc.DeleteMfaExemption(c.Request.Context(), id, c.Query("domainId"), c.Param("ruleId")); err != nil {
		respondError(c, err)
		return
	}
	c.Status(http.StatusNoContent)
}
