package model

import (
	"errors"
	"fmt"
	"strings"
	"sync"
	"time"

	"gorm.io/gorm"
)

// SupplierCapability 供应商技术能力档案表（与 supplier_applications 一对一）。
type SupplierCapability struct {
	ID                        int    `json:"id" gorm:"primaryKey;comment:主键ID"`
	SupplierApplicationID     int    `json:"supplier_application_id" gorm:"uniqueIndex;not null;comment:供应商申请ID"`
	CoreServiceTypes          string `json:"core_service_types" gorm:"type:text;comment:核心服务类型(JSON数组)"`
	SupportedModels           string `json:"supported_models" gorm:"type:text;comment:支持的模型(JSON数组)"`
	SupportedModelNotes       string `json:"supported_model_notes" gorm:"type:text;comment:支持模型补充说明"`
	SupportedAPIEndpoints     string `json:"supported_api_endpoints" gorm:"type:text;comment:支持的API接口(JSON数组)"`
	SupportedAPIEndpointExtra string `json:"supported_api_endpoint_extra" gorm:"type:text;comment:API接口补充说明"`
	SupportedParams           string `json:"supported_params" gorm:"type:text;comment:支持参数配置(JSON数组)"`
	SupportedParamsExtra      string `json:"supported_params_extra" gorm:"type:text;comment:参数配置补充说明"`
	StreamingSupported        bool   `json:"streaming_supported" gorm:"type:boolean;default:false;comment:是否支持流式响应"`
	StreamingNotes            string `json:"streaming_notes" gorm:"type:text;comment:流式响应说明"`
	StructuredOutputSupported bool   `json:"structured_output_supported" gorm:"type:boolean;default:false;comment:是否支持结构化输出"`
	StructuredOutputNotes     string `json:"structured_output_notes" gorm:"type:text;comment:结构化输出说明"`
	MultimodalTypes           string `json:"multimodal_types" gorm:"type:text;comment:多模态支持类型(JSON数组)"`
	MultimodalExtra           string `json:"multimodal_extra" gorm:"type:text;comment:多模态补充说明"`
	PricingModes              string `json:"pricing_modes" gorm:"type:text;comment:定价模式(JSON数组)"`
	ReferenceInputPrice       string `json:"reference_input_price" gorm:"type:varchar(64);comment:参考输入单价(USD/1K Token)"`
	ReferenceOutputPrice      string `json:"reference_output_price" gorm:"type:varchar(64);comment:参考输出单价(USD/1K Token)"`
	FailureBillingMode        string `json:"failure_billing_mode" gorm:"type:varchar(32);comment:故障计费规则(bill/no_bill)"`
	FailureBillingNotes       string `json:"failure_billing_notes" gorm:"type:text;comment:故障计费说明"`
	APIBaseURLs               string `json:"api_base_urls" gorm:"type:text;comment:API接口地址(JSON数组)"`
	OpenAICompatible          bool   `json:"openai_compatible" gorm:"column:open_ai_compatible;type:boolean;default:false;comment:是否兼容OpenAI规范"`
	TruthCommitmentConfirmed  bool   `json:"truth_commitment_confirmed" gorm:"type:boolean;default:false;comment:信息真实性承诺"`
	CreatedAt                 int64  `json:"created_at" gorm:"type:bigint;index;comment:创建时间戳"`
	UpdatedAt                 int64  `json:"updated_at" gorm:"type:bigint;comment:更新时间戳"`
}

var (
	ensureSupplierCapabilitySchemaOnce sync.Once
	ensureSupplierCapabilitySchemaErr  error
)

// EnsureSupplierCapabilitySchemaColumns 确保供应商能力表关键布尔字段已存在（兼容旧库漏迁移场景）。
func EnsureSupplierCapabilitySchemaColumns() error {
	ensureSupplierCapabilitySchemaOnce.Do(func() {
		// 兼容旧版本数据库缺列导致 upsert 报 "Unknown column"。
		if !DB.Migrator().HasColumn(&SupplierCapability{}, "OpenAICompatible") {
			if err := DB.Migrator().AddColumn(&SupplierCapability{}, "OpenAICompatible"); err != nil {
				ensureSupplierCapabilitySchemaErr = fmt.Errorf("add column openai_compatible failed: %w", err)
				return
			}
		}
		if !DB.Migrator().HasColumn(&SupplierCapability{}, "TruthCommitmentConfirmed") {
			if err := DB.Migrator().AddColumn(&SupplierCapability{}, "TruthCommitmentConfirmed"); err != nil {
				ensureSupplierCapabilitySchemaErr = fmt.Errorf("add column truth_commitment_confirmed failed: %w", err)
				return
			}
		}
	})
	return ensureSupplierCapabilitySchemaErr
}

// GetSupplierCapabilityByApplicationID 根据申请ID查询供应商技术能力档案。
func GetSupplierCapabilityByApplicationID(applicationID int) (*SupplierCapability, error) {
	var item SupplierCapability
	if err := DB.Where("supplier_application_id = ?", applicationID).First(&item).Error; err != nil {
		return nil, err
	}
	return &item, nil
}

// UpsertSupplierCapabilityByApplicationID 按申请ID新增或更新供应商技术能力档案。
func UpsertSupplierCapabilityByApplicationID(applicationID int, capability *SupplierCapability) (*SupplierCapability, error) {
	if err := EnsureSupplierCapabilitySchemaColumns(); err != nil {
		return nil, err
	}
	tx := DB.Begin()
	if tx.Error != nil {
		return nil, tx.Error
	}
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	now := time.Now().Unix()
	var existing SupplierCapability
	if err := tx.Where("supplier_application_id = ?", applicationID).First(&existing).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			capability.SupplierApplicationID = applicationID
			capability.CreatedAt = now
			capability.UpdatedAt = now
			if err = tx.Create(capability).Error; err != nil {
				tx.Rollback()
				return nil, err
			}
			if err = tx.Commit().Error; err != nil {
				return nil, err
			}
			return capability, nil
		}
		tx.Rollback()
		return nil, err
	}
	updates := map[string]any{
		"core_service_types":           capability.CoreServiceTypes,
		"supported_models":             capability.SupportedModels,
		"supported_model_notes":        capability.SupportedModelNotes,
		"supported_api_endpoints":      capability.SupportedAPIEndpoints,
		"supported_api_endpoint_extra": capability.SupportedAPIEndpointExtra,
		"supported_params":             capability.SupportedParams,
		"supported_params_extra":       capability.SupportedParamsExtra,
		"streaming_supported":          capability.StreamingSupported,
		"streaming_notes":              capability.StreamingNotes,
		"structured_output_supported":  capability.StructuredOutputSupported,
		"structured_output_notes":      capability.StructuredOutputNotes,
		"multimodal_types":             capability.MultimodalTypes,
		"multimodal_extra":             capability.MultimodalExtra,
		"pricing_modes":                capability.PricingModes,
		"reference_input_price":        capability.ReferenceInputPrice,
		"reference_output_price":       capability.ReferenceOutputPrice,
		"failure_billing_mode":         capability.FailureBillingMode,
		"failure_billing_notes":        capability.FailureBillingNotes,
		"api_base_urls":                capability.APIBaseURLs,
		"open_ai_compatible":           capability.OpenAICompatible,
		"truth_commitment_confirmed":   capability.TruthCommitmentConfirmed,
		"updated_at":                   now,
	}
	if err := tx.Model(&SupplierCapability{}).Where("supplier_application_id = ?", applicationID).Updates(updates).Error; err != nil {
		tx.Rollback()
		return nil, err
	}
	existing.CoreServiceTypes = capability.CoreServiceTypes
	existing.SupportedModels = capability.SupportedModels
	existing.SupportedModelNotes = capability.SupportedModelNotes
	existing.SupportedAPIEndpoints = capability.SupportedAPIEndpoints
	existing.SupportedAPIEndpointExtra = capability.SupportedAPIEndpointExtra
	existing.SupportedParams = capability.SupportedParams
	existing.SupportedParamsExtra = capability.SupportedParamsExtra
	existing.StreamingSupported = capability.StreamingSupported
	existing.StreamingNotes = capability.StreamingNotes
	existing.StructuredOutputSupported = capability.StructuredOutputSupported
	existing.StructuredOutputNotes = capability.StructuredOutputNotes
	existing.MultimodalTypes = capability.MultimodalTypes
	existing.MultimodalExtra = capability.MultimodalExtra
	existing.PricingModes = capability.PricingModes
	existing.ReferenceInputPrice = capability.ReferenceInputPrice
	existing.ReferenceOutputPrice = capability.ReferenceOutputPrice
	existing.FailureBillingMode = capability.FailureBillingMode
	existing.FailureBillingNotes = capability.FailureBillingNotes
	existing.APIBaseURLs = capability.APIBaseURLs
	existing.OpenAICompatible = capability.OpenAICompatible
	existing.TruthCommitmentConfirmed = capability.TruthCommitmentConfirmed
	existing.UpdatedAt = now
	if err := tx.Commit().Error; err != nil {
		return nil, err
	}
	return &existing, nil
}

// IsSupplierCapabilityNotFound 判断是否未找到供应商技术能力档案。
func IsSupplierCapabilityNotFound(err error) bool {
	return errors.Is(err, gorm.ErrRecordNotFound)
}

// IsSupplierCapabilityComplete 判断供应商技术能力档案是否满足审批通过最低必填条件。
func IsSupplierCapabilityComplete(capability *SupplierCapability) bool {
	if capability == nil {
		return false
	}
	if strings.TrimSpace(capability.CoreServiceTypes) == "" {
		return false
	}
	if strings.TrimSpace(capability.SupportedModels) == "" {
		return false
	}
	if strings.TrimSpace(capability.SupportedAPIEndpoints) == "" {
		return false
	}
	if strings.TrimSpace(capability.SupportedParams) == "" {
		return false
	}
	if strings.TrimSpace(capability.PricingModes) == "" {
		return false
	}
	if strings.TrimSpace(capability.FailureBillingMode) == "" {
		return false
	}
	if strings.TrimSpace(capability.APIBaseURLs) == "" {
		return false
	}
	return capability.TruthCommitmentConfirmed
}
