package database

import (
	"database/sql"
	"fmt"
	"log"
	"strings"
	"time"

	"sms-receiver-go/config"
	"sms-receiver-go/models"

	_ "github.com/mattn/go-sqlite3"
)

var db *sql.DB

// Init 初始化数据库
func Init(cfg *config.DatabaseConfig) error {
	var err error
	db, err = sql.Open("sqlite3", cfg.Path)
	if err != nil {
		return fmt.Errorf("打开数据库失败: %w", err)
	}

	if err = db.Ping(); err != nil {
		return fmt.Errorf("数据库连接失败: %w", err)
	}

	// 创建表
	if err = createTables(); err != nil {
		return fmt.Errorf("创建表失败: %w", err)
	}

	log.Printf("数据库初始化成功: %s", cfg.Path)
	return nil
}

// createTables 创建数据表
func createTables() error {
	// 短信消息表
	createMessagesSQL := `
	CREATE TABLE IF NOT EXISTS sms_messages (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		from_number TEXT NOT NULL,
		content TEXT NOT NULL,
		timestamp INTEGER NOT NULL,
		device_info TEXT,
		sim_info TEXT,
		sign_verified INTEGER,
		ip_address TEXT,
		created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
	);
	`

	// 接收日志表
	createLogsSQL := `
	CREATE TABLE IF NOT EXISTS receive_logs (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		from_number TEXT NOT NULL,
		content TEXT NOT NULL,
		timestamp INTEGER NOT NULL,
		sign TEXT,
		sign_valid INTEGER,
		ip_address TEXT,
		status TEXT NOT NULL,
		error_message TEXT,
		created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
	);
	`

	// 创建索引
	createIndexesSQL := `
	CREATE INDEX IF NOT EXISTS idx_messages_from ON sms_messages(from_number);
	CREATE INDEX IF NOT EXISTS idx_messages_timestamp ON sms_messages(timestamp);
	CREATE INDEX IF NOT EXISTS idx_messages_created ON sms_messages(created_at);
	CREATE INDEX IF NOT EXISTS idx_logs_created ON receive_logs(created_at);
	`

	statements := []string{createMessagesSQL, createLogsSQL, createIndexesSQL}
	for _, stmt := range statements {
		if _, err := db.Exec(stmt); err != nil {
			return fmt.Errorf("执行 SQL 失败: %w", err)
		}
	}

	return nil
}

// InsertMessage 插入短信消息
func InsertMessage(msg *models.SMSMessage) (int64, error) {
	result, err := db.Exec(`
		INSERT INTO sms_messages (from_number, content, timestamp, device_info, sim_info, sign_verified, ip_address)
		VALUES (?, ?, ?, ?, ?, ?, ?)
	`,
		msg.FromNumber,
		msg.Content,
		msg.Timestamp,
		msg.DeviceInfo,
		msg.SIMInfo,
		msg.SignVerified,
		msg.IPAddress,
	)
	if err != nil {
		return 0, fmt.Errorf("插入消息失败: %w", err)
	}
	return result.LastInsertId()
}

// InsertLog 插入接收日志
func InsertLog(log *models.ReceiveLog) (int64, error) {
	result, err := db.Exec(`
		INSERT INTO receive_logs (from_number, content, timestamp, sign, sign_valid, ip_address, status, error_message)
		VALUES (?, ?, ?, ?, ?, ?, ?, ?)
	`,
		log.FromNumber,
		log.Content,
		log.Timestamp,
		log.Sign,
		log.SignValid,
		log.IPAddress,
		log.Status,
		log.ErrorMessage,
	)
	if err != nil {
		return 0, fmt.Errorf("插入日志失败: %w", err)
	}
	return result.LastInsertId()
}

// GetMessages 获取短信列表
func GetMessages(page, limit int, from string, search string) ([]models.SMSMessage, int64, error) {
	offset := (page - 1) * limit

	// 构建查询条件
	var conditions []string
	var args []interface{}

	if from != "" {
		conditions = append(conditions, "from_number = ?")
		args = append(args, from)
	}
	if search != "" {
		conditions = append(conditions, "(from_number LIKE ? OR content LIKE ?)")
		args = append(args, "%"+search+"%", "%"+search+"%")
	}

	whereClause := ""
	if len(conditions) > 0 {
		whereClause = "WHERE " + strings.Join(conditions, " AND ")
	}

	// 查询总数
	var total int64
	countSQL := fmt.Sprintf("SELECT COUNT(*) FROM sms_messages %s", whereClause)
	if err := db.QueryRow(countSQL, args...).Scan(&total); err != nil {
		return nil, 0, fmt.Errorf("查询总数失败: %w", err)
	}

	// 查询数据（按短信时间戳排序，与 Python 版本一致）
	querySQL := fmt.Sprintf(`
		SELECT id, from_number, content, timestamp, device_info, sim_info, sign_verified, ip_address, created_at
		FROM sms_messages
		%s
		ORDER BY timestamp DESC, id DESC
		LIMIT ? OFFSET ?
	`, whereClause)

	args = append(args, limit, offset)
	rows, err := db.Query(querySQL, args...)
	if err != nil {
		return nil, 0, fmt.Errorf("查询消息失败: %w", err)
	}
	defer rows.Close()

	var messages []models.SMSMessage
	for rows.Next() {
		var msg models.SMSMessage
		err := rows.Scan(
			&msg.ID,
			&msg.FromNumber,
			&msg.Content,
			&msg.Timestamp,
			&msg.DeviceInfo,
			&msg.SIMInfo,
			&msg.SignVerified,
			&msg.IPAddress,
			&msg.CreatedAt,
		)
		if err != nil {
			return nil, 0, fmt.Errorf("扫描消息失败: %w", err)
		}
		messages = append(messages, msg)
	}

	return messages, total, nil
}

// GetMessageByID 根据 ID 获取消息详情
func GetMessageByID(id int64) (*models.SMSMessage, error) {
	var msg models.SMSMessage
	err := db.QueryRow(`
		SELECT id, from_number, content, timestamp, device_info, sim_info, sign_verified, ip_address, created_at
		FROM sms_messages WHERE id = ?
	`, id).Scan(
		&msg.ID,
		&msg.FromNumber,
		&msg.Content,
		&msg.Timestamp,
		&msg.DeviceInfo,
		&msg.SIMInfo,
		&msg.SignVerified,
		&msg.IPAddress,
		&msg.CreatedAt,
	)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, nil
		}
		return nil, fmt.Errorf("查询消息失败: %w", err)
	}
	return &msg, nil
}

// GetStatistics 获取统计信息
func GetStatistics() (*models.Statistics, error) {
	stats := &models.Statistics{}

	// 总数
	if err := db.QueryRow("SELECT COUNT(*) FROM sms_messages").Scan(&stats.Total); err != nil {
		return nil, err
	}

	// 今日数量
	today := time.Now().Format("2006-01-02")
	if err := db.QueryRow("SELECT COUNT(*) FROM sms_messages WHERE date(created_at) = ?", today).Scan(&stats.Today); err != nil {
		return nil, err
	}

	// 本周数量
	weekStart := time.Now().AddDate(0, 0, -int(time.Now().Weekday())+1).Format("2006-01-02")
	if err := db.QueryRow("SELECT COUNT(*) FROM sms_messages WHERE created_at >= ?", weekStart).Scan(&stats.Week); err != nil {
		return nil, err
	}

	// 签名验证通过数量
	if err := db.QueryRow("SELECT COUNT(*) FROM sms_messages WHERE sign_verified = 1").Scan(&stats.Verified); err != nil {
		return nil, err
	}

	// 签名验证未通过数量
	if err := db.QueryRow("SELECT COUNT(*) FROM sms_messages WHERE sign_verified = 0").Scan(&stats.Unverified); err != nil {
		return nil, err
	}

	return stats, nil
}

// GetLogs 获取接收日志
func GetLogs(page, limit int) ([]models.ReceiveLog, int64, error) {
	offset := (page - 1) * limit

	// 查询总数
	var total int64
	if err := db.QueryRow("SELECT COUNT(*) FROM receive_logs").Scan(&total); err != nil {
		return nil, 0, err
	}

	rows, err := db.Query(`
		SELECT id, from_number, content, timestamp, sign, sign_valid, ip_address, status, error_message, created_at
		FROM receive_logs
		ORDER BY created_at DESC
		LIMIT ? OFFSET ?
	`, limit, offset)
	if err != nil {
		return nil, 0, err
	}
	defer rows.Close()

	var logs []models.ReceiveLog
	for rows.Next() {
		var log models.ReceiveLog
		err := rows.Scan(
			&log.ID,
			&log.FromNumber,
			&log.Content,
			&log.Timestamp,
			&log.Sign,
			&log.SignValid,
			&log.IPAddress,
			&log.Status,
			&log.ErrorMessage,
			&log.CreatedAt,
		)
		if err != nil {
			return nil, 0, err
		}
		logs = append(logs, log)
	}

	return logs, total, nil
}

// CleanupOldMessages 清理旧消息
func CleanupOldMessages(days int) (int64, error) {
	cutoff := time.Now().AddDate(0, 0, -days).Format("2006-01-02 15:04:05")
	result, err := db.Exec("DELETE FROM sms_messages WHERE created_at < ?", cutoff)
	if err != nil {
		return 0, err
	}
	return result.RowsAffected()
}

// GetDB 获取数据库实例
func GetDB() *sql.DB {
	return db
}

// Close 关闭数据库连接
func Close() error {
	if db != nil {
		return db.Close()
	}
	return nil
}
