package store

import (
	"time"
)

type User struct {
	ID           uint      `gorm:"primaryKey" json:"id"`
	Username     string    `gorm:"uniqueIndex;size:64;not null" json:"username"`
	PasswordHash string    `gorm:"size:255;not null" json:"-"`
	Role         string    `gorm:"size:16;not null;default:visitor" json:"role"`
	Status       bool      `gorm:"not null;default:true" json:"status"`
	CreatedAt    time.Time `json:"created_at"`
	UpdatedAt    time.Time `json:"updated_at"`
}

type Client struct {
	ID           uint       `gorm:"primaryKey" json:"id"`
	Name         string     `gorm:"size:128;not null" json:"name"`
	VerifyKey    string     `gorm:"uniqueIndex;size:64;not null" json:"verify_key"`
	OwnerUserID  uint       `gorm:"index;not null" json:"owner_user_id"`
	RateLimit    int64      `gorm:"default:0" json:"rate_limit"`
	MaxConn      int        `gorm:"default:0" json:"max_conn"`
	ExpireAt     *time.Time `json:"expire_at"`
	Status       bool       `gorm:"not null;default:true" json:"status"`
	IPForwardMode string    `gorm:"size:16;default:replace" json:"ip_forward_mode"` // replace, append
	CustomHeaders string    `gorm:"type:text" json:"custom_headers"`             // JSON map
	InletFlow    int64      `gorm:"default:0" json:"inlet_flow"`
	ExportFlow   int64      `gorm:"default:0" json:"export_flow"`
	CreatedAt    time.Time  `json:"created_at"`
	UpdatedAt    time.Time  `json:"updated_at"`
}

type Tunnel struct {
	ID         uint      `gorm:"primaryKey" json:"id"`
	ClientID   uint      `gorm:"index;not null" json:"client_id"`
	Name       string    `gorm:"size:128" json:"name"`
	Mode       string    `gorm:"size:16;not null" json:"mode"` // tcp, udp
	ListenIP   string    `gorm:"size:64;default:0.0.0.0" json:"listen_ip"`
	ListenPort int       `gorm:"not null;uniqueIndex" json:"listen_port"`
	TargetAddr string    `gorm:"size:256;not null" json:"target_addr"`
	IPForwardMode string `gorm:"size:16;default:replace" json:"ip_forward_mode"` // replace, append
	CustomHeaders string `gorm:"type:text" json:"custom_headers"`             // JSON map
	Status     bool      `gorm:"not null;default:true" json:"status"`
	RunStatus  bool      `gorm:"not null;default:false" json:"run_status"`
	InletFlow  int64     `gorm:"default:0" json:"inlet_flow"`
	ExportFlow        int64     `gorm:"default:0" json:"export_flow"`
	VisitorAuthEnabled bool     `gorm:"not null;default:false" json:"visitor_auth_enabled"`
	VisitorBindMode    string   `gorm:"size:16;default:all" json:"visitor_bind_mode"` // all, selected
	VisitorTTLSeconds  int      `gorm:"default:7200" json:"visitor_ttl_seconds"`
	CreatedAt          time.Time `json:"created_at"`
	UpdatedAt          time.Time `json:"updated_at"`
}

type Host struct {
	ID         uint      `gorm:"primaryKey" json:"id"`
	ClientID   uint      `gorm:"index;not null" json:"client_id"`
	Host       string    `gorm:"size:256;not null;uniqueIndex:idx_host_route" json:"host"`
	Location   string    `gorm:"size:256;default:/;uniqueIndex:idx_host_route" json:"location"`
	Scheme     string    `gorm:"size:16;default:all" json:"scheme"` // http, https, all
	TargetAddr string    `gorm:"size:256;not null" json:"target_addr"`
	CertPath   string    `gorm:"size:512" json:"cert_path"`
	KeyPath    string    `gorm:"size:512" json:"key_path"`
	AutoHTTPS  bool      `gorm:"default:false" json:"auto_https"`
	IPForwardMode string `gorm:"size:16;default:replace" json:"ip_forward_mode"` // replace, append
	CustomHeaders string `gorm:"type:text" json:"custom_headers"`             // JSON map
	Status     bool      `gorm:"not null;default:true" json:"status"`
	InletFlow  int64     `gorm:"default:0" json:"inlet_flow"`
	ExportFlow        int64     `gorm:"default:0" json:"export_flow"`
	VisitorAuthEnabled bool     `gorm:"not null;default:false" json:"visitor_auth_enabled"`
	VisitorBindMode    string   `gorm:"size:16;default:all" json:"visitor_bind_mode"` // all, selected
	VisitorTTLSeconds  int      `gorm:"default:7200" json:"visitor_ttl_seconds"`
	CreatedAt          time.Time `json:"created_at"`
	UpdatedAt          time.Time `json:"updated_at"`
}

type ResourceVisitor struct {
	ID           uint      `gorm:"primaryKey" json:"id"`
	ResourceType string    `gorm:"size:16;not null;uniqueIndex:idx_rv_bind" json:"resource_type"`
	ResourceID   uint      `gorm:"not null;uniqueIndex:idx_rv_bind" json:"resource_id"`
	UserID       uint      `gorm:"not null;uniqueIndex:idx_rv_bind" json:"user_id"`
	CreatedAt    time.Time `json:"created_at"`
}

type IPRule struct {
	ID           uint      `gorm:"primaryKey" json:"id"`
	Scope        string    `gorm:"size:16;not null;index" json:"scope"` // global, client, host, tunnel
	ResourceID   uint      `gorm:"index;default:0" json:"resource_id"`
	Type         string    `gorm:"size:8;not null" json:"type"` // allow, deny
	Pattern      string    `gorm:"size:512;not null" json:"pattern"`
	PatternKind  string    `gorm:"size:16;not null;default:exact" json:"pattern_kind"` // exact, cidr, regex
	Priority     int       `gorm:"default:0" json:"priority"`
	Remark       string    `gorm:"size:256" json:"remark"`
	CreatedAt    time.Time `json:"created_at"`
	UpdatedAt    time.Time `json:"updated_at"`
}

type AuthPolicy struct {
	ID           uint      `gorm:"primaryKey" json:"id"`
	ResourceType string    `gorm:"size:16;not null;index" json:"resource_type"` // host, tunnel
	ResourceID   uint      `gorm:"index;not null" json:"resource_id"`
	Type         string    `gorm:"size:16;not null" json:"type"` // basic, form, callback
	Password     string    `gorm:"size:256" json:"-"`
	CallbackURL  string    `gorm:"size:512" json:"callback_url"`
	Enabled      bool      `gorm:"not null;default:true" json:"enabled"`
	TTLSeconds   int       `gorm:"default:7200" json:"ttl_seconds"`
	CreatedAt    time.Time `json:"created_at"`
	UpdatedAt    time.Time `json:"updated_at"`
}

type FlowStat struct {
	ID           uint      `gorm:"primaryKey" json:"id"`
	ResourceType string    `gorm:"size:16;not null;uniqueIndex:idx_flow_resource" json:"resource_type"`
	ResourceID   uint      `gorm:"not null;uniqueIndex:idx_flow_resource" json:"resource_id"`
	InletBytes   int64     `gorm:"default:0" json:"inlet_bytes"`
	ExportBytes  int64     `gorm:"default:0" json:"export_bytes"`
	UpdatedAt    time.Time `json:"updated_at"`
}

type RequestIP struct {
	ID           uint      `gorm:"primaryKey" json:"id"`
	ResourceType string    `gorm:"size:16;not null;uniqueIndex:idx_req_ip" json:"resource_type"`
	ResourceID   uint      `gorm:"not null;uniqueIndex:idx_req_ip" json:"resource_id"`
	IP           string    `gorm:"size:64;not null;uniqueIndex:idx_req_ip" json:"ip"`
	DirectIP     string    `gorm:"size:64" json:"direct_ip"`
	HitCount     int64     `gorm:"default:0" json:"hit_count"`
	LastSeenAt   time.Time `json:"last_seen_at"`
}

type Session struct {
	ID        uint      `gorm:"primaryKey" json:"id"`
	Token     string    `gorm:"uniqueIndex;size:512;not null" json:"token"`
	UserID    uint      `gorm:"index;not null" json:"user_id"`
	ExpiresAt time.Time `gorm:"index" json:"expires_at"`
	CreatedAt time.Time `json:"created_at"`
}

type APIKey struct {
	ID        uint      `gorm:"primaryKey" json:"id"`
	Name      string    `gorm:"size:128;not null" json:"name"`
	KeyPrefix string    `gorm:"size:16;not null" json:"key_prefix"`
	KeyHash   string    `gorm:"size:64;not null;uniqueIndex" json:"-"`
	UserID    uint      `gorm:"index;not null" json:"user_id"`
	Status    bool      `gorm:"not null;default:true" json:"status"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

// VisitorAccessLog records visitor login and resource access (max 200 per user retained).
type VisitorAccessLog struct {
	ID           uint      `gorm:"primaryKey" json:"id"`
	UserID       uint      `gorm:"index:idx_va_user_time;not null" json:"user_id"`
	ResourceType string    `gorm:"size:16;not null" json:"resource_type"`
	ResourceID   uint      `gorm:"not null" json:"resource_id"`
	Action       string    `gorm:"size:16;not null" json:"action"` // login, access
	Method       string    `gorm:"size:16" json:"method"`
	Path         string    `gorm:"size:512" json:"path"`
	IP           string    `gorm:"size:64" json:"ip"`
	UserAgent    string    `gorm:"size:256" json:"user_agent"`
	CreatedAt    time.Time `gorm:"index:idx_va_user_time" json:"created_at"`
}
