package service

import (
	"math"
	"regexp"
	"strconv"
	"time"

	"ops-assistant/models"

	"github.com/yanyiwu/gojieba"
	"gorm.io/gorm"
)

type FinanceService struct {
	db    *gorm.DB
	jieba *gojieba.Jieba
}

func NewFinanceService(db *gorm.DB) *FinanceService {
	return &FinanceService{
		db:    db,
		jieba: gojieba.NewJieba(),
	}
}

func (s *FinanceService) Close() {
	s.jieba.Free()
}

// ParseText 从自然语言文本中提取金额（分）和分类
func (s *FinanceService) ParseText(text string) (int64, string) {
	// 1. 提取金额 — 优先匹配带单位的，如 "15.5元"、"¥30"、"20块"
	amountPatterns := []*regexp.Regexp{
		regexp.MustCompile(`[¥￥]\s*(\d+\.?\d*)`),
		regexp.MustCompile(`(\d+\.?\d*)\s*[元块]`),
	}

	var amountStr string
	for _, re := range amountPatterns {
		m := re.FindStringSubmatch(text)
		if len(m) > 1 {
			amountStr = m[1]
			break
		}
	}

	// 兜底：取最后一个独立数字
	if amountStr == "" {
		re := regexp.MustCompile(`(\d+\.?\d*)`)
		matches := re.FindAllStringSubmatch(text, -1)
		if len(matches) > 0 {
			amountStr = matches[len(matches)-1][1]
		}
	}

	if amountStr == "" {
		return 0, ""
	}

	amountFloat, err := strconv.ParseFloat(amountStr, 64)
	if err != nil || amountFloat <= 0 {
		return 0, ""
	}

	// 转为分
	amountCents := int64(math.Round(amountFloat * 100))

	// 2. 提取分类（Jieba 分词 + 数据库匹配）
	words := s.jieba.Cut(text, true)
	category := "其他"

	for _, word := range words {
		var ck models.CategoryKeyword
		if err := s.db.Where("keyword = ?", word).First(&ck).Error; err == nil {
			category = ck.Category
			break
		}
	}

	return amountCents, category
}

// AddTransaction 解析文本并创建一条交易记录
func (s *FinanceService) AddTransaction(userID int64, text string) (int64, string, error) {
	amount, category := s.ParseText(text)
	if amount == 0 {
		return 0, "", nil
	}

	tx := models.Transaction{
		UserID:   userID,
		Amount:   amount,
		Category: category,
		Note:     text,
		Date:     time.Now().Format("2006-01-02"),
	}

	return amount, category, s.db.Create(&tx).Error
}

// GetTransactions 获取用户的交易记录
func (s *FinanceService) GetTransactions(userID int64, limit int) ([]models.Transaction, error) {
	var items []models.Transaction
	err := s.db.Where("user_id = ? AND is_deleted = ?", userID, false).
		Order("id desc").Limit(limit).Find(&items).Error
	return items, err
}

// GetTransactionsByDate 获取用户指定日期的交易记录
func (s *FinanceService) GetTransactionsByDate(userID int64, date string) ([]models.Transaction, error) {
	var items []models.Transaction
	err := s.db.Where("user_id = ? AND date = ? AND is_deleted = ?", userID, date, false).
		Order("id desc").Find(&items).Error
	return items, err
}

// CategoryStat 分类统计结果
type CategoryStat struct {
	Category string
	Total    int64
	Count    int
}

// GetCategoryStats 获取用户指定日期范围的分类统计
func (s *FinanceService) GetCategoryStats(userID int64, dateFrom, dateTo string) ([]CategoryStat, error) {
	var stats []CategoryStat
	err := s.db.Model(&models.Transaction{}).
		Select("category, SUM(amount) as total, COUNT(*) as count").
		Where("user_id = ? AND date >= ? AND date <= ? AND is_deleted = ?", userID, dateFrom, dateTo, false).
		Group("category").
		Order("total desc").
		Find(&stats).Error
	return stats, err
}

// DailyStat 每日统计结果
type DailyStat struct {
	Date  string
	Total int64
	Count int
}

// GetDailyStats 获取用户指定日期范围的每日统计
func (s *FinanceService) GetDailyStats(userID int64, dateFrom, dateTo string) ([]DailyStat, error) {
	var stats []DailyStat
	err := s.db.Model(&models.Transaction{}).
		Select("date, SUM(amount) as total, COUNT(*) as count").
		Where("user_id = ? AND date >= ? AND date <= ? AND is_deleted = ?", userID, dateFrom, dateTo, false).
		Group("date").
		Order("date asc").
		Find(&stats).Error
	return stats, err
}
