//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//

import UIKit
import SignalServiceKit

// MARK: - StickerPickerSheetDelegate

public protocol StickerPickerSheetDelegate: AnyObject {
    func makeManageStickersViewController() -> UIViewController
}

// MARK: - StickerPickerSheet

public class StickerPickerSheet: InteractiveSheetViewController {
    public override var interactiveScrollViews: [UIScrollView] { stickerPicker.stickerPackCollectionViews }
    public override var sheetBackgroundColor: UIColor { .clear }

    /// Used for presenting the sticker manager from the toolbar.
    ///
    /// This delegate is optional. If it is not set, the picker sheet will
    /// still function, but the manage stickers button will not appear
    /// on the toolbar.
    public weak var sheetDelegate: StickerPickerSheetDelegate? {
        didSet {
            // The toolbar only shows the manage button if it has a delegate
            // If the sheet doesn't have a delegate, it can't present the
            // manage stickers view controller, so only set the toolbar
            // delegate if there is a sheet delegate.
            stickerPacksToolbar.delegate = sheetDelegate == nil ? nil : self
        }
    }
    /// Used for handling sticker selection.
    public weak var pickerDelegate: StickerPickerDelegate?
    private let stickerPacksToolbar = StickerPacksToolbar(forceDarkTheme: true)
    private lazy var stickerPicker = StickerPickerPageView(delegate: self, forceDarkTheme: true)

    override init(blurEffect: UIBlurEffect? = nil) {
        super.init(blurEffect: blurEffect)
    }

    init(backgroundColor: UIColor) {
        super.init()
        stickerPicker.backgroundColor = backgroundColor
    }

    public override func viewDidLoad() {
        super.viewDidLoad()

        contentView.addSubview(stickerPicker)
        stickerPicker.autoPinEdgesToSuperviewEdges()
        stickerPicker.stickerPackCollectionViews.forEach { $0.alwaysBounceVertical = true }

        view.addSubview(stickerPacksToolbar)
        stickerPacksToolbar.autoPinEdges(toSuperviewEdgesExcludingEdge: .top)
        stickerPacksToolbar.backgroundColor = .ows_gray90
    }

    private var viewHasAppeared = false
    public override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        viewHasAppeared = true
    }

    public override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        // Ensure the scrollView's layout has completed
        // as we're about to use its bounds to calculate
        // the masking view and contentOffset.
        contentView.layoutIfNeeded()

        // Ensure you can scroll to the last sticker without
        // them being stuck behind the toolbar.
        let bottomInset = stickerPacksToolbar.height - stickerPacksToolbar.safeAreaInsets.bottom
        let contentInset = UIEdgeInsets(top: 0, leading: 0, bottom: bottomInset, trailing: 0)
        stickerPicker.stickerPackCollectionViews.forEach { collectionView in
            collectionView.contentInset = contentInset
            collectionView.scrollIndicatorInsets = contentInset
        }

        guard !viewHasAppeared else { return }
        stickerPicker.wasPresented()
    }
}

// MARK: StickerPacksToolbarDelegate

extension StickerPickerSheet: StickerPacksToolbarDelegate {
    public func presentManageStickersView() {
        guard let sheetDelegate else { return }
        let manageStickersViewController = sheetDelegate.makeManageStickersViewController()
        presentFormSheet(manageStickersViewController, animated: true)
    }
}

// MARK: StickerPickerPageViewDelegate

extension StickerPickerSheet: StickerPickerPageViewDelegate {
    public func didSelectSticker(stickerInfo: StickerInfo) {
        self.pickerDelegate?.didSelectSticker(stickerInfo: stickerInfo)
    }

    public var storyStickerConfiguration: StoryStickerConfiguration {
        self.pickerDelegate?.storyStickerConfiguration ?? .hide
    }

    public func setItems(_ items: [StickerHorizontalListViewItem]) {
        stickerPacksToolbar.packsCollectionView.items = items
    }

    public func updateSelections(scrollToSelectedItem: Bool) {
        stickerPacksToolbar.packsCollectionView.updateSelections(scrollToSelectedItem: scrollToSelectedItem)
    }
}
