//
//  PaymentModelsTests.swift
//  suixinkanTests
//

import XCTest
@testable import suixinkan

/// 收款模型解码测试。
final class PaymentModelsTests: XCTestCase {
    func testPayPageConfigResponseDecodesBrandFields() throws {
        let json = """
        {
          "background": "https://example.com/background.png",
          "logo": "https://example.com/logo.png",
          "title": "那拉提旅拍管理收费平台",
          "subtitle": "那拉提景区"
        }
        """.data(using: .utf8)!

        let response = try JSONDecoder().decode(PayPageConfigResponse.self, from: json)

        XCTAssertEqual(response.background, "https://example.com/background.png")
        XCTAssertEqual(response.logo, "https://example.com/logo.png")
        XCTAssertEqual(response.title, "那拉提旅拍管理收费平台")
        XCTAssertEqual(response.subtitle, "那拉提景区")
    }

    func testPayPageConfigMergesOnlyUsableRemoteFields() {
        let cached = PayPageConfig(
            background: "https://cache.example.com/background.png",
            logo: "https://cache.example.com/logo.png",
            title: "缓存标题",
            subtitle: "缓存副标题"
        )

        let merged = cached.merging(
            PayPageConfigResponse(
                background: "",
                logo: "http://unsafe.example.com/logo.png",
                title: "  最新标题  ",
                subtitle: ""
            )
        )

        XCTAssertEqual(merged.background, cached.background)
        XCTAssertEqual(merged.logo, cached.logo)
        XCTAssertEqual(merged.title, "最新标题")
        XCTAssertEqual(merged.subtitle, cached.subtitle)
    }

    func testPayPageBrandingOnlyEnablesNalatiScenicId() {
        XCTAssertTrue(PayPageBrandingPolicy.isNalati(scenicId: 128))
        XCTAssertFalse(PayPageBrandingPolicy.isNalati(scenicId: 127))
        XCTAssertFalse(PayPageBrandingPolicy.isNalati(scenicId: 0))
    }

    func testPaymentAccountDisplayFormatterUsesCurrentPhotographerAndAllUniqueStores() {
        XCTAssertEqual(
            PaymentAccountDisplayFormatter.photographerName(userName: " 当前摄影师 ", realName: "实名"),
            "当前摄影师"
        )
        XCTAssertEqual(
            PaymentAccountDisplayFormatter.storeNames(["一号店", " 二号店 ", "一号店", ""]),
            "一号店、二号店"
        )
        XCTAssertEqual(PaymentAccountDisplayFormatter.storeNames([]), "-")
    }

    func testRolePermissionResponseDecodesAllAccountStores() throws {
        let json = """
        {
          "role": {
            "id": 41,
            "name": "摄影师",
            "role_code": "photographer",
            "notes": null,
            "permission": []
          },
          "scenic": [],
          "store": [
            {"id": 37, "name": "随心旅拍", "status": 1},
            {"id": 38, "name": "空中草原店", "status": 1}
          ]
        }
        """.data(using: .utf8)!

        let response = try JSONDecoder().decode(RolePermissionResponse.self, from: json)

        XCTAssertEqual(response.store.map(\.name), ["随心旅拍", "空中草原店"])
    }

    func testPayCodeResponseDecodesSnakeCaseFields() throws {
        let json = """
        {
          "static_pay_url": "https://pay.example.com/static",
          "dynamic_pay_url": "https://pay.example.com/dynamic"
        }
        """.data(using: .utf8)!

        let response = try JSONDecoder().decode(PayCodeResponse.self, from: json)

        XCTAssertEqual(response.staticPayURL, "https://pay.example.com/static")
        XCTAssertEqual(response.dynamicPayURL, "https://pay.example.com/dynamic")
    }

    func testRepaymentCollectionRecordResponseDecodesGroupedFields() throws {
        let json = """
        {
          "analyse": [
            {
              "date": "2024-01-15",
              "order_count": 2,
              "order_amount_sum": "100.00"
            }
          ],
          "list": [
            {
              "order_number": "NO001",
              "user_phone": "13800138000",
              "order_amount": "50.00",
              "create_date": "2024-01-15",
              "create_time": "10:00:00"
            }
          ]
        }
        """.data(using: .utf8)!

        let response = try JSONDecoder().decode(RepaymentCollectionRecordResponse.self, from: json)

        XCTAssertEqual(response.analyse.count, 1)
        XCTAssertEqual(response.analyse[0].orderCount, 2)
        XCTAssertEqual(response.list[0].orderNumber, "NO001")
    }
}
