//
//  ErrorMessageParserTests.swift
//  honeyDueTests
//
//  Unit tests for ErrorMessageParser error code mapping, network error detection,
//  and message parsing logic.
//

import Testing
@testable import honeyDue

// MARK: - API Error Code Mapping Tests

struct ErrorCodeMappingTests {

    @Test func invalidCredentialsCode() {
        let result = ErrorMessageParser.parse("error.invalid_credentials")
        #expect(result == "Invalid username or password. Please try again.")
    }

    @Test func invalidTokenCode() {
        let result = ErrorMessageParser.parse("error.invalid_token")
        #expect(result == "Your session has expired. Please log in again.")
    }

    @Test func usernameTakenCode() {
        let result = ErrorMessageParser.parse("error.username_taken")
        #expect(result == "This username is already taken. Please choose another.")
    }

    @Test func emailTakenCode() {
        let result = ErrorMessageParser.parse("error.email_taken")
        #expect(result == "This email is already registered. Try logging in instead.")
    }

    @Test func invalidVerificationCodeCode() {
        let result = ErrorMessageParser.parse("error.invalid_verification_code")
        #expect(result == "Invalid verification code. Please check and try again.")
    }

    @Test func verificationCodeExpiredCode() {
        let result = ErrorMessageParser.parse("error.verification_code_expired")
        #expect(result == "Your verification code has expired. Please request a new one.")
    }

    @Test func rateLimitExceededCode() {
        let result = ErrorMessageParser.parse("error.rate_limit_exceeded")
        #expect(result == "Too many attempts. Please wait a few minutes and try again.")
    }

    @Test func tooManyRequestsCode() {
        let result = ErrorMessageParser.parse("error.too_many_requests")
        #expect(result == "Too many requests. Please try again later.")
    }

    @Test func taskNotFoundCode() {
        let result = ErrorMessageParser.parse("error.task_not_found")
        #expect(result == "Task not found. It may have been deleted.")
    }

    @Test func residenceNotFoundCode() {
        let result = ErrorMessageParser.parse("error.residence_not_found")
        #expect(result == "Property not found. It may have been deleted.")
    }

    @Test func accessDeniedCode() {
        let result = ErrorMessageParser.parse("error.access_denied")
        #expect(result == "You don't have permission for this action.")
    }

    @Test func shareCodeInvalidCode() {
        let result = ErrorMessageParser.parse("error.share_code_invalid")
        #expect(result == "Invalid share code. Please check and try again.")
    }

    @Test func propertiesLimitReachedCode() {
        let result = ErrorMessageParser.parse("error.properties_limit_reached")
        #expect(result == "You've reached your property limit. Upgrade to add more.")
    }

    @Test func internalErrorCode() {
        let result = ErrorMessageParser.parse("error.internal")
        #expect(result == "Something went wrong. Please try again.")
    }

    @Test func titleRequiredCode() {
        let result = ErrorMessageParser.parse("error.title_required")
        #expect(result == "Title is required.")
    }
}

// MARK: - Unknown Error Code Tests

struct UnknownErrorCodeTests {

    @Test func unknownErrorCodeGeneratesMessage() {
        let result = ErrorMessageParser.parse("error.some_new_error")
        #expect(result == "Some new error. Please try again.")
    }

    @Test func unknownErrorCodeWithSingleWord() {
        let result = ErrorMessageParser.parse("error.forbidden")
        #expect(result == "Forbidden. Please try again.")
    }
}

// MARK: - Network Error Pattern Tests

struct NetworkErrorPatternTests {

    @Test func offlineErrorDetected() {
        let result = ErrorMessageParser.parse("The Internet connection appears to be offline")
        #expect(result == "No internet connection. Please check your network.")
    }

    @Test func timeoutErrorDetected() {
        let result = ErrorMessageParser.parse("The request timed out")
        #expect(result == "Request timed out. Please try again.")
    }

    @Test func connectionLostDetected() {
        let result = ErrorMessageParser.parse("The network connection was lost")
        #expect(result == "Connection lost. Please try again.")
    }

    @Test func sslErrorDetected() {
        let result = ErrorMessageParser.parse("An SSL error has occurred")
        #expect(result == "Secure connection failed. Please try again.")
    }

    @Test func nsUrlErrorCodeDetected() {
        let result = ErrorMessageParser.parse("Error Code=-1009 in domain NSURLErrorDomain")
        #expect(result.contains("internet") || result.contains("connect"))
    }

    @Test func connectionRefusedDetected() {
        let result = ErrorMessageParser.parse("Connection refused")
        #expect(result == "Unable to connect. The server may be temporarily unavailable.")
    }

    @Test func socketTimeoutDetected() {
        let result = ErrorMessageParser.parse("SocketTimeoutException: connect timed out")
        #expect(result == "Request timed out. Please try again.")
    }

    @Test func tooManyRequestsDetected() {
        let result = ErrorMessageParser.parse("Too many requests. Please try again later.")
        #expect(result == "Too many requests. Please try again later.")
    }

    @Test func tooManyRequestsWithRetryAfterDetected() {
        let result = ErrorMessageParser.parse("Too many requests. Please try again in 30 seconds.")
        #expect(result.contains("Too many requests"))
    }
}

// MARK: - Technical Error Detection Tests

struct TechnicalErrorDetectionTests {

    @Test func stackTraceDetected() {
        let result = ErrorMessageParser.parse("java.lang.NullPointerException at com.example.App.method(App.kt:42)")
        #expect(result == "Something went wrong. Please try again.")
    }

    @Test func swiftErrorDetected() {
        let result = ErrorMessageParser.parse("Fatal error in module.swift:123")
        #expect(result == "Something went wrong. Please try again.")
    }

    @Test func kotlinErrorDetected() {
        let result = ErrorMessageParser.parse("Exception at kotlin.coroutines.ContinuationKt.kt:55")
        #expect(result == "Something went wrong. Please try again.")
    }

    @Test func nsErrorDomainDetected() {
        let result = ErrorMessageParser.parse("Error Domain=NSURLErrorDomain Code=-1001 UserInfo={NSLocalizedDescription=timed out}")
        #expect(result != "Error Domain=NSURLErrorDomain Code=-1001 UserInfo={NSLocalizedDescription=timed out}")
    }
}

// MARK: - JSON Error Parsing Tests

struct JSONErrorParsingTests {

    @Test func jsonWithErrorFieldParsed() {
        let json = #"{"error": "error.invalid_credentials"}"#
        let result = ErrorMessageParser.parse(json)
        #expect(result == "Invalid username or password. Please try again.")
    }

    @Test func jsonWithMessageFieldParsed() {
        let json = #"{"message": "Something went wrong"}"#
        let result = ErrorMessageParser.parse(json)
        #expect(result == "Something went wrong")
    }

    @Test func jsonWithDetailFieldParsed() {
        let json = #"{"detail": "Not authorized"}"#
        let result = ErrorMessageParser.parse(json)
        #expect(result == "Not authorized")
    }

    @Test func jsonWithDataObjectReturnsGeneric() {
        let json = #"{"id": 1, "title": "Test"}"#
        let result = ErrorMessageParser.parse(json)
        #expect(result == "Request failed. Please check your input and try again.")
    }

    @Test func invalidJsonReturnsGeneric() {
        let json = #"{malformed json"#
        let result = ErrorMessageParser.parse(json)
        #expect(result == "An error occurred. Please try again.")
    }
}

// MARK: - User-Friendly Message Tests

struct UserFriendlyMessageTests {

    @Test func shortReadableMessagePassedThrough() {
        let result = ErrorMessageParser.parse("Invalid email address")
        #expect(result == "Invalid email address")
    }

    @Test func emptyStringReturnsSelf() {
        // Empty/whitespace strings pass through the parser's user-friendly check
        let result = ErrorMessageParser.parse("")
        #expect(result == "")
    }

    @Test func whitespaceOnlyReturnsTrimmed() {
        let result = ErrorMessageParser.parse("   ")
        #expect(result == "")
    }
}
