import Adamantium
import AnalyticsClient
import APIClient
import AVFoundation
import AVKit
import CommentsClient
import ComponentLibrary
import ComposableArchitecture
import EventBusClient
import FeatureClipDetail
import FeatureShare
import FeatureShareSheet
import FeatureToasts
import Localization
import OmniPlayerClient
import PlayerClient
import StatsigClient
import SwiftUI
import Utilities

struct MultiGestureContainerViewRepresentable: UIViewRepresentable {
    let clips: [Clip]
    @Binding var selectedIndex: Int
    let verticalContentScrollOffset: (CGFloat) -> Void
    let isVerticalScrollingDisabled: Bool
    let isScrubbing: Bool
    let instantBlur: Bool
    let dimGradient: Bool
    let verticalDragOffsetWhileAtTop: (CGFloat) -> Void
    let setVisibleHorizontalIndex: (Int) -> Void
    let playClipAtHorizontalIndex: (Int) -> Void
    let scrollDownTrigger: Int
    let scrollToTopTrigger: Int
    let content: AnyView

    init<V: View>(
        clips: [Clip],
        selectedIndex: Binding<Int>,
        content: V,
        verticalContentScrollOffset: @escaping (CGFloat) -> Void,
        isVerticalScrollingDisabled: Bool,
        isScrubbing: Bool,
        instantBlur: Bool,
        dimGradient: Bool,
        verticalDragOffsetWhileAtTop: @escaping (CGFloat) -> Void,
        setVisibleHorizontalIndex: @escaping (Int) -> Void,
        playClipAtHorizontalIndex: @escaping (Int) -> Void,
        scrollDownTrigger: Int = 0,
        scrollToTopTrigger: Int = 0
    ) {
        self.clips = clips
        self._selectedIndex = selectedIndex
        self.content = AnyView(content)
        self.verticalContentScrollOffset = verticalContentScrollOffset
        self.isVerticalScrollingDisabled = isVerticalScrollingDisabled
        self.isScrubbing = isScrubbing
        self.instantBlur = instantBlur
        self.dimGradient = dimGradient
        self.verticalDragOffsetWhileAtTop = verticalDragOffsetWhileAtTop
        self.setVisibleHorizontalIndex = setVisibleHorizontalIndex
        self.playClipAtHorizontalIndex = playClipAtHorizontalIndex
        self.scrollDownTrigger = scrollDownTrigger
        self.scrollToTopTrigger = scrollToTopTrigger
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> MultiGestureContainerView {
        @Dependency(\.omniplayerClient) var omniplayerClient

        let scrollView = VerticalClipScrollView()
        scrollView.verticalContentScrollOffset = verticalContentScrollOffset
        scrollView.isVerticalScrollingDisabled = isVerticalScrollingDisabled
        scrollView.verticalDragOffsetWhileAtTop = verticalDragOffsetWhileAtTop

        // Make scroll view background transparent
        scrollView.backgroundColor = .clear

        // Create hosting controller for SwiftUI content
        let hostingController = UIHostingController(rootView: content)
        hostingController.sizingOptions = .intrinsicContentSize
        hostingController.view.backgroundColor = .clear
        hostingController.view.translatesAutoresizingMaskIntoConstraints = false

        // Explicitly tell the hosting controller to ignore safe areas
        hostingController.additionalSafeAreaInsets = .zero

        // Important: Ensure the content disregards safe area insets
        scrollView.contentInsetAdjustmentBehavior = .never

        scrollView.addSubview(hostingController.view)

        NSLayoutConstraint.activate([
            hostingController.view.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
            hostingController.view.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
            hostingController.view.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
            hostingController.view.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
            hostingController.view.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor),
        ])

        context.coordinator.hostingController = hostingController

        // Create and configure the container view
        let containerView = MultiGestureContainerView(scrollView: scrollView)
        containerView.backgroundColor = .clear // Ensure container view has clear background
        containerView.clips = clips
        containerView.selectedIndex = selectedIndex
        containerView.onCollectionViewPageChange = setVisibleHorizontalIndex
        containerView.playClipAtHorizontalIndex = playClipAtHorizontalIndex
        containerView.verticalContentScrollOffset = verticalContentScrollOffset

        // Set the queue rotation callbacks for infinite carousel functionality
        containerView.onRotateQueueForward = {
            await omniplayerClient.rotateQueueForward()
        }
        containerView.onRotateQueueBackward = {
            await omniplayerClient.rotateQueueBackward()
        }

        return containerView
    }

    func updateUIView(_ uiView: MultiGestureContainerView, context: Context) {
        // Update scroll view properties
        uiView.scrollView.isVerticalScrollingDisabled = isVerticalScrollingDisabled
        uiView.scrollView.verticalDragOffsetWhileAtTop = verticalDragOffsetWhileAtTop

        // Update scrubbing state
        uiView.isScrubbing = isScrubbing

        // Programatically set blur (example: when showing tooltips)
        uiView.instantBlur = instantBlur
        uiView.dimGradient = dimGradient
        // Update hosting controller if needed
        if context.coordinator.needsContentUpdate {
            context.coordinator.hostingController?.rootView = content
            context.coordinator.needsContentUpdate = false
        }

        // Update collection view data if needed
        if uiView.clips != clips {
            uiView.clips = clips
            uiView.collectionView.reloadData()
        }

        // Update selected index if changed
        if uiView.selectedIndex != selectedIndex {
            uiView.selectedIndex = selectedIndex
        }

        // Handle scroll down trigger
        if scrollDownTrigger != context.coordinator.lastScrollDownTrigger {
            context.coordinator.lastScrollDownTrigger = scrollDownTrigger
            if scrollDownTrigger > 0 {
                uiView.scrollDownToShowClipDetails()
            }
        }

        // Handle scroll to top trigger
        if scrollToTopTrigger != context.coordinator.lastScrollToTopTrigger {
            context.coordinator.lastScrollToTopTrigger = scrollToTopTrigger
            if scrollToTopTrigger > 0 {
                uiView.scrollToTop()
            }
        }
    }

    class Coordinator {
        var hostingController: UIHostingController<AnyView>?
        var needsContentUpdate = true
        let verticalContentScrollOffset: (CGFloat) -> Void
        var lastScrollDownTrigger: Int = 0
        var lastScrollToTopTrigger: Int = 0

        init(_ parent: MultiGestureContainerViewRepresentable) {
            self.verticalContentScrollOffset = parent.verticalContentScrollOffset
        }
    }
}
