import APIClient
import ComposableArchitecture
import FeatureHookDownload
import FeatureShareAssetCreation
import Foundation
import Localization
import ShareAssetClient
import UIKit

/// Responsible for performing system and platform sharing
@Reducer
public struct ShareReducer<Item: Shareable> {
    public typealias State = ShareSheetState<Item>

    public enum Action {
        case triggerShareActionTarget(ShareableTarget)
    }

    @Dependency(ShareAssetClient.self) var shareAssetClient
    @Dependency(\.hookDownloadClient) var hookDownloadClient
    @Dependency(\.dismiss) var dismiss

    public var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .triggerShareActionTarget(let actionTarget):
                switch actionTarget {
                case .system(let system):
                    switch system {
                    case .copyLink:
                        return copyEffect(&state)
                    case .download:
                        return createAssetEffect(&state, target: .downloadVideo)
                    case .more:
                        return systemShareEffect(&state)
                    }

                case .platform(let platform):
                    switch platform {
                    case .facebook:
                        return createAssetEffect(&state, target: .facebookStories)
                    case .instagram:
                        return createAssetEffect(&state, target: .instagramStories)
                    case .messages:
                        return messagesEffect(&state)
                    case .tiktok:
                        return createAssetEffect(&state, target: .tiktokVideo)
                    case .whatsApp:
                        return whatsAppEffect(&state)
                    case .x:
                        return xEffect(&state)
                    }
                }
            }
        }
    }
}

private extension ShareReducer {
    func copyEffect(_ state: inout ShareSheetState<Item>) -> Effect<ShareReducer.Action> {
        UIPasteboard.general.string = state.effectiveShareURL.absoluteString
        state.toast = .success(L10n.FeatureShareAssets.toastLinkCopied)
        return .none
    }

    func createAssetEffect(_ state: inout ShareSheetState<Item>, target: ShareAssetCreationTarget) -> Effect<ShareReducer.Action> {
        if let hook = state.item as? Hook {
            let shareTarget: HookDownloadClient.ShareTarget = switch target {
            case .instagramStories: .instagram
            case .tiktokVideo: .tiktok
            case .facebookStories: .facebook
            case .downloadVideo: .download
            }

            let attributionURL = state.effectiveShareURL
            hookDownloadClient.triggerHookDownload(hook, shareTarget, attributionURL)

            return .run { _ in
                await dismiss()
            }
        }

        guard let clip = state.item as? Clip else {
            assertionFailure("Attempting to launch asset creation for an unsupported type.")
            return .none
        }

        let mostRecentShareAssetGenerationForClip = shareAssetClient.getSavedShareAssetGenerationForClip(clip.id)

        state.destination = .assetCreation(AssetCreationState(
            clip: clip,
            shareURL: state.effectiveShareURL,
            targetDestination: target,
            lyricsData: state.lyricsData ?? .empty,
            waveformData: state.waveformData ?? .empty,
            lastGenerationURL: mostRecentShareAssetGenerationForClip
        ))
        return .none
    }

    func messagesEffect(_ state: inout ShareSheetState<Item>) -> Effect<ShareReducer.Action> {
        state.destination = .messageComposer
        return .none
    }

    func systemShareEffect(_ state: inout ShareSheetState<Item>) -> Effect<ShareReducer.Action> {
        state.destination = .systemShareSheet
        return .none
    }

    func whatsAppEffect(_ state: inout ShareSheetState<Item>) -> Effect<ShareReducer.Action> {
        let components = URLComponents(
            string: "whatsapp://send?text=\(state.decoratedShareString)",
            encodingInvalidCharacters: true
        )
        guard let url = components?.url else {
            state.toast = .warning(L10n.FeatureShare.sharingFailed)
            return .none
        }
        return .run { @MainActor _ in
            await UIApplication.shared.open(url)
        }
    }

    func xEffect(_ state: inout ShareSheetState<Item>) -> Effect<ShareReducer.Action> {
        let shareURL = state.effectiveShareURL.absoluteString
        let shareText = state.item.shareText ?? ""
        let components = URLComponents(
            string: "https://x.com/intent/tweet?url=\(shareURL)&text=\(shareText)",
            encodingInvalidCharacters: true
        )
        guard let url = components?.url else {
            state.toast = .warning(L10n.FeatureShare.sharingFailed)
            return .none
        }
        return .run { @MainActor _ in
            await UIApplication.shared.open(url)
        }
    }
}
