package vulnmodel

import (
	"database/sql/driver"
	"encoding/json"
	"fmt"
	"time"

	coremodel "vul-backend/internal/model"
)

type SeverityLevel string

const (
	SeverityLow      SeverityLevel = "low"
	SeverityMedium   SeverityLevel = "medium"
	SeverityHigh     SeverityLevel = "high"
	SeverityCritical SeverityLevel = "critical"
)

type VulnerabilityStatus string

const (
	StatusActive        VulnerabilityStatus = "active"
	StatusRetesting     VulnerabilityStatus = "retesting"
	StatusFixed         VulnerabilityStatus = "fixed"
	StatusFalsePositive VulnerabilityStatus = "false_positive"
	StatusRiskAccepted  VulnerabilityStatus = "risk_accepted"
)

// StringArray stores a slice of strings using a JSON column.
type StringArray []string

func (a StringArray) Value() (driver.Value, error) {
	if len(a) == 0 {
		return "[]", nil
	}
	b, err := json.Marshal(a)
	if err != nil {
		return nil, err
	}
	return string(b), nil
}

func (a *StringArray) Scan(value interface{}) error {
	switch v := value.(type) {
	case []byte:
		if len(v) == 0 {
			*a = []string{}
			return nil
		}
		return json.Unmarshal(v, a)
	case string:
		if v == "" {
			*a = []string{}
			return nil
		}
		return json.Unmarshal([]byte(v), a)
	case nil:
		*a = []string{}
		return nil
	default:
		return fmt.Errorf("unsupported type for StringArray: %T", value)
	}
}

type Vulnerability struct {
	coremodel.Base
	Title               string              `gorm:"size:500" json:"title"`
	SeverityLevel       SeverityLevel       `gorm:"size:20" json:"severity_level"`
	Status              VulnerabilityStatus `gorm:"size:20" json:"status"`
	Application         string              `gorm:"size:200" json:"application"`
	BusinessDept        string              `gorm:"size:120" json:"business_dept"`
	VulnerabilityType   string              `gorm:"size:120" json:"vulnerability_type"`
	DiscoveryChannel    string              `gorm:"size:20" json:"discovery_channel"`
	DiscoveryPhase      string              `gorm:"size:20" json:"discovery_phase"`
	NetworkEnv          string              `gorm:"size:20" json:"network_env"`
	IsThirdParty        bool                `json:"is_third_party"`
	InterfacePath       string              `gorm:"size:500" json:"interface_path"`
	Source              string              `gorm:"size:120" json:"source"`
	AffectedAssetsCount int                 `json:"affected_assets_count"`
	Tags                StringArray         `gorm:"type:json" json:"tags"`
	HasPOCVerification  bool                `json:"has_poc_verification"`
	DependencyName      string              `gorm:"size:200" json:"dependency_name"`
	DependencyVersion   string              `gorm:"size:100" json:"dependency_version"`
	BatchGroupID        *uint64             `json:"batch_group_id"`
	OwnerID             *uint64             `json:"owner_id"`
	Owner               *coremodel.User     `gorm:"foreignKey:OwnerID" json:"owner,omitempty"`
	SubmitterID         uint64              `json:"submitter_id"`
	Submitter           coremodel.User      `gorm:"foreignKey:SubmitterID" json:"submitter"`
	Description         string              `gorm:"type:text" json:"description"`
	VerificationSteps   string              `gorm:"type:text" json:"verification_steps"`
	POCText             string              `gorm:"type:text" json:"poc_text"`
	SubmittedAt         time.Time           `json:"submitted_at"`
	ClaimedAt           *time.Time          `json:"claimed_at"`
	FixRequestedAt      *time.Time          `json:"fix_requested_at"`
	FixedAt             *time.Time          `json:"fixed_at"`
	ClosedAt            *time.Time          `json:"closed_at"`
	SLADeadline         time.Time           `json:"sla_deadline"`
	IsOverdue           bool                `json:"is_overdue"`
}
