package host

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

	"git.lnton.com/lnton/pkg/orm"
	"gorm.io/gorm"
)

var (
	_ encoding.BinaryMarshaler   = (*Device)(nil)
	_ encoding.BinaryUnmarshaler = (*Device)(nil)
)

// Ability 设备能力
type Ability struct {
	PTZ            bool `json:"ptz"`             // 云台控制
	WIFI           bool `json:"wifi"`            // WIFI配网
	OTA            bool `json:"ota"`             // OTA升级
	CloudBroadcast bool `json:"cloud_broadcast"` // 云广播
	AI             bool `json:"ai"`              // 智能检测
	GAT1400        bool `json:"gat_1400"`        // GA/T1400
	Talk           bool `json:"talk"`            // P2P对讲
}

// Device 设备
type Device struct {
	ID             string    `gorm:"primaryKey" json:"id"`
	CreatedAt      orm.Time  `gorm:"notNull;default:CURRENT_TIMESTAMP;index;comment:创建时间" json:"created_at"`
	UpdatedAt      orm.Time  `gorm:"notNull;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"`
	Name           string    `gorm:"column:name;notNull;default:'';comment:设备名称" json:"name"`         // 设备名称
	Protocol       string    `gorm:"column:protocol;notNull;default:'';comment:设备协议" json:"protocol"` // 设备协议 rtsp/rtmp
	IP             string    `gorm:"column:ip;notNull;default:'';comment:设备IP" json:"ip"`             // ip 地址
	Port           int       `gorm:"column:port;notNull;default:0;comment:端口" json:"port"`            // 端口号
	Addr           string    `gorm:"column:addr;notNull;default:'';comment:ip 物理地址" json:"addr"`
	Remark         string    `gorm:"column:remark;notNull;default:'';comment:备注" json:"remark"`                  // 备注描述
	Username       string    `gorm:"column:username;notNull;default:'';comment:账号" json:"username"`              // 账号
	Password       string    `gorm:"column:password;notNull;default:'';comment:密码" json:"password"`              // 密码
	MediaTransport string    `json:"media_transport,omitempty"`                                                  // TCP/UDP 服务端配置，空表示 UDP
	GBCode         string    `gorm:"column:gb_code;notNull;default:'';comment:国标设备编码" json:"gb_code"`            // 设备编码
	UID            int       `gorm:"column:uid;notNull;default:0;comment:创建者" json:"uid"`                        // 创建者
	Version        string    `gorm:"column:version;notNull;default:'';comment:版本" json:"version"`                // 固件版本号
	Ability        Ability   `gorm:"column:ability;type:jsonb;notNull;default:'{}';comment:设备能力" json:"ability"` // 能力
	Status         bool      `gorm:"column:status;notNull;default:FALSE;comment:在线状态" json:"status"`             // true:在线;false;离线
	Model          string    `gorm:"column:model;notNull;default:'';comment:设备型号" json:"model"`                  // 状态
	ChannelCount   int       `gorm:"column:channel_count;notNull;default:0;comment:通道数量" json:"channel_count"`   // 通道数量
	Ext            DeviceExt `gorm:"type:jsonb;notNull;default:'{}';comment:设备扩展信息" json:"ext"`
	GB             GBExt     `gorm:"type:jsonb;notNull;default:'{}';comment:国标扩展信息" json:"gb"`
	ONVIF          ONVIFExt  `gorm:"type:jsonb;notNull;default:'{}';comment:ONVIF 扩展信息" json:"onvif"`
	Network        string    `gorm:"column:network;notNull;default:'WAN';comment:网络类型" json:"network"` // LAN:局域网;WAN:公网
	// CustomRTPIP    string    `gorm:"column:custom_rtp_ip;notNull;default:'';comment:自定义 rtp ip" json:"custom_rtp_ip"` // 自定义 rtp ip
	RTPID      string `gorm:"column:rtp_id;notNull;default:''" json:"rtp_id"`
	ISPlatform bool   `gorm:"column:is_platform;notNull;default:FALSE;comment:设备或平台" json:"is_platform"` // 设备/平台
	URL        string `gorm:"column:url;notNull;default:'';comment:拉流地址" json:"url"`                     // 拉流地址
	// LastUpdatedAt orm.Time `gorm:"column:last_updated_at;notNull;default:'1970-01-01 00:00:00';index;comment:最后更新时间" json:"last_updated_at"`
	LastPushedAt orm.Time `gorm:"column:last_pushed_at;notNull;index;default:'1970-01-01 00:00:00';comment:最后推送时间" json:"last_pushed_at"`
	FilterList   string   `gorm:"column:filter_list;notNull;default:'';comment:过滤列表" json:"filter_list"`

	// 示例数据 1,2,3
	// 应用场景
	// - 播放的时候，提供相关线路连接，默认取第一个
	Routes      string `gorm:"column:routes;notNull;default:'';comment:线路" json:"routes"`
	DefaultGBID string `gorm:"-" json:"default_gb_id"`
	PullMode    int    `gorm:"column:pull_mode;notNull;default:0;comment:拉流模式" json:"pull_mode"` // 拉流模式 默认(0) 拉流库(1)
	Audio       string `gorm:"column:audio;notNull;default:'0';comment:音频控制" json:"audio"`       // 音频控制 0 关闭 1 启用 *** 自定义音频地址

	// 长沙地铁项目
	ServerID   string `gorm:"column:server_id;notNull;default:'';comment:平台ID" json:"server_id" `
	ServerName string `json:"column:server_name;notNull;default:'';comment:平台名称" json:"server_name"`
}

func (a DeviceExt) Value() (driver.Value, error) {
	return json.Marshal(a)
}

func (d *Device) BeforeCreate(tx *gorm.DB) error {
	d.CreatedAt = orm.Now()
	d.UpdatedAt = orm.Now()
	return nil
}

func (d *Device) BeforeUpdate(tx *gorm.DB) error {
	d.UpdatedAt = orm.Now()
	return nil
}

func (d *Device) NetworkIP(iip, eip string) string {
	if d.Network == "LAN" {
		return iip
	}
	return eip
}

type ONVIFExt struct {
	AuthType string `gorm:"column:auth_type;notNull;default:'';comment:认证类型" json:"auth_type"` // 认证类型
}

// Scan implements orm.Scaner.
func (o *ONVIFExt) Scan(input interface{}) error {
	return orm.JsonUnmarshal(input, o)
}

func (o ONVIFExt) Value() (driver.Value, error) {
	return json.Marshal(o)
}

// GBExt 国标扩展信息
// 实际在使用过程中，发现部分字段存在支持其它协议的情况
type GBExt struct {
	SIPTransport string `json:"sip_transport,omitempty"` // TCP/UDP 由设备主动推送
	SIPVersion   string `json:"sip_version,omitempty"`   // 国标 sip 版本号 2011/2016/2022

	CatalogPeriod     int    `json:"catalog_period"`               // 目录刷新周期
	CatelogSubscribe  bool   `json:"catelog_subscribe,omitempty"`  // 目录订阅，仅支持 gb28181
	AlarmSubscribe    bool   `json:"alarm_subscribe,omitempty"`    // 报警订阅，支持 gb28181/sdsdk
	PositionSubscribe bool   `json:"position_subscribe,omitempty"` // 位置订阅，仅支持 gb28181
	NotifyURL         string `json:"notify_url,omitempty"`         // 通知地址

	StorageID  int `json:"storage_id,string,omitempty"`
	StrategyID int `json:"strategy_id,string,omitempty"`
}

// Scan implements orm.Scaner.
func (d *GBExt) Scan(input interface{}) error {
	return orm.JsonUnmarshal(input, d)
}

func (d GBExt) Value() (driver.Value, error) {
	return json.Marshal(d)
}

// DeviceExt 设备信息
type DeviceExt struct {
	WanIP        string `json:"wan_ip"`
	LanIP        string `json:"lan_ip"`
	Mac          string `json:"mac,omitempty"`
	SDKVersion   string `json:"sdk_version,omitempty"`
	UID          string `json:"uid,omitempty"`          // 没啥用，等同于 sn，甲方设计必须有这个参数
	Manufacturer string `json:"manufacturer,omitempty"` // 厂商
	RemoteIP     string `json:"remote_ip,omitempty"`
}

// Scan implements orm.Scaner.
func (d *DeviceExt) Scan(input interface{}) error {
	return orm.JsonUnmarshal(input, d)
}

// UnmarshalBinary implements encoding.BinaryUnmarshaler.
func (d *Device) UnmarshalBinary(data []byte) error {
	return json.Unmarshal(data, d)
}

// MarshalBinary implements encoding.BinaryMarshaler.
func (d Device) MarshalBinary() ([]byte, error) {
	return json.Marshal(d)
}

// func (d *Device) GetRoutes() []Route {
// 	routes := make([]Route, 0, 2)
// 	routeIDs := strings.Split(d.Routes, ",")
// 	for _, id := range routeIDs {
// 		if id == "" {
// 			continue
// 		}
// 		intID, _ := strconv.Atoi(id)
// 		routes = append(routes, Route{ID: intID})
// 	}
// 	return routes
// }
