import ComponentLibrary
import ComposableArchitecture
import Localization
import ShareAssetClient
import SwiftUI
import Utilities

struct VisualizerGalleryPreviewOverlay: View {
    let clipTitle: String
    let clipAuthor: String
    let currentTime: TimeInterval
    let clipDuration: TimeInterval

    let frameSize: CGSize
    let assetConfig: VisualizerAssetConfig

    init(
        clipTitle: String,
        clipAuthor: String,
        currentTime: TimeInterval,
        clipDuration: TimeInterval,
        frameSize: CGSize,
        assetConfig: VisualizerAssetConfig
    ) {
        self.clipTitle = clipTitle
        self.clipAuthor = clipAuthor
        self.currentTime = currentTime
        self.clipDuration = clipDuration
        self.frameSize = frameSize
        self.assetConfig = assetConfig
    }

    var body: some View {
        ZStack {
            clipTitleView
            sunoLogoView
        }
        .frame(width: frameSize.width, height: frameSize.height)
        .overlay {
            if assetConfig.shareAssetConfig.stickerStyle.usesFrameCardV1 {
                Image.Assets.shareAssetMaskOverlay
                    .resizable()
                    .aspectRatio(contentMode: .fill)
            }
        }
    }
}

private extension VisualizerGalleryPreviewOverlay {
    var paddingLeading: CGFloat {
        return frameSize.width * 0.075
    }

    var space: CGFloat {
        return frameSize.height * 0.00813
    }

    var spaceX2: CGFloat {
        return space * 2.0
    }

    var spaceX4: CGFloat {
        return space * 4.0
    }

    /*
        Handle setting up title view and all ancillary views
        near title like author handle and timer potentially.

        The set depends on which preset you are using.
     */
    @ViewBuilder
    var clipTitleView: some View {
        let paddingTopHigh = frameSize.height * 0.1
        let paddingTopLeadingCorner = frameSize.height * 0.05
        let paddingTopHighFramed = frameSize.height * 0.175
        let paddingTimerTop = frameSize.height * 0.1675

        let titlePosStyle = assetConfig.shareAssetConfig.stickerStyle.titlePositionStyle

        ZStack(alignment: .center) {
            switch titlePosStyle {
            case .none:
                EmptyView()

            case .topCenterFramed:
                VStack(spacing: .zero) {
                    titleText
                        .padding(.bottom, space)
                    authorHandleText
                        .padding(.bottom, spaceX4)
                    timerBlock
                    Spacer()
                }
                .padding(.top, paddingTopHighFramed)

            case .topCenterHigh:
                VStack(spacing: .zero) {
                    titleText
                        .padding(.bottom, space)
                    authorHandleText
                        .padding(.bottom, spaceX4)
                    timerBlock
                    Spacer()
                }
                .padding(.top, paddingTopHigh)

            case .topLeadingCorner:
                HStack {
                    VStack(alignment: .leading, spacing: .zero) {
                        titleText
                            .padding(.bottom, space)
                        authorHandleText
                        Spacer()
                    }
                    Spacer()
                }
                .padding(.top, paddingTopLeadingCorner)
                .padding(.leading, paddingLeading)

            case .centerLeading:
                HStack {
                    VStack(alignment: .leading, spacing: .zero) {
                        timerBlock
                            .padding(.bottom, spaceX2)
                        titleText
                            .padding(.bottom, space)
                        authorHandleText
                    }
                    Spacer()
                }
                .padding(.leading, paddingLeading)

            case .centerFramed:
                VStack(spacing: .zero) {
                    titleText
                        .padding(.bottom, space)
                    authorHandleText
                }

                VStack {
                    timerBlock
                        .padding(.top, paddingTimerTop)
                    Spacer()
                }
            }
        }
    }

    /*
        Handle setting up suno logo view and all ancillary views
        near title like timer potentially.

        The set depends on which preset you are using.
     */
    @ViewBuilder
    var sunoLogoView: some View {
        let paddingBottom = frameSize.height * 0.1
        let paddingBottomLeadingCorner = frameSize.height * 0.05
        let paddingBottomFramed = frameSize.height * 0.2

        let logoPosStyle = assetConfig.shareAssetConfig.stickerStyle.logoPositionStyle
        let timerPos = assetConfig.shareAssetConfig.stickerStyle.timerPositionStyle

        VStack {
            Spacer()

            switch logoPosStyle {
            case .bottomCenter:
                HStack {
                    logoImage
                }
                .padding(.bottom, paddingBottom)

            case .bottomCenterFramed:
                HStack {
                    logoImage
                }
                .padding(.bottom, paddingBottomFramed)

            case .bottomLeading:
                HStack {
                    logoImage
                    Spacer()
                    switch timerPos {
                    case .bottomTrailingCorner:
                        timerBlock
                    case .none, .paddedCenterLeading, .topCenterFramed, .topCenterHigh:
                        EmptyView()
                    }
                }
                .padding(.bottom, paddingBottomLeadingCorner)
                .padding(.horizontal, paddingLeading)

            case .none:
                EmptyView()
            }
        }
    }

    @ViewBuilder
    var timerBlock: some View {
        Text(TimeInterval.formattedTimeRange(currentTime: currentTime, duration: clipDuration))
            .typographyV1(
                .monospace
                    .size { _ in frameSize.height * 0.0175 }
                    .lineHeight(.one)
            )
            .lineLimit(1)
            .truncationMode(.tail)
            .foregroundStyle(.white)
        /* We don't use semantic values in shader rendering */
    }

    @ViewBuilder
    var titleText: some View {
        Text(clipTitle)
            .typographyV1(
                .headline3
                    .size { _ in frameSize.height * 0.0375 }
                    .lineHeight(.one)
            )
            .lineLimit(1)
            .truncationMode(.tail)
            .foregroundStyle(.white)
        /* We don't use semantic values in shader rendering */
    }

    @ViewBuilder
    var authorHandleText: some View {
        Text("\(L10n.FeatureShareAssets.by) \(clipAuthor)")
            .typographyV1(
                .subtitleSmall
                    .size { _ in frameSize.height * 0.02 }
                    .lineHeight(.one)
            )
            .lineLimit(1)
            .truncationMode(.tail)
            .foregroundStyle(.white.opacity(0.5))
        /* We don't use semantic values in shader rendering */
    }

    @ViewBuilder
    var logoImage: some View {
        let logoHeight = frameSize.height * 0.025

        Image.Icon.logoV1
            .resizable()
            .aspectRatio(contentMode: .fit)
            .frame(height: logoHeight)
            .foregroundStyle(.white)
    }
}
