package service

import (
	"testing"
	"time"
)

func TestDepreciationScheduleDay_UsesHouseTypeOffsets(t *testing.T) {
	openOrigin := mustDepreciationDate(t, "2026-01-01")
	if got := DepreciationScheduleDay(openOrigin, mustDepreciationDate(t, "2026-06-24"), "open_house"); got != 0 {
		t.Fatalf("expected open house day before start to be 0, got %d", got)
	}
	if got := DepreciationScheduleDay(openOrigin, mustDepreciationDate(t, "2026-06-25"), "open_house"); got != 1 {
		t.Fatalf("expected open house start day to map to schedule day 1, got %d", got)
	}

	closeOrigin := mustDepreciationDate(t, "2026-01-01")
	if got := DepreciationScheduleDay(closeOrigin, mustDepreciationDate(t, "2026-06-03"), "close_house"); got != 0 {
		t.Fatalf("expected close house day before start to be 0, got %d", got)
	}
	if got := DepreciationScheduleDay(closeOrigin, mustDepreciationDate(t, "2026-06-04"), "close_house"); got != 1 {
		t.Fatalf("expected close house start day to map to schedule day 1, got %d", got)
	}
}

func TestCalculateDepreciationAtDayN_UsesRemainingBasisRecursively(t *testing.T) {
	percentByHouseType := map[string]map[int]float64{
		"close_house": {
			1: 10,
			2: 20,
		},
	}

	pulletCostDayN, depreciationValue, depreciationPercent := CalculateDepreciationAtDayN(1000, 2, "close_house", percentByHouseType)
	if pulletCostDayN != 900 {
		t.Fatalf("expected remaining basis entering day 2 to be 900, got %v", pulletCostDayN)
	}
	if depreciationValue != 180 {
		t.Fatalf("expected day 2 depreciation to be 180, got %v", depreciationValue)
	}
	if depreciationPercent != 20 {
		t.Fatalf("expected day 2 depreciation percent to be 20, got %v", depreciationPercent)
	}
}

func TestCalculateDepreciationFromDayRange_StartsFromProvidedScheduleDay(t *testing.T) {
	percentByHouseType := map[string]map[int]float64{
		"close_house": {
			1: 10,
			2: 20,
			3: 5,
		},
	}

	pulletCostDayN, depreciationValue, depreciationPercent := CalculateDepreciationFromDayRange(1000, 2, 3, "close_house", percentByHouseType)
	if pulletCostDayN != 800 {
		t.Fatalf("expected remaining basis entering day 3 to be 800, got %v", pulletCostDayN)
	}
	if depreciationValue != 40 {
		t.Fatalf("expected day 3 depreciation to be 40, got %v", depreciationValue)
	}
	if depreciationPercent != 5 {
		t.Fatalf("expected day 3 depreciation percent to be 5, got %v", depreciationPercent)
	}
}

func mustDepreciationDate(t *testing.T, raw string) time.Time {
	t.Helper()

	location, err := time.LoadLocation("Asia/Jakarta")
	if err != nil {
		t.Fatalf("failed loading timezone: %v", err)
	}

	value, err := time.ParseInLocation("2006-01-02", raw, location)
	if err != nil {
		t.Fatalf("failed parsing date %q: %v", raw, err)
	}

	return value
}
