//
//  OrderRefundDialogValidationTests.swift
//  suixinkanTests
//

import XCTest
@testable import suixinkan

final class OrderRefundDialogValidationTests: XCTestCase {

    func testPhotographerOrderRequiresRefundReason() {
        let result = OrderRefundDialogValidation.validate(
            kind: .photographerOrder,
            mode: .full,
            amountText: "",
            reason: "",
            fullRefundAmount: "88.00",
            maxRefundAmount: "88.00"
        )

        XCTAssertEqual(failureMessage(from: result), "请输入退款原因")
    }

    func testPhotographerPartialRefundRequiresAmount() {
        let result = OrderRefundDialogValidation.validate(
            kind: .photographerOrder,
            mode: .partial,
            amountText: "",
            reason: "用户申请退款",
            fullRefundAmount: "88.00",
            maxRefundAmount: "88.00"
        )

        XCTAssertEqual(failureMessage(from: result), "请输入退款金额")
    }

    func testStoreOrderRefundReasonLengthValidation() {
        let shortResult = OrderRefundDialogValidation.validate(
            kind: .storeOrder,
            mode: .full,
            amountText: "",
            reason: "太短",
            fullRefundAmount: "0",
            maxRefundAmount: "99.00"
        )
        XCTAssertEqual(failureMessage(from: shortResult), "退款原因至少5个字符")

        let longResult = OrderRefundDialogValidation.validate(
            kind: .storeOrder,
            mode: .full,
            amountText: "",
            reason: String(repeating: "a", count: 256),
            fullRefundAmount: "0",
            maxRefundAmount: "99.00"
        )
        XCTAssertEqual(failureMessage(from: longResult), "退款原因最多255个字符")
    }

    func testStoreOrderPartialRefundAmountValidation() {
        let emptyResult = OrderRefundDialogValidation.validate(
            kind: .storeOrder,
            mode: .partial,
            amountText: "",
            reason: "用户申请退款",
            fullRefundAmount: "0",
            maxRefundAmount: "99.00"
        )
        XCTAssertEqual(failureMessage(from: emptyResult), "请输入退款金额")

        let invalidResult = OrderRefundDialogValidation.validate(
            kind: .storeOrder,
            mode: .partial,
            amountText: "0",
            reason: "用户申请退款",
            fullRefundAmount: "0",
            maxRefundAmount: "99.00"
        )
        XCTAssertEqual(failureMessage(from: invalidResult), "请输入有效的退款金额")

        let overflowResult = OrderRefundDialogValidation.validate(
            kind: .storeOrder,
            mode: .partial,
            amountText: "100.00",
            reason: "用户申请退款",
            fullRefundAmount: "0",
            maxRefundAmount: "99.00"
        )
        XCTAssertEqual(failureMessage(from: overflowResult), "退款金额不能大于实际支付金额")
    }

    func testStoreOrderFullRefundUsesZeroAmount() throws {
        let result = OrderRefundDialogValidation.validate(
            kind: .storeOrder,
            mode: .full,
            amountText: "99.00",
            reason: "用户申请退款",
            fullRefundAmount: "0",
            maxRefundAmount: "99.00"
        )

        let payload = try successPayload(from: result)
        XCTAssertEqual(payload.refundType, OrderRefundMode.full.rawValue)
        XCTAssertEqual(payload.refundAmount, "0")
        XCTAssertEqual(payload.refundReason, "用户申请退款")
    }

    func testMoneyInputKeepsSingleDotAndTwoDecimalPlaces() {
        XCTAssertEqual(OrderRefundDialogValidation.filterMoneyInput("12..345a6", maxLength: 10), "12.34")
        XCTAssertEqual(OrderRefundDialogValidation.filterMoneyInput("12345678901", maxLength: 10), "1234567890")
    }

    private func failureMessage(from result: Result<OrderRefundDialogPayload, OrderRefundDialogValidationError>) -> String? {
        if case .failure(let error) = result {
            return error.message
        }
        return nil
    }

    private func successPayload(
        from result: Result<OrderRefundDialogPayload, OrderRefundDialogValidationError>
    ) throws -> OrderRefundDialogPayload {
        switch result {
        case .success(let payload):
            return payload
        case .failure(let error):
            XCTFail("Expected success, got failure: \(error.message)")
            throw NSError(domain: "OrderRefundDialogValidationTests", code: 1)
        }
    }
}
