"""
core.salary 단위 테스트 — 포괄임금제 외 시급 추정.
"""
import os
import sys

import pytest

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

from core.salary import estimate_pay, format_won


class TestEstimatePay:
    def test_zero_wage_returns_zero(self):
        out = estimate_pay([{'total_hours': 8, 'overtime_minutes': 30}], 0)
        assert out['base'] == 0
        assert out['overtime'] == 0
        assert out['total'] == 0

    def test_negative_wage_returns_zero(self):
        out = estimate_pay([{'total_hours': 8, 'overtime_minutes': 0}], -1000)
        assert out['total'] == 0

    def test_empty_records(self):
        out = estimate_pay([], 10000)
        assert out['base'] == 0
        assert out['overtime'] == 0
        assert out['total'] == 0

    def test_basic_8h_no_overtime(self):
        # 8h 정규 × 10000 = 80000
        out = estimate_pay([{'total_hours': 8.0, 'overtime_minutes': 0}], 10000)
        assert out['base'] == 80000
        assert out['overtime'] == 0
        assert out['total'] == 80000

    def test_8h_with_30min_overtime(self):
        # 정규 = 7.5h × 10000 = 75000
        # 연장 = 0.5h × 10000 × 1.5 = 7500
        out = estimate_pay(
            [{'total_hours': 8.0, 'overtime_minutes': 30}],
            hourly_wage=10000,
            overtime_rate=1.5,
        )
        assert out['base'] == pytest.approx(75000)
        assert out['overtime'] == pytest.approx(7500)
        assert out['total'] == pytest.approx(82500)

    def test_custom_overtime_rate(self):
        # 연장 = 1h × 10000 × 2.0 = 20000
        out = estimate_pay(
            [{'total_hours': 9.0, 'overtime_minutes': 60}],
            hourly_wage=10000,
            overtime_rate=2.0,
        )
        assert out['overtime'] == pytest.approx(20000)
        assert out['base'] == pytest.approx(80000)

    def test_aggregated_multiple_records(self):
        records = [
            {'total_hours': 8.0, 'overtime_minutes': 0},
            {'total_hours': 9.0, 'overtime_minutes': 60},
            {'total_hours': 8.5, 'overtime_minutes': 30},
        ]
        out = estimate_pay(records, hourly_wage=10000)
        # base_hours = 8 + 8 + 8 = 24h
        # overtime_hours = 0 + 1 + 0.5 = 1.5h
        assert out['base_hours'] == pytest.approx(24.0)
        assert out['overtime_hours'] == pytest.approx(1.5)
        assert out['base'] == pytest.approx(240000)
        assert out['overtime'] == pytest.approx(22500)  # 1.5 * 10000 * 1.5

    def test_missing_keys_default_zero(self):
        out = estimate_pay([{}], 10000)
        assert out['total'] == 0

    def test_overtime_minutes_zero_when_negative_total(self):
        # total - overtime이 음수가 되면 base는 0으로 클램프
        out = estimate_pay(
            [{'total_hours': 0.3, 'overtime_minutes': 60}],  # 0.3h - 1h = -0.7
            hourly_wage=10000,
        )
        assert out['base'] == 0
        assert out['overtime'] == pytest.approx(15000)


class TestFormatWon:
    @pytest.mark.parametrize("amount,expected", [
        (0, '0원'),
        (1000, '1,000원'),
        (1234567, '1,234,567원'),
        (999, '999원'),
        (82500.4, '82,500원'),  # round
        (82500.6, '82,501원'),
    ])
    def test_format(self, amount, expected):
        assert format_won(amount) == expected
