package service

import (
	"errors"
	"fmt"
	"time"
	"wails-app/internal/dao"
	"wails-app/internal/global"
	"wails-app/internal/modules/shift/repository"
)

type ShiftService struct {
	repo *repository.ShiftRepository
}

func NewShiftService() *ShiftService {
	return &ShiftService{repo: &repository.ShiftRepository{}}
}

func (s *ShiftService) Start(operatorID uint, startingCash float64) (*dao.ShiftRecord, error) {
	active, _ := s.repo.GetActive(operatorID)
	if active != nil {
		return nil, errors.New("已有当班记录，请先交班")
	}
	rec := &dao.ShiftRecord{
		OperatorID: operatorID, StartTime: time.Now(),
		StartingCash: startingCash, Status: "active",
	}
	if err := s.repo.Create(rec); err != nil {
		return nil, err
	}
	return rec, nil
}

func (s *ShiftService) End(operatorID uint, actualCash float64, remark string) (*dao.ShiftRecord, error) {
	active, err := s.repo.GetActive(operatorID)
	if err != nil {
		return nil, errors.New("无当班记录")
	}

	var collected float64
	global.GVA_DB.Raw("SELECT COALESCE(SUM(amount),0) FROM payment_record WHERE payment_method='cash' AND operator_id = ? AND paid_at >= ? AND paid_at < ?",
		operatorID, active.StartTime, time.Now()).Scan(&collected)

	now := time.Now()
	expected := active.StartingCash + collected
	diff := actualCash - expected
	active.EndTime = &now
	active.CollectedCash = collected
	active.ExpectedTotal = expected
	active.ActualTotal = actualCash
	active.Difference = diff
	active.Status = "closed"
	active.Remark = remark
	if err := s.repo.Update(active); err != nil {
		return nil, err
	}
	fmt.Printf("交班: 接班%.2f+当班%.2f=应交%.2f 实交%.2f 差异%.2f\n",
		active.StartingCash, collected, expected, actualCash, diff)
	return active, nil
}

func (s *ShiftService) GetCurrent(operatorID uint) (*dao.ShiftRecord, error) {
	rec, err := s.repo.GetActive(operatorID)
	if err != nil {
		return nil, err
	}
	// 实时统计当班现金收款
	var collected float64
	global.GVA_DB.Raw("SELECT COALESCE(SUM(amount),0) FROM payment_record WHERE payment_method='cash' AND operator_id = ? AND paid_at >= ?",
		operatorID, rec.StartTime).Scan(&collected)
	rec.CollectedCash = collected
	return rec, nil
}

func (s *ShiftService) List(q repository.ShiftListQuery, operatorID uint) ([]repository.ShiftListItem, int64, error) {
	return s.repo.List(q, operatorID)
}
