import APIClient
import ComponentLibrary
import ComposableArchitecture
import FeatureToasts
import Foundation
import Localization
import StatsigClient
import SwiftUI

public struct HookActionsMenu: View {
    let store: StoreOf<HookActions>
    let coverSize: CGSize = .init(width: 60, height: 80)
    let darkTrait = UITraitCollection(userInterfaceStyle: .dark)

    private func resolveColorForDarkTrait(_ color: Color) -> Color {
        Color(UIColor(color).resolvedColor(with: darkTrait))
    }

    // force dark mode to prevent visual bugs when presented on light-mode parent
    private func rowForegroundColor(flagWarning: Bool) -> Color {
        let color = flagWarning ? Color.SemanticV2.accentError : Color.SemanticV1.textPrimary
        return resolveColorForDarkTrait(color)
    }

    private var backgroundColor: Color {
        return resolveColorForDarkTrait(resolveColorForDarkTrait(Color.SemanticV2.backgroundSmokeThin))
    }

    private var titleColor: Color {
        return resolveColorForDarkTrait(resolveColorForDarkTrait(Color.SemanticV2.foregroundPrimary))
    }

    private var subtitleColor: Color {
        return resolveColorForDarkTrait(Color.SemanticV2.backgroundFogDense)
    }

    public init(store: StoreOf<HookActions>) {
        self.store = store
    }

    public var body: some View {
        VStack(spacing: 12) {
            header
            hookActions
        }
        .preferredColorScheme(.dark)
        .padding(.vertical, 30)
        .padding(.horizontal, 16)
        .presentationCornerRadius(20, conditional: true)
        .presentationBackground {
            Rectangle()
                .fill(.ultraThinMaterial)
                .overlay(backgroundColor)
        }
        .presentationDragIndicator(.visible)
        .selfSizingPresentation()
    }

    @ViewBuilder
    private var header: some View {
        HStack(spacing: 0) {
            HStack(spacing: 12) {
                coverImage

                VStack(alignment: .leading, spacing: 2) {
                    songTitle
                    authorName
                }
            }
            Spacer()
        }
        .padding(.horizontal, 8)
    }

    @ViewBuilder
    private var hookActions: some View {
        VStack(spacing: 14) {
            // First row: Add to Playlist, Like Song, Share Hook
            HStack(spacing: 12) {
                addToPlaylist
                likeSong
                shareHook
            }

            // Second section: Common actions for everyone
            commonActions

            // Third section: Changes if Me
            if store.isMe {
                meOnlyActions
            } else {
                otherUserActions
            }
        }
    }

    @ViewBuilder
    private var commonActions: some View {
        // Common actions for everyone: Go to Full Song, Remix Song, Download Hook
        VStack(spacing: 0.5) {
            FullWidthMenuRow(
                title: L10n.FeatureHooks.goToFullSong,
                action: { store.send(.goToFullSongTapped) },
                leadingImage: Image.Icon.musicNote
            )

            if store.canRemix {
                sectionDivider

                FullWidthMenuRow(
                    title: L10n.FeatureHooks.remixSong,
                    action: { store.send(.remixSongTapped) },
                    leadingImage: Image.Icon.remix
                )
            }

            if store.canDownloadHook {
                sectionDivider

                FullWidthMenuRow(
                    title: L10n.FeatureHooks.downloadHook,
                    action: { store.send(.downloadHookTapped) },
                    leadingImage: Image.Icon.downloadTray
                        .resizable()
                )
            }
            
            if store.isMe {
                sectionDivider
                
                FullWidthMenuRow(
                    title: L10n.FeatureClipDetail.allowComments,
                    action: {
                        store.send(.setCommentsAccess(!store.allowComments))
                    },
                    leadingImage: Image.Icon.comment,
                    toggleBinding: .init(get: {
                        store.allowComments
                    }, set: { newValue in
                        store.send(.setCommentsAccess(newValue))
                    })
                )
            }
        }
        .clipShape(RoundedRectangle(cornerRadius: 16))
    }

    @ViewBuilder
    private var meOnlyActions: some View {
        // Owner-only actions: Delete Hook
        VStack(spacing: 0) {
            FullWidthMenuRow(
                title: L10n.FeatureHooks.deleteHook,
                flagWarning: true,
                action: { store.send(.deleteHookTapped) },
                leadingImage: Image.Icon.trashV2
            )
        }
        .clipShape(RoundedRectangle(cornerRadius: 16))
    }

    @ViewBuilder
    private var otherUserActions: some View {
        // Other user actions: Hide Creator, Not Interested, Report
        VStack(spacing: 0.5) {
            FullWidthMenuRow(
                title: L10n.FeatureHooks.hideCreator,
                action: { store.send(.hideCreatorTapped) },
                leadingImage: Image.Icon.minus
            )

            sectionDivider

            FullWidthMenuRow(
                title: L10n.FeatureHooks.reportInappropriate,
                action: { store.send(.reportInappropriateTapped) },
                leadingImage: Image.Icon.flagV2
            )

            sectionDivider

            FullWidthMenuRow(
                title: isHookDisliked ? L10n.FeatureClipDetail.removeDislike : L10n.FeatureHooks.notInterested,
                action: { store.send(.notInterestedTapped) },
                leadingImage: isHookDisliked ? Image.Icon.checkV1 : Image.Icon.thumbsDown
            )
        }
        .clipShape(RoundedRectangle(cornerRadius: 16))
    }

    @ViewBuilder
    private var addToPlaylist: some View {
        MenuRow(
            title: L10n.FeatureClipDetail.addToPlaylist
        ) {
            store.send(.addToPlaylistTapped)
        } icon: {
            Image.Icon.plus
                .resizable()
                .renderingMode(.template)
                .foregroundStyle(rowForegroundColor(flagWarning: false))
                .frame(width: 24, height: 24)
        }
        .clipShape(RoundedRectangle(cornerRadius: 10))
    }

    private var isClipLiked: Bool {
        store.hook.clip?.isLiked ?? false
    }

    private var isHookDisliked: Bool {
        store.hook.isDisliked
    }

    @ViewBuilder
    private var likeSong: some View {
        MenuRow(
            title: isClipLiked ? L10n.FeatureClipDetail.liked : L10n.FeatureClipDetail.likeSong
        ) {
            store.send(.likeSongTapped)
        } icon: {
            // Show checkmark if song is liked, thumbs up if not
            (isClipLiked ? Image.Icon.checkV1 : Image.Icon.thumbsUp)
                .resizable()
                .renderingMode(.template)
                .foregroundStyle(rowForegroundColor(flagWarning: false))
                .frame(width: 24, height: 24)
        }
        .clipShape(RoundedRectangle(cornerRadius: 10))
    }

    @ViewBuilder
    private var shareHook: some View {
        MenuRow(
            title: L10n.FeatureHooks.shareHook
        ) {
            store.send(.shareHookTapped)
        } icon: {
            Image.Omniplayer.share
                .resizable()
                .renderingMode(.template)
                .foregroundStyle(rowForegroundColor(flagWarning: false))
                .frame(width: 24, height: 24)
        }
        .clipShape(RoundedRectangle(cornerRadius: 10))
    }

    @ViewBuilder
    private var sectionDivider: some View {
        Spacer()
            .frame(height: 0.00001)
    }

    @ViewBuilder
    private func MenuRow(
        title: String,
        action: @escaping () -> Void,
        icon: () -> some View
    ) -> some View {
        Button(action: action) {
            VStack(spacing: 8) {
                icon()
                MarqueeText(
                    text: title,
                    font: TypographyV1.caption2.uiFont ?? .systemFont(ofSize: 12),
                    leftFade: 0.5,
                    rightFade: 0.5,
                    startDelay: 2,
                    alignment: .center
                )
                .foregroundStyle(titleColor)
            }
            .padding(.horizontal, 8)
            .padding(.vertical, 12)
            .frame(maxWidth: .infinity)
            .background(Color.SemanticV2.backgroundFogThin)
        }
        .buttonStyle(.plain)
    }

    @ViewBuilder
    private func FullWidthMenuRow(
        title: String,
        flagWarning: Bool = false,
        action: @escaping () -> Void,
        leadingImage: Image? = nil,
        toggleBinding: Binding<Bool>? = nil
    ) -> some View {
        Button(action: action) {
            HStack(spacing: 0) {
                HStack(spacing: 10) {
                    if let leadingImage {
                        leadingImage
                            .renderingMode(.template)
                            .foregroundStyle(rowForegroundColor(flagWarning: flagWarning))
                            .frame(width: 24, height: 24)
                    }

                    Text(title)
                        .typographyV1(.heading4.neueMontrealMedium())
                        .foregroundStyle(rowForegroundColor(flagWarning: flagWarning))
                        .frame(maxWidth: .infinity, alignment: .leading)
                }

                Spacer()
                
                if let toggleBinding {
                    Toggle(
                        isOn: toggleBinding,
                        label: {
                            EmptyView()
                        }
                    )
                    .labelsHidden()
                    .tint(Color.SemanticV2.accentPink)
                }
            }
            .padding(16)
            .contentShape(Rectangle())
            .background(Color.SemanticV2.backgroundFogThin)
        }
        .buttonStyle(.plain)
    }

    @ViewBuilder
    private var songTitle: some View {
        if let title = store.hook.clip?.title {
            MarqueeText(
                text: title,
                font: TypographyV1.heading4.neueMontrealMedium().kerning(0.32).uiFont ?? .systemFont(ofSize: 16),
                leftFade: 0.5,
                rightFade: 0.5,
                startDelay: 2,
                alignment: .leading
            )
            .foregroundStyle(titleColor)
        }
    }

    @ViewBuilder
    private var authorName: some View {
        if let displayName = store.hook.user?.displayName {
            MarqueeText(
                text: displayName,
                font: TypographyV1.authorFont.uiFont ?? .systemFont(ofSize: 14),
                leftFade: 0.5,
                rightFade: 0.5,
                startDelay: 2,
                alignment: .leading
            )
            .foregroundStyle(subtitleColor)
        }
    }

    private var coverImage: some View {
        RemoteImage(
            url: store.hook.thumbnailImageUrl, fallbackId: store.hook.id
        )
        .aspectRatio(contentMode: .fill)
        .frame(width: coverSize.width, height: coverSize.height)
        .clipShape(RoundedRectangle(cornerRadius: 14))
    }
}

private extension TypographyV1 {
    static let titleFont: TypographyV1 = .heading4
        .neueMontrealMedium()
        .size { _ in 16.0 }
        .lineHeight(24.0)
        .kerning(0.32)

    static let authorFont: TypographyV1 =
        .playerCaption.neueMontrealMedium()
        .size { _ in 14.0 }
        .lineHeight(20.0)
        .kerning(0.32)
}
