import APIClient
import Sharing
import UIKit
import Utilities

/// Defines the empty state behavior for the hooks grid
public enum HooksGridEmptyState: Equatable {
    /// No special empty state handling
    case none
    /// Show prompt to create the first hook
    case createFirstHook
    /// Show empty state for no liked hooks
    case noLikedHooks
}

/// Configuration for displaying a grid of hooks with customizable appearance and behavior
public struct HooksGridConfig: Equatable {
    public init(me: Shared<Me>, showBackButton: Bool, initialState: InitialState, gridAppearance: HooksGridAppearance, emptyState: HooksGridEmptyState, source: HooksFeedSource) {
        self.me = me
        self.showBackButton = showBackButton
        self.initialState = initialState
        self.gridAppearance = gridAppearance
        self.emptyState = emptyState
        self.source = source
    }

    /// Initial data state for the hooks grid
    public enum InitialState: Equatable {
        /// No initial data provided
        case none
        /// Currently loading data
        case loading
        /// Grid starts with prefetched hooks data
        case prefetched(
            hooks: [Hook],
            pendingHooks: [PendingHook],
            hasMore: Bool,
            pageSize: Int
        )
    }

    /// Represents a hook that is still being processed (uploading or rendering)
    public struct PendingHook: Equatable {
        public let hook: Hook
        public let thumbnail: UIImage?

        public init(hook: Hook, thumbnail: UIImage? = nil) {
            self.hook = hook
            self.thumbnail = thumbnail
        }

        public static func == (lhs: PendingHook, rhs: PendingHook) -> Bool {
            lhs.hook == rhs.hook && lhs.thumbnail?.pngData() == rhs.thumbnail?.pngData()
        }
    }

    public let me: Shared<Me>
    public let showBackButton: Bool
    public let initialState: InitialState
    public let gridAppearance: HooksGridAppearance
    public let emptyState: HooksGridEmptyState
    public let source: HooksFeedSource
}

public extension HooksGridConfig {
    static func `default`(
        me: Shared<Me>,
        showBackButton: Bool,
        initialState: InitialState
    ) -> Self {
        Self(
            me: me,
            showBackButton: showBackButton,
            initialState: initialState,
            gridAppearance: .default,
            emptyState: .none,
            source: .hooksFeed
        )
    }

    static func myHooks(
        me: Shared<Me>,
        initialState: InitialState
    ) -> Self {
        Self(
            me: me,
            showBackButton: false,
            initialState: initialState,
            gridAppearance: .myHooks,
            emptyState: .createFirstHook,
            source: .libraryGrid
        )
    }

    static func userHooks(
        me: Shared<Me>,
        initialState: InitialState,
        handle: String
    ) -> Self {
        Self(
            me: me,
            showBackButton: false,
            initialState: initialState,
            gridAppearance: .default,
            emptyState: .none,
            source: .profileGrid(handle: handle)
        )
    }

    static func clipHooks(
        me: Shared<Me>,
        initialState: InitialState,
        clipId: String
    ) -> Self {
        Self(
            me: me,
            showBackButton: false,
            initialState: initialState,
            gridAppearance: .default,
            emptyState: .none,
            source: .clip(clipId: clipId)
        )
    }

    static func likedHooks(
        me: Shared<Me>,
        initialState: InitialState
    ) -> Self {
        Self(
            me: me,
            showBackButton: false,
            initialState: initialState,
            gridAppearance: .myHooks,
            emptyState: .noLikedHooks,
            source: .libraryGrid
        )
    }
}
