import SwiftUI
import Testing
import UIKit
@testable import WebTerm

/// T-iPad-4 · Projects 大屏化的纯布局决策单测。判据是**设备 idiom + 可用宽度**
/// （单点，仿 `LayoutPolicy` 先例）——见 `ProjectsLayout` 注释解释为何用 idiom
/// 而非 size class（iPad 的 Projects 表单 sheet 内部恒 compact，与 iPhone 横屏
/// 无异，size class 无法在不回归 iPhone 的前提下区分二者）。
///
/// iPhone 零回归的可测护栏：`.phone` 分支必须与「现状」逐字节等价——列数恒
/// 为 1（现有单列 List）、不走网格、sheet detents 恒为 nil（不加修饰符 = 现有
/// 默认全高 sheet）。`.pad` 分支才是新增的大屏行为。
@Suite("ProjectsGridLayout column count (T-iPad-4)")
struct ProjectsGridLayoutTests {
    // MARK: - iPhone → 恒 1 列 / 不走网格（字节级不变）

    @Test(".phone → 恒 1 列，宽度无关（含横屏宽尺寸，现有单列 List 原样复用）")
    func phoneIsAlwaysSingleColumn() {
        #expect(ProjectsGridLayout.columnCount(availableWidth: 320, idiom: .phone) == 1)
        // iPhone 横屏很宽（~852）也绝不多列 —— 零回归的关键护栏。
        #expect(ProjectsGridLayout.columnCount(availableWidth: 852, idiom: .phone) == 1)
        #expect(ProjectsGridLayout.columnCount(availableWidth: 2000, idiom: .phone) == 1)
    }

    @Test(".phone 不走网格；.pad 走网格")
    func usesGridOnlyOnPad() {
        #expect(ProjectsGridLayout.usesGrid(idiom: .phone) == false)
        #expect(ProjectsGridLayout.usesGrid(idiom: .pad) == true)
    }

    // MARK: - iPad → 按可用宽度 1/2/3 列

    @Test(".pad 且窄于两列阈值 → 1 列（极窄 iPad 多任务，绝不挤压）")
    func padNarrowIsSingleColumn() {
        #expect(ProjectsGridLayout.columnCount(
            availableWidth: ProjectsGridLayout.twoColumnMinWidth - 1, idiom: .pad) == 1)
    }

    @Test(".pad 且在 [两列阈值, 三列阈值) → 2 列（表单 sheet 内宽即此档）")
    func padMediumIsTwoColumns() {
        #expect(ProjectsGridLayout.columnCount(
            availableWidth: ProjectsGridLayout.twoColumnMinWidth, idiom: .pad) == 2)
        #expect(ProjectsGridLayout.columnCount(
            availableWidth: ProjectsGridLayout.threeColumnMinWidth - 1, idiom: .pad) == 2)
    }

    @Test(".pad 且 >= 三列阈值 → 3 列（更宽面板/横屏全宽）")
    func padWideIsThreeColumns() {
        #expect(ProjectsGridLayout.columnCount(
            availableWidth: ProjectsGridLayout.threeColumnMinWidth, idiom: .pad) == 3)
        #expect(ProjectsGridLayout.columnCount(availableWidth: 1400, idiom: .pad) == 3)
    }

    @Test("列数恒 >= 1（任何宽度都不返回 0/负，防空网格崩溃）")
    func columnCountIsAlwaysPositive() {
        for width in stride(from: CGFloat(0), through: 2000, by: 137) {
            #expect(ProjectsGridLayout.columnCount(availableWidth: width, idiom: .pad) >= 1)
            #expect(ProjectsGridLayout.columnCount(availableWidth: width, idiom: .phone) == 1)
        }
    }
}

@Suite("ProjectsSheetSizing (T-iPad-4)")
struct ProjectsSheetSizingTests {
    @Test(".phone → nil（不加 detent 修饰符 = 现有默认全高 sheet，字节级不变）")
    func phoneIsNil() {
        #expect(ProjectsSheetSizing.detents(idiom: .phone) == nil)
    }

    @Test(".pad → [.medium, .large]（iPad 卡片式，不铺满大屏；仍可上拉到大）")
    func padIsCardDetents() {
        #expect(ProjectsSheetSizing.detents(idiom: .pad) == [.medium, .large])
    }
}
