//
//  RoadMapModels.swift
//  Baccarat
//
//  Models for Baccarat road map displays including Big Road and derived roads.
//

import Foundation
import SwiftUI

// MARK: - Road Types

/// The available road map display types.
enum RoadType: String, CaseIterable, Identifiable, Codable {
    case bead = "bead"
    case big = "big"
    case bigEyeBoy = "bigEyeBoy"
    case smallRoad = "smallRoad"
    case cockroachPig = "cockroachPig"
    
    var id: String { rawValue }
    
    /// Localized display name for the road type.
    var displayName: String {
        switch self {
        case .bead: return String(localized: "Bead Road")
        case .big: return String(localized: "Big Road")
        case .bigEyeBoy: return String(localized: "Big Eye Boy")
        case .smallRoad: return String(localized: "Small Road")
        case .cockroachPig: return String(localized: "Cockroach Pig")
        }
    }
    
    /// Short description for tooltips.
    var shortDescription: String {
        switch self {
        case .bead:
            return String(localized: "Simple grid showing all results in order.")
        case .big:
            return String(localized: "Shows streaks. New column when winner changes.")
        case .bigEyeBoy:
            return String(localized: "Compares current streak to previous. Red = repeating pattern.")
        case .smallRoad:
            return String(localized: "Like Big Eye Boy, but looks 2 columns back.")
        case .cockroachPig:
            return String(localized: "Finest pattern detection. Looks 3 columns back.")
        }
    }
    
    /// Icon for the road type.
    var icon: String {
        switch self {
        case .bead: return "circle.grid.3x3"
        case .big: return "chart.bar.xaxis"
        case .bigEyeBoy: return "eye.fill"
        case .smallRoad: return "road.lanes"
        case .cockroachPig: return "ant.fill"
        }
    }
    
    /// Whether this is a derived road (Big Eye Boy, Small Road, Cockroach Pig).
    var isDerived: Bool {
        switch self {
        case .bead, .big: return false
        case .bigEyeBoy, .smallRoad, .cockroachPig: return true
        }
    }
    
    /// The column offset used for derived road calculations.
    /// Big Eye Boy compares to 1 column back, Small Road to 2, Cockroach Pig to 3.
    var columnOffset: Int {
        switch self {
        case .bead, .big: return 0
        case .bigEyeBoy: return 1
        case .smallRoad: return 2
        case .cockroachPig: return 3
        }
    }
    
    /// The starting column requirement for derived roads.
    /// Big Eye Boy starts after column 2, Small Road after column 3, Cockroach Pig after column 4.
    var startingColumn: Int {
        switch self {
        case .bead, .big: return 1
        case .bigEyeBoy: return 2
        case .smallRoad: return 3
        case .cockroachPig: return 4
        }
    }
}

// MARK: - Big Road Entry

/// An entry in the Big Road grid.
/// Represents a single result positioned in the column-based streak layout.
struct BigRoadEntry: Identifiable, Equatable {
    let id: UUID
    
    /// The game result (Player wins or Banker wins).
    /// Ties are tracked separately via `tieCount`.
    let result: GameResult
    
    /// The column position (0-indexed).
    let column: Int
    
    /// The row position (0-indexed, 0 is top).
    let row: Int
    
    /// Number of ties that occurred after this result.
    let tieCount: Int
    
    /// Whether this result was a natural (8 or 9).
    let isNatural: Bool
    
    /// Whether a pair occurred in this hand.
    let hasPair: Bool
    
    /// The original round result for additional data access.
    let roundResult: RoundResult?
    
    init(
        id: UUID = UUID(),
        result: GameResult,
        column: Int,
        row: Int,
        tieCount: Int = 0,
        isNatural: Bool = false,
        hasPair: Bool = false,
        roundResult: RoundResult? = nil
    ) {
        self.id = id
        self.result = result
        self.column = column
        self.row = row
        self.tieCount = tieCount
        self.isNatural = isNatural
        self.hasPair = hasPair
        self.roundResult = roundResult
    }
    
    // MARK: - Equatable (custom implementation excluding roundResult)
    
    static func == (lhs: BigRoadEntry, rhs: BigRoadEntry) -> Bool {
        lhs.id == rhs.id &&
        lhs.result == rhs.result &&
        lhs.column == rhs.column &&
        lhs.row == rhs.row &&
        lhs.tieCount == rhs.tieCount &&
        lhs.isNatural == rhs.isNatural &&
        lhs.hasPair == rhs.hasPair
    }
    
    /// The color for this entry based on the result.
    var color: Color {
        result.color
    }
    
    /// Label for display (P or B).
    var label: String {
        switch result {
        case .playerWins: return "P"
        case .bankerWins: return "B"
        case .tie: return "T"
        }
    }
}

// MARK: - Derived Road Entry

/// An entry in a derived road (Big Eye Boy, Small Road, or Cockroach Pig).
/// Uses hollow circles: red indicates pattern repeating, blue indicates pattern breaking.
struct DerivedRoadEntry: Identifiable, Equatable {
    let id: UUID
    
    /// Whether this entry is red (pattern repeating) or blue (pattern breaking).
    let isRed: Bool
    
    /// The column position (0-indexed).
    let column: Int
    
    /// The row position (0-indexed, 0 is top).
    let row: Int
    
    init(
        id: UUID = UUID(),
        isRed: Bool,
        column: Int,
        row: Int
    ) {
        self.id = id
        self.isRed = isRed
        self.column = column
        self.row = row
    }
    
    /// The color for this entry.
    var color: Color {
        isRed ? .red : .blue
    }
}

// MARK: - Big Road Column

/// A column in the Big Road, containing multiple entries.
/// Used internally by the road map builder for layout calculations.
struct BigRoadColumn: Identifiable, Equatable {
    let id: UUID
    
    /// The column index (0-indexed).
    let index: Int
    
    /// The entries in this column (top to bottom).
    var entries: [BigRoadEntry]
    
    /// The result type for this column (all entries have the same result).
    var result: GameResult? {
        entries.first?.result
    }
    
    /// The depth (number of entries) in this column.
    var depth: Int {
        entries.count
    }
    
    init(id: UUID = UUID(), index: Int, entries: [BigRoadEntry] = []) {
        self.id = id
        self.index = index
        self.entries = entries
    }
}
