"""연장근무 자동 적립 가드 테스트.

auto_overtime(자동 적립)가 OFF면, 자동 퇴근 경로(근무일 경계 롤오버 등)에서도
은행 적립을 하지 않아야 한다 — clock_out() 대화상자에서 '아니오'를 고른 것과 동일한 의미.

handle_workday_rollover는 위젯 의존이 tail(load_today_data/update_overtime_balance)뿐이라,
__new__로 만든 인스턴스에 필요한 속성만 채워 단위 테스트한다 (QApplication 불필요).
"""
import os
import sys
from datetime import datetime, timedelta, time as dtime

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from core.database import Database
from core.time_calculator import TimeCalculator
from ui.main_window import MainWindow


def _rollover_balance(db, monkeypatch):
    """어제 미퇴근 상태에서 근무일 경계 롤오버를 실행하고 적립 잔액을 반환."""
    from PyQt5.QtWidgets import QMessageBox
    monkeypatch.setattr(QMessageBox, 'information',
                        staticmethod(lambda *a, **k: QMessageBox.Ok))

    today = datetime.now().date()
    y = today - timedelta(days=1)
    db.add_work_record(y.isoformat(), '09:00:00', is_manual=True)  # 어제: 미퇴근

    w = MainWindow.__new__(MainWindow)  # __init__ 우회 (위젯/타이머 없음)
    w.db = db
    w.time_calc = TimeCalculator(work_minutes=480)
    w.clock_in_time = datetime.combine(y, dtime(9, 0, 0))
    w.is_clocked_in = True
    w.midnight_rollover_handled = False
    w.is_on_break = False
    w.lunch_break_enabled = False
    w.dinner_break_enabled = False
    w.load_today_data = lambda: None           # tail UI refresh stub
    w.update_overtime_balance = lambda: None   # tail UI refresh stub

    w.handle_workday_rollover(datetime.combine(today, dtime(7, 0, 0)))
    return db.get_total_overtime_balance()


def test_rollover_does_not_accrue_when_auto_overtime_off(tmp_path, monkeypatch):
    db = Database(str(tmp_path / 'off.db'))
    db.set_setting('auto_overtime', 'false')
    assert _rollover_balance(db, monkeypatch) == 0


def test_rollover_accrues_when_auto_overtime_on(tmp_path, monkeypatch):
    db = Database(str(tmp_path / 'on.db'))
    db.set_setting('auto_overtime', 'true')
    assert _rollover_balance(db, monkeypatch) > 0


def test_delete_overtime_earned_reduces_balance(tmp_path):
    """적립(은행) 기록 삭제 시 잔액이 그만큼 감소한다."""
    from datetime import date
    db = Database(str(tmp_path / 'del.db'))
    today = date.today().isoformat()
    db.add_overtime_earned(None, 90, today)
    assert db.get_total_overtime_balance() == 90

    bank_id = db.get_connection().execute(
        'SELECT id FROM overtime_bank').fetchone()[0]
    assert db.delete_overtime_earned(bank_id) is True
    assert db.get_total_overtime_balance() == 0

    # 없는 id 삭제는 False
    assert db.delete_overtime_earned(999999) is False
