import XCTest
@testable import PortfolioJournal

final class MonthlyCheckInStoreTests: XCTestCase {
    override func setUp() {
        super.setUp()
        MonthlyCheckInStore.clearAll()
    }

    override func tearDown() {
        MonthlyCheckInStore.clearAll()
        super.tearDown()
    }

    func testEffectiveMonthUsesPreviousMonthWithinGracePeriod() {
        let calendar = Calendar(identifier: .gregorian)
        let referenceDate = calendar.date(from: DateComponents(year: 2026, month: 2, day: 20))!
        let effective = MonthlyCheckInStore.effectiveMonth(for: referenceDate, relativeTo: referenceDate, graceDays: 20)

        let expected = calendar.date(from: DateComponents(year: 2026, month: 1, day: 1))!
        XCTAssertEqual(effective, expected)
    }

    func testEffectiveMonthUsesCurrentMonthAfterGracePeriod() {
        let calendar = Calendar(identifier: .gregorian)
        let referenceDate = calendar.date(from: DateComponents(year: 2026, month: 2, day: 21))!
        let effective = MonthlyCheckInStore.effectiveMonth(for: referenceDate, relativeTo: referenceDate, graceDays: 20)

        let expected = calendar.date(from: DateComponents(year: 2026, month: 2, day: 1))!
        XCTAssertEqual(effective, expected)
    }

    func testCompletionAfterGraceAutoFillsMissingMonths() {
        let calendar = Calendar(identifier: .gregorian)
        let decemberDate = calendar.date(from: DateComponents(year: 2025, month: 12, day: 15))!
        let decemberCompletion = calendar.date(from: DateComponents(year: 2025, month: 12, day: 31))!
        MonthlyCheckInStore.setNote("Carry", for: decemberDate)
        MonthlyCheckInStore.setRating(4, for: decemberDate)
        MonthlyCheckInStore.setMood(.balanced, for: decemberDate)
        MonthlyCheckInStore.setCompletionDate(decemberCompletion, for: decemberDate)

        let completionDate = calendar.date(from: DateComponents(year: 2026, month: 2, day: 21))!
        MonthlyCheckInStore.setCompletionDate(completionDate, for: completionDate)

        let januaryDate = calendar.date(from: DateComponents(year: 2026, month: 1, day: 5))!
        let januaryEntry = MonthlyCheckInStore.entry(for: januaryDate)
        XCTAssertEqual(januaryEntry?.note, "Carry")
        XCTAssertEqual(januaryEntry?.rating, 4)
        XCTAssertEqual(januaryEntry?.mood, .balanced)
        XCTAssertNotNil(januaryEntry?.completionDate)
    }

    func testSetCompletionDateForVeryOldMonthStillCompletesEntry() {
        let calendar = Calendar(identifier: .gregorian)
        let oldMonthDate = calendar.date(from: DateComponents(year: 2024, month: 1, day: 10))!
        let completionDate = calendar.date(from: DateComponents(year: 2026, month: 2, day: 22))!

        MonthlyCheckInStore.setCompletionDate(completionDate, for: oldMonthDate)

        let entry = MonthlyCheckInStore.entry(for: oldMonthDate)
        XCTAssertNotNil(entry?.completionDate)
    }
}
