import ComponentLibrary
import ComposableArchitecture
import FeatureBanner
import FeatureHookDownload
import Localization
import ShareAssetClient
import SwiftUI
import FeatureToasts

extension RootCoordinatorV1 {
    /// Compute a smooth progress ratio from polling count using logarithmic scaling
    func progressRatio(forPollCount pollCount: Int) -> CGFloat {
        let safeCount = Float(max(1, pollCount))
        var ratio = logf(safeCount) * 0.2 + 0.2
        ratio = min(ratio, 0.95)
        return CGFloat(ratio)
    }

    // MARK: - Helpers

    private func icon(for target: ShareAssetCreationTarget?) -> Banner.PreviewAncillaryBubbleIcon {
        guard let target else { return .none }
        switch target {
        case .downloadVideo: return .download
        case .instagramStories: return .instagram
        case .facebookStories: return .facebook
        case .tiktokVideo: return .tiktok
        }
    }

    private func readyText(for target: ShareAssetCreationTarget) -> String {
        switch target {
        case .downloadVideo:
            return L10n.FeatureShareAssets.boomYourClipsReady
        case .instagramStories, .facebookStories, .tiktokVideo:
            return L10n.FeatureShareAssets.boomYourClipsReady
        }
    }

    private func showProgressBanner(message: String, ratio: Double, icon: Banner.PreviewAncillaryBubbleIcon, previewImageURLs: [URL]? = nil, autoDismiss: Bool = false) -> Effect<Action> {
        .run { [ratio, icon, previewImageURLs, message] send in
            await send(.rootTab(.bannerAction(.show(
                type: .progress(
                    .string(message),
                    completionRatio: ratio,
                    subStyle: .shareAssetGeneration,
                    previewCardBubbleIcon: icon,
                    previewImageURLs: previewImageURLs
                ),
                autoDismiss: autoDismiss
            ))))
        }
    }

    private func showShareReadyBanner(target: ShareAssetCreationTarget, localURL: URL, attributionURL: URL) -> Effect<Action> {
        .run { [localURL, attributionURL, target] send in
            await send(.rootTab(.bannerAction(.show(
                type: .progress(
                    .string(readyText(for: target)),
                    completionRatio: 1.0,
                    subStyle: .shareAssetGeneration,
                    previewCardBubbleIcon: icon(for: target),
                    destination: .shareAsset(target, localURL, attributionURL),
                    previewImageURLs: [localURL]
                ),
                autoDismiss: false
            ))))
        }
    }

    private func showHookCompletionBanner(
        message: String,
        icon: Banner.PreviewAncillaryBubbleIcon,
        localURL: URL,
        destination: BannerReducer.State.BannerType.Destination,
        autoDismiss: Bool
    ) -> Effect<Action> {
        .run { [message, icon, localURL, destination, autoDismiss] send in
            await send(.rootTab(.bannerAction(.show(
                type: .progress(
                    .string(message),
                    completionRatio: 1.0,
                    subStyle: .shareAssetGeneration,
                    previewCardBubbleIcon: icon,
                    destination: destination,
                    previewImageURLs: [localURL]
                ),
                autoDismiss: autoDismiss
            ))))
        }
    }

    func effectForShareAssetEvent(_ shareAssetEvent: ShareAssetClient.ShareAssetClientEvent) -> Effect<Action> {
        switch shareAssetEvent {
        case .startedRenderingShareAsset:
            return showProgressBanner(message: L10n.FeatureShareAssets.yourVideoClipIsInTheWorks, ratio: progressRatio(forPollCount: 0), icon: .none)

        case .polledRendering(_, _, let target, let pollCount):
            return showProgressBanner(message: L10n.FeatureShareAssets.yourVideoClipIsInTheWorks, ratio: progressRatio(forPollCount: pollCount), icon: icon(for: target))

        case .shareAssetReady(_, _, let target, _, let localCacheURL, let attributionURL, _):
            return showShareReadyBanner(target: target, localURL: localCacheURL, attributionURL: attributionURL)

        case .shareAssetCouldNotRender:
            return .none
        }
    }

    func effectForHookDownloadEvent(_ hookDownloadEvent: HookDownloadClient.HookDownloadClientEvent) -> Effect<Action> {
        switch hookDownloadEvent {
        case .startedFetchingDownloadURL(_, _, let target, _):
            let icon = iconForHookTarget(target)
            let message = messageForHookTarget(target, isProgress: true)
            return showProgressBanner(message: message, ratio: progressRatio(forPollCount: 0), icon: icon)

        case .polledForDownloadURL(_, _, let pollCount, let target, _):
            let icon = iconForHookTarget(target)
            let message = messageForHookTarget(target, isProgress: true)
            return showProgressBanner(message: message, ratio: progressRatio(forPollCount: pollCount), icon: icon)

        case .downloadURLReady:
            // Continue showing progress, will update when download starts
            return .none

        case .startedDownloadingHook(_, _, _, let target, _):
            let icon = iconForHookTarget(target)
            let message = messageForHookTarget(target, isProgress: true)
            return showProgressBanner(message: message, ratio: 0.8, icon: icon)

        case .hookDownloadComplete(let hook, _, let localURL, let target, let attributionURL):
            // For Instagram/TikTok/Facebook, use shareAsset destination to open platform app
            if let attributionURL = attributionURL, target != .download {
                let assetTarget: ShareAssetCreationTarget = switch target {
                case .instagram: .instagramStories
                case .tiktok: .tiktokVideo
                case .facebook: .facebookStories
                case .download: .downloadVideo
                }

                return showHookCompletionBanner(
                    message: L10n.FeatureHooks.hookReadyForShare,
                    icon: iconForHookTarget(target),
                    localURL: localURL,
                    destination: .shareAsset(assetTarget, localURL, attributionURL),
                    autoDismiss: false
                )
            } else {
                // For download, show simple completion banner
                return showHookCompletionBanner(
                    message: L10n.FeatureHooks.hookDownloadComplete,
                    icon: iconForHookTarget(target),
                    localURL: localURL,
                    destination: .hookDownload(hook, localURL),
                    autoDismiss: true
                )
            }

        case .hookDownloadFailed(_, _, let error, _):
            @Dependency(\.toastClient.show) var showToast
            showToast(.warning(
                L10n.FeatureHooks.downloadFailed,
                .string(error.localizedDescription),
                position: .top
            ))
            return .send(.rootTab(.bannerAction(.dismiss)), animation: .default)
        }
    }

    private func iconForHookTarget(_ target: HookDownloadClient.ShareTarget) -> Banner.PreviewAncillaryBubbleIcon {
        switch target {
        case .download: .download
        case .instagram: .instagram
        case .tiktok: .tiktok
        case .facebook: .facebook
        }
    }

    private func messageForHookTarget(_ target: HookDownloadClient.ShareTarget, isProgress: Bool) -> String {
        switch target {
        case .download:
            return isProgress ? L10n.FeatureHooks.downloadingHook : L10n.FeatureHooks.hookDownloadComplete
        case .instagram, .tiktok, .facebook:
            return isProgress ? L10n.FeatureHooks.downloadingHookForShare : L10n.FeatureHooks.hookReadyForShare
        }
    }
}
