package repositories

import (
	"log"
	"regexp"
	"strings"
	"time"

	"github.com/niangaodev/art-code/config"
	"github.com/niangaodev/art-code/models"
)

// CreateUserAccessLog 创建用户访问日志
func CreateUserAccessLog(logEntry *models.UserAccessLog) error {
	if logEntry.AccessTime == 0 {
		logEntry.AccessTime = time.Now().Unix()
	}
	err := config.DB.Create(logEntry).Error
	if err != nil {
		log.Printf("Error creating user access log: %v", err)
		return err
	}
	return nil
}

// HasVisitedThisHour checks if the visitor already has an access log for this article in the current hour.
func HasVisitedThisHour(articleID, userID uint, visitorKey string) (bool, error) {
	hourStart := time.Now().Truncate(time.Hour).Unix()
	hourEnd := hourStart + 3600

	var count int64
	query := config.DB.Model(&models.UserAccessLog{}).
		Where("deleted_at = ?", 0).
		Where("article_id = ?", articleID).
		Where("access_time >= ? AND access_time < ?", hourStart, hourEnd)

	if userID > 0 {
		query = query.Where("user_id = ?", userID)
	} else {
		query = query.Where("visitor_key = ?", visitorKey)
	}

	if err := query.Count(&count).Error; err != nil {
		return false, err
	}

	return count > 0, nil
}

// AccessStats 访问统计数据结构
type AccessStats struct {
	Date  string `json:"date"`
	Count int    `json:"count"`
}

// GetArticleAccessTrend 获取文章访问趋势
func GetArticleAccessTrend(startDate, endDate string) ([]AccessStats, error) {
	query := config.DB.Model(&models.UserAccessLog{}).
		Select("FROM_UNIXTIME(access_time, '%Y-%m-%d') as date, COUNT(*) as count")

	if startDate != "" {
		startUnix := parseDateToUnix(startDate, false)
		query = query.Where("access_time >= ?", startUnix)
	}
	if endDate != "" {
		endUnix := parseDateToUnix(endDate, true)
		query = query.Where("access_time <= ?", endUnix)
	}

	var results []AccessStats
	err := query.Group("date").
		Order("date ASC").
		Scan(&results).Error

	return results, err
}

// GetTopArticlesByAccess 获取访问量最高的文章
func GetTopArticlesByAccess(limit int) ([]struct {
	ArticleID int    `json:"article_id"`
	Title     string `json:"title"`
	Count     int    `json:"count"`
}, error) {
	var results []struct {
		ArticleID int    `json:"article_id"`
		Title     string `json:"title"`
		Count     int    `json:"count"`
	}
	err := config.DB.Model(&models.UserAccessLog{}).
		Select("user_access_logs.article_id, posts.title, COUNT(*) as count").
		Joins("JOIN posts ON user_access_logs.article_id = posts.id").
		Group("user_access_logs.article_id, posts.title").
		Order("count DESC").
		Limit(limit).
		Scan(&results).Error

	return results, err
}

// GetPostAccessLogsFromUserAccessLogs 获取指定文章的访问记录（从 user_access_logs 表）
func GetPostAccessLogsFromUserAccessLogs(postID int, page, pageSize int) ([]models.UserAccessLog, int64, error) {
	query := config.DB.Model(&models.UserAccessLog{}).
		Where("deleted_at = ?", 0).
		Where("article_id = ?", postID)

	var total int64
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	var logs []models.UserAccessLog
	offset := (page - 1) * pageSize
	err := query.Order("access_time DESC").
		Limit(pageSize).
		Offset(offset).
		Find(&logs).Error

	return logs, total, err
}

// GetUserRegionsFromUserAccessLogs 获取用户地域分布（使用 user_access_logs 表的 user_location 字段）
// 返回所有34个省份的数据，没有数据的省份 Count 设为 0
func GetUserRegionsFromUserAccessLogs(startDate, endDate string) ([]struct {
	Region string
	Count  int
}, error) {
	query := config.DB.Model(&models.UserAccessLog{}).
		Select("COALESCE(NULLIF(user_location, ''), 'Unknown') as region, COUNT(DISTINCT user_ip) as count").
		Where("deleted_at = ?", 0)

	if startDate != "" {
		startUnix := parseDateToUnix(startDate, false)
		query = query.Where("access_time >= ?", startUnix)
	}

	if endDate != "" {
		endUnix := parseDateToUnix(endDate, true)
		query = query.Where("access_time <= ?", endUnix)
	}

	var results []struct {
		Region string
		Count  int
	}
	err := query.Group("region").
		Order("count DESC").
		Limit(50).
		Scan(&results).Error

	if err != nil {
		return nil, err
	}

	// 解析归属地，提取省份信息并聚合
	// 注意：现在返回完整的省份名称（如"浙江省"、"北京市"等），不进行任何处理
	provinceMap := make(map[string]int)
	for _, r := range results {
		province := extractProvinceFromRegion(r.Region)
		if province != "未知" {
			provinceMap[province] += r.Count
			log.Printf("Extracted province: %s from region: %s, count: %d", province, r.Region, r.Count)
		} else {
			log.Printf("Failed to extract province from region: %s", r.Region)
		}
	}

	// 定义完整的省份名称列表（包含"省"、"市"、"自治区"等后缀）
	allProvincesFullNames := []string{
		"北京市", "天津市", "河北省", "山西省", "内蒙古自治区", "辽宁省", "吉林省", "黑龙江省",
		"上海市", "江苏省", "浙江省", "安徽省", "福建省", "江西省", "山东省", "河南省",
		"湖北省", "湖南省", "广东省", "广西壮族自治区", "海南省", "重庆市", "四川省", "贵州省",
		"云南省", "西藏自治区", "陕西省", "甘肃省", "青海省", "宁夏回族自治区", "新疆维吾尔自治区", "台湾省", "香港特别行政区", "澳门特别行政区",
	}

	// 为所有省份生成数据，没有数据的设为0
	var finalResults []struct {
		Region string
		Count  int
	}
	for _, province := range allProvincesFullNames {
		count := provinceMap[province]
		finalResults = append(finalResults, struct {
			Region string
			Count  int
		}{
			Region: province,
			Count:  count,
		})
	}

	return finalResults, nil
}

// 所有省份列表（34个）- 用于用户访问日志统计
var allProvincesForUserAccess = []string{
	"北京", "天津", "河北", "山西", "内蒙古", "辽宁", "吉林", "黑龙江",
	"上海", "江苏", "浙江", "安徽", "福建", "江西", "山东", "河南",
	"湖北", "湖南", "广东", "广西", "海南", "重庆", "四川", "贵州",
	"云南", "西藏", "陕西", "甘肃", "青海", "宁夏", "新疆", "台湾", "香港", "澳门",
}

// extractProvinceFromRegion 从归属地字符串中提取省份信息
// 格式: 国家|省份|城市|ISP
// 例如: 中国|浙江省|杭州市|电信 -> 浙江省
// 注意：返回完整的省份名称，包括"省"、"市"、"自治区"等后缀，以匹配地图数据
func extractProvinceFromRegion(region string) string {
	if region == "" || region == "Unknown" || region == "Internal" {
		return "未知"
	}

	// 使用正则表达式验证格式: 国家|省份|城市|ISP
	// 匹配格式: 至少包含"国家|省份"两部分
	regionPattern := regexp.MustCompile(`^[^|]+\|[^|]+`)
	if !regionPattern.MatchString(region) {
		log.Printf("Invalid region format (regex validation failed): %s", region)
		return "未知"
	}

	parts := strings.Split(region, "|")
	// 格式应该是: 国家|省份|城市|ISP (至少需要2个部分)
	if len(parts) < 2 {
		log.Printf("Invalid region format (insufficient parts): %s, parts: %v", region, parts)
		return "未知"
	}

	province := strings.TrimSpace(parts[1]) // 省份在索引1
	if province == "" || province == "0" {
		log.Printf("Invalid province in region: %s, province part: %s", region, province)
		return "未知"
	}

	// 直接返回完整的省份名称，不移除"省"、"市"、"自治区"等后缀
	// 这样可以直接匹配地图数据中的省份名称
	return province
}
