package alertmodel

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

	coremodel "security-center-backend/internal/model"
)

type UInt64Array []uint64

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

type StringArray []string

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

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

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

type TriggerSource string

const (
	TriggerSourceManual TriggerSource = "manual"
	TriggerSourceCron   TriggerSource = "cron"
	TriggerSourceEvent  TriggerSource = "event"
)

type RunStatus string

const (
	RunStatusRunning RunStatus = "running"
	RunStatusSuccess RunStatus = "success"
	RunStatusError   RunStatus = "error"
)

type DeliveryStatus string

const (
	DeliveryStatusSuccess DeliveryStatus = "success"
	DeliveryStatusError   DeliveryStatus = "error"
)

type SLAReminderKind string

const (
	SLAReminderKindDueSoon SLAReminderKind = "due_soon"
	SLAReminderKindOverdue SLAReminderKind = "overdue"
)

type RecipientType string

const (
	RecipientTypeWebhook  RecipientType = "webhook"
	RecipientTypeEmployee RecipientType = "employee"
	RecipientTypeScope    RecipientType = "scope"
)

type RecipientTargetKey string

const (
	RecipientTargetSecurityTeam    RecipientTargetKey = "security_team"
	RecipientTargetRDTeam          RecipientTargetKey = "rd_team"
	RecipientTargetEntityDept      RecipientTargetKey = "entity_department"
	RecipientTargetEntityOwner     RecipientTargetKey = "entity_owner"
	RecipientTargetEntityFixer     RecipientTargetKey = "entity_fixer"
	RecipientTargetEntitySubmitter RecipientTargetKey = "entity_submitter"
)

type LarkAlertRule struct {
	coremodel.Base
	Name                  string          `gorm:"size:255" json:"name"`
	Enabled               bool            `json:"enabled"`
	EntityType            string          `gorm:"size:32;index" json:"entity_type"` // vulnerability | asset
	CronExpr              string          `gorm:"size:64" json:"cron_expr,omitempty"`
	EventOnCreate         bool            `json:"event_on_create"`
	EventOnUpdate         bool            `json:"event_on_update"`
	EventOnStatusChange   bool            `json:"event_on_status_change"`
	EventOnSeverityChange bool            `json:"event_on_severity_change"`
	SendViaWebhook        bool            `json:"send_via_webhook"`
	SendViaApp            bool            `json:"send_via_app"`
	RecipientEmployeeIDs  UInt64Array     `gorm:"type:json" json:"recipient_employee_ids,omitempty"`
	RecipientTargetKeys   StringArray     `gorm:"type:json" json:"recipient_target_keys,omitempty"`
	Conditions            coremodel.JSONB `gorm:"type:json" json:"conditions,omitempty"`
	CardTemplate          string          `gorm:"type:text" json:"card_template"`
	MaxMatchesPerRun      int             `gorm:"default:50" json:"max_matches_per_run"`
	LastRunAt             *time.Time      `json:"last_run_at,omitempty"`
}

type LarkAlertRun struct {
	coremodel.Base
	RuleID            *uint64       `gorm:"index" json:"rule_id,omitempty"`
	TriggerSource     TriggerSource `gorm:"size:16" json:"trigger_source"`
	TriggerEntityType string        `gorm:"size:32" json:"trigger_entity_type,omitempty"`
	TriggerEntityID   *uint64       `json:"trigger_entity_id,omitempty"`
	Status            RunStatus     `gorm:"size:16" json:"status"`
	StartedAt         time.Time     `json:"started_at"`
	FinishedAt        *time.Time    `json:"finished_at,omitempty"`
	DurationMs        uint64        `json:"duration_ms"`
	MatchedCount      int           `json:"matched_count"`
	DeliveriesTotal   int           `json:"deliveries_total"`
	DeliveriesSuccess int           `json:"deliveries_success"`
	DeliveriesFailed  int           `json:"deliveries_failed"`
	ErrorMessage      string        `gorm:"type:text" json:"error_message,omitempty"`
}

type LarkAlertDelivery struct {
	coremodel.Base
	RunID          uint64          `gorm:"index" json:"run_id"`
	RuleID         *uint64         `gorm:"index" json:"rule_id,omitempty"`
	RecipientType  RecipientType   `gorm:"size:16" json:"recipient_type"`
	RecipientLabel string          `gorm:"size:64" json:"recipient_label,omitempty"`
	EmployeeID     *uint64         `gorm:"index" json:"employee_id,omitempty"`
	WebhookURLHash string          `gorm:"size:64" json:"webhook_url_hash,omitempty"`
	Status         DeliveryStatus  `gorm:"size:16" json:"status"`
	SentAt         time.Time       `json:"sent_at"`
	ResponseCode   *int            `json:"response_code,omitempty"`
	ErrorMessage   string          `gorm:"type:text" json:"error_message,omitempty"`
	ResponseBody   string          `gorm:"type:text" json:"response_body,omitempty"`
	CardPreview    coremodel.JSONB `gorm:"type:json" json:"card_preview,omitempty"`
}

type AlertRuntimeOffset struct {
	coremodel.Base
	OffsetKey       string `gorm:"size:64;uniqueIndex" json:"offset_key"`
	LastProcessedID uint64 `gorm:"not null;default:0" json:"last_processed_id"`
}

type VulnerabilitySLAReminderDelivery struct {
	coremodel.Base
	VulnerabilityID     uint64          `gorm:"index:idx_sla_reminder_lookup,priority:1" json:"vulnerability_id"`
	ReminderKind        SLAReminderKind `gorm:"size:32;index:idx_sla_reminder_lookup,priority:2" json:"reminder_kind"`
	RecipientEmployeeID uint64          `gorm:"index:idx_sla_reminder_lookup,priority:3" json:"recipient_employee_id"`
	RecipientLabel      string          `gorm:"size:64" json:"recipient_label,omitempty"`
	SLADeadlineSnapshot time.Time       `gorm:"index:idx_sla_reminder_lookup,priority:4" json:"sla_deadline_snapshot"`
	Status              DeliveryStatus  `gorm:"size:16;index:idx_sla_reminder_lookup,priority:5" json:"status"`
	SentAt              time.Time       `gorm:"index" json:"sent_at"`
	ErrorMessage        string          `gorm:"type:text" json:"error_message,omitempty"`
	CardPreview         coremodel.JSONB `gorm:"type:json" json:"card_preview,omitempty"`
}
