import UIKit

// MARK: - Layout Params

/// Parameters for layout calculation (screen width, insets).
/// Telegram equivalent: `ListViewItemLayoutParams`.
struct RosettaListLayoutParams: Sendable {
    let width: CGFloat
    let leftInset: CGFloat
    let rightInset: CGFloat
}

// MARK: - Node Layout

/// Calculated layout result — content size + insets.
/// Telegram equivalent: `ListViewItemNodeLayout`.
struct RosettaListNodeLayout {
    let contentSize: CGSize
    let insets: UIEdgeInsets

    var size: CGSize {
        CGSize(
            width: contentSize.width + insets.left + insets.right,
            height: contentSize.height + insets.top + insets.bottom
        )
    }
}

// MARK: - Update Animation

/// Animation type for node updates.
/// Telegram equivalent: `ListViewItemUpdateAnimation`.
enum RosettaListUpdateAnimation {
    case none
    case system(duration: Double, transition: ControlledTransitionConfig)
}

struct ControlledTransitionConfig {
    let duration: Double
    let curve: AnimationCurve

    enum AnimationCurve {
        case spring(damping: CGFloat)
        case easeInOut
    }

    static let `default` = ControlledTransitionConfig(
        duration: 0.4,
        curve: .spring(damping: 0.78)
    )
}

// MARK: - Direction Hint

/// Hint for insertion/deletion animation direction.
/// Telegram equivalent: `ListViewItemOperationDirectionHint`.
enum RosettaListDirectionHint {
    case up
    case down
}

// MARK: - Scroll Position

/// Target scroll position for programmatic scrolling.
/// Telegram equivalent: `ListViewScrollPosition`.
enum RosettaListScrollPosition {
    case top(CGFloat)
    case center
    case bottom(CGFloat)
    case visible
}

// MARK: - List Item Protocol

/// Data model protocol for list items.
/// Telegram equivalent: `ListViewItem` (ListViewItem.swift:72-106).
///
/// Two-phase async layout pattern:
/// 1. `nodeConfiguredForParams` — creates node + calculates layout on background
/// 2. Completion delivers ready-to-display node + layout to main thread
protocol RosettaListItem: AnyObject {
    /// Unique identifier for diffing.
    var id: String { get }

    /// Estimated height before layout calculation. Used for scroll position
    /// estimation when exact layout isn't ready yet.
    /// Telegram: `approximateHeight` property.
    var approximateHeight: CGFloat { get }

    /// Reuse identifier for node pool recycling.
    var reuseIdentifier: String { get }

    /// Create a new node and calculate its layout.
    /// `async` closure schedules work on background queue.
    /// Telegram: `nodeConfiguredForParams` (ListViewItem.swift:72-75).
    func nodeConfiguredForParams(
        async: @escaping (@escaping () -> Void) -> Void,
        params: RosettaListLayoutParams,
        previousItem: RosettaListItem?,
        nextItem: RosettaListItem?,
        completion: @escaping (RosettaListNode, RosettaListNodeLayout) -> Void
    )

    /// Update an existing (recycled) node with new data.
    /// Telegram: `updateNode` (ListViewItem.swift:78-88).
    func updateNode(
        async: @escaping (@escaping () -> Void) -> Void,
        node: RosettaListNode,
        params: RosettaListLayoutParams,
        previousItem: RosettaListItem?,
        nextItem: RosettaListItem?,
        animation: RosettaListUpdateAnimation,
        completion: @escaping (RosettaListNodeLayout) -> Void
    )
}

// MARK: - Insert/Delete/Update Operations

/// Batch operations for list updates.
/// Telegram equivalent: `ListViewInsertItem`, `ListViewDeleteItem`, `ListViewUpdateItem`.

struct RosettaListInsertItem {
    let index: Int
    let previousIndex: Int?
    let item: RosettaListItem
    let directionHint: RosettaListDirectionHint?
}

struct RosettaListDeleteItem {
    let index: Int
    let directionHint: RosettaListDirectionHint?
}

struct RosettaListUpdateItem {
    let index: Int
    let previousIndex: Int
    let item: RosettaListItem
    let directionHint: RosettaListDirectionHint?
}
