// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.

import UIKit
import SessionUIKit
import SessionMessagingKit
import SessionUtilitiesKit
import SignalUtilitiesKit

final class MediaInfoVC: BaseVC, SessionCarouselViewDelegate {
    internal static let mediaSize: CGFloat = UIScreen.main.bounds.width - 2 * Values.veryLargeSpacing
    internal static let arrowSize: CGSize = CGSize(width: 20, height: 30)
    
    private let attachments: [Attachment]
    private let isOutgoing: Bool
    private let threadId: String
    private let threadVariant: SessionThread.Variant
    private let interactionId: Int64
    
    private var currentPage: Int = 0
    
    // MARK: - UI
    private lazy var mediaInfoView: MediaInfoView = MediaInfoView(attachment: nil)
    private lazy var mediaCarouselView: SessionCarouselView = {
        let slices: [MediaPreviewView] = self.attachments.map {
            MediaPreviewView(
                attachment: $0,
                isOutgoing: self.isOutgoing
            )
        }
        let result: SessionCarouselView = SessionCarouselView(
            info: SessionCarouselView.Info(
                slices: slices,
                copyOfFirstSlice: slices.first?.copyView(),
                copyOfLastSlice: slices.last?.copyView(),
                sliceSize: CGSize(
                    width: Self.mediaSize,
                    height: Self.mediaSize
                ),
                shouldShowPageControl: true,
                pageControlStyle: SessionCarouselView.PageControlStyle(
                    size: .medium,
                    backgroundColor: .init(white: 0, alpha: 0.4),
                    bottomInset: Values.mediumSpacing
                ),
                shouldShowArrows: true,
                arrowsSize: Self.arrowSize,
                cornerRadius: 8
            )
        )
        result.set(.height, to: Self.mediaSize)
        result.delegate = self
        
        return result
    }()
    
    private lazy var fullScreenButton: UIButton = {
        let result: UIButton = UIButton(type: .custom)
        result.setImage(
            UIImage(systemName: "arrow.up.left.and.arrow.down.right")?
                .withRenderingMode(.alwaysTemplate),
            for: .normal
        )
        result.themeTintColor = .textPrimary
        result.backgroundColor = .init(white: 0, alpha: 0.4)
        result.layer.cornerRadius = 14
        result.set(.width, to: 28)
        result.set(.height, to: 28)
        result.addTarget(self, action: #selector(showMediaFullScreen), for: .touchUpInside)
        
        return result
    }()
    
    // MARK: - Initialization
    
    init(
        attachments: [Attachment],
        isOutgoing: Bool,
        threadId: String,
        threadVariant: SessionThread.Variant,
        interactionId: Int64
    ) {
        self.threadId = threadId
        self.threadVariant = threadVariant
        self.interactionId = interactionId
        self.isOutgoing = isOutgoing
        self.attachments = attachments
        super.init(nibName: nil, bundle: nil)
    }

    override init(nibName: String?, bundle: Bundle?) {
        preconditionFailure("Use init(attachments:) instead.")
    }

    required init?(coder: NSCoder) {
        preconditionFailure("Use init(attachments:) instead.")
    }
    
    // MARK: - Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()
        
        ViewControllerUtilities.setUpDefaultSessionStyle(
            for: self,
            title: "message_info_title".localized(),
            hasCustomBackButton: false
        )
        
        let mediaStackView: UIStackView = UIStackView()
        mediaStackView.axis = .horizontal
        
        mediaInfoView.update(attachment: attachments[0])
        
        mediaCarouselView.addSubview(fullScreenButton)
        fullScreenButton.pin(.trailing, to: .trailing, of: mediaCarouselView, withInset: -(Values.smallSpacing + Values.veryLargeSpacing))
        fullScreenButton.pin(.bottom, to: .bottom, of: mediaCarouselView, withInset: -Values.smallSpacing)
        
        let stackView: UIStackView = UIStackView(arrangedSubviews: [ mediaCarouselView, mediaInfoView ])
        stackView.axis = .vertical
        stackView.alignment = .center
        stackView.spacing = Values.largeSpacing
        
        self.view.addSubview(stackView)
        stackView.pin([ UIView.HorizontalEdge.leading, UIView.HorizontalEdge.trailing ], to: self.view)
        stackView.pin(.top, to: .top, of: self.view, withInset: Values.veryLargeSpacing)
    }
    
    // MARK: - Interaction
    
    @objc func showMediaFullScreen() {
        let attachment = self.attachments[self.currentPage]
        let viewController: UIViewController? = MediaGalleryViewModel.createDetailViewController(
            for: self.threadId,
            threadVariant: self.threadVariant,
            interactionId: self.interactionId,
            selectedAttachmentId: attachment.id,
            options: [ .sliderEnabled ]
        )
        if let viewController: UIViewController = viewController {
            viewController.transitioningDelegate = nil
            self.present(viewController, animated: true)
        }
    }
    
    // MARK: - SessionCarouselViewDelegate
    
    func carouselViewDidScrollToNewSlice(currentPage: Int) {
        self.currentPage = currentPage
        mediaInfoView.update(attachment: attachments[currentPage])
    }
}
