import Localization
import SwiftUI
import UIKit

public struct HookCard: View {
    let thumbnailUrlString: String?
    let thumbnailImage: UIImage?
    let createdAt: Date?
    let clipName: String?
    let playCount: Int
    let statusPillText: String?
    let cardTapped: () -> Void
    let moreTapped: () -> Void
    let statusPillTapped: (() -> Void)?
    let isProcessing: Bool
    let showUnpublishedBadge: Bool

    private let aspectRatio: CGFloat = 0.6
    private let cornerRadius: CGFloat = 14

    public init(
        thumbnailUrlString: String?,
        thumbnailImage: UIImage? = nil,
        createdAt: Date?,
        clipName: String?,
        playCount: Int,
        statusPillText: String? = nil,
        cardTapped: @escaping () -> Void,
        moreTapped: @escaping () -> Void,
        statusPillTapped: (() -> Void)? = nil,
        isProcessing: Bool = false,
        showUnpublishedBadge: Bool = false
    ) {
        self.thumbnailUrlString = thumbnailUrlString
        self.thumbnailImage = thumbnailImage
        self.createdAt = createdAt
        self.clipName = clipName
        self.playCount = playCount
        self.statusPillText = statusPillText
        self.cardTapped = cardTapped
        self.moreTapped = moreTapped
        self.statusPillTapped = statusPillTapped
        self.isProcessing = isProcessing
        self.showUnpublishedBadge = showUnpublishedBadge
    }

    public var body: some View {
        Button(action: cardTapped) {
            card
        }
    }

    private var card: some View {
        RoundedRectangle(cornerRadius: cornerRadius)
            .fill(Color.SemanticV1.backgroundSecondary)
            .aspectRatio(aspectRatio, contentMode: .fill)
            .fixedSize(horizontal: false, vertical: true)
            .overlay {
                content
            }
    }

    private var content: some View {
        ZStack {
            borderOutline
            clipImage
            linearGradient
            moreActionAndHookInfo
        }
    }

    private var borderOutline: some View {
        RoundedRectangle(cornerRadius: cornerRadius)
            .fill(Color.clear)
            .strokeBorder(Color.white.opacity(0.2), lineWidth: 0.5)
    }

    private var linearGradient: some View {
        LinearGradient(
            stops: [
                .init(color: .black.opacity(0.2), location: 0),
                .init(color: .black.opacity(0), location: 0.25),
                .init(color: .black.opacity(0), location: 0.75),
                .init(color: .black.opacity(0.5), location: 1),
            ],
            startPoint: .top,
            endPoint: .bottom
        )
        .clipShape(RoundedRectangle(cornerRadius: cornerRadius))
    }

    private var moreActionAndHookInfo: some View {
        VStack(alignment: .leading, spacing: 0) {
            playCountAndMoreButton
            Spacer()
            clipLabel
            if let statusPillText {
                postStatusPill(statusPillText)
                    .padding(.top, 4)
            } else if isProcessing {
                processingLabel
            } else {
                createdAtLabel
            }
        }
        .padding(8)
    }

    @ViewBuilder
    private var createdAtLabel: some View {
        if let createdAt {
            Text(createdAt.customTimeAgoDisplay())
                .typographyV1(.subtitleSmall.lineHeight(16))
                .foregroundColor(.white.opacity(0.6))
                .frame(height: 16)
        }
    }

    @ViewBuilder
    private var processingLabel: some View {
        Text(L10n.FeatureHooks.processing)
            .typographyV1(.subtitleSmall.lineHeight(16))
            .foregroundColor(.white.opacity(0.6))
            .frame(height: 16)
    }

    @ViewBuilder
    private var clipLabel: some View {
        if let clipName {
            Text(clipName)
                .typographyV1(.subtitleSmall.lineHeight(16))
                .lineLimit(2)
                .multilineTextAlignment(.leading)
                .foregroundStyle(.white)
                .padding(.bottom, 4)
        }
    }

    private var playCountAndMoreButton: some View {
        HStack(spacing: 4) {
            Image.Icon.eye
                .resizable()
                .frame(width: 14, height: 14)
                .foregroundColor(.white)
            Text(playCount.formatted(.number.notation(.compactName)))
                .typographyV1(.subtitleSmall.lineHeight(14))
                .foregroundColor(.white)
            Spacer()
            Button(action: moreTapped) {
                Image.Icon.moreHorizontal
                    .resizable()
                    .frame(width: 14, height: 14)
                    .foregroundColor(.white)
            }
        }
        .frame(height: 14)
    }

    @ViewBuilder
    private var clipImage: some View {
        Group {
            if let thumbnailImage {
                Image(uiImage: thumbnailImage)
                    .resizable()
                    .cornerRadius(cornerRadius)
                    .aspectRatio(aspectRatio, contentMode: .fit)
            } else if let thumbnailUrlString {
                RemoteImage(url: thumbnailUrlString, fallbackId: "1")
                    .cornerRadius(cornerRadius)
                    .aspectRatio(aspectRatio, contentMode: .fit)
            } else {
                Color.clear
                    .aspectRatio(aspectRatio, contentMode: .fit)
                    .clipShape(RoundedRectangle(cornerRadius: cornerRadius))
            }
        }
        .overlay {
            if showUnpublishedBadge {
                ZStack {
                    Color.black
                        .opacity(0.6)
                    Image.Icon.globeSlash
                        .resizable()
                        .renderingMode(.template)
                        .foregroundStyle(.white)
                        .frame(width: 24, height: 24)
                }
                .clipShape(RoundedRectangle(cornerRadius: cornerRadius))
            }
        }
    }

    @ViewBuilder
    private func postStatusPill(_ statusPillText: String) -> some View {
        Button {
            if let statusPillTapped = statusPillTapped {
                statusPillTapped()
            }
        } label: {
            HStack(spacing: 0) {
                Image.Icon.information
                    .renderingMode(.template)
                    .resizable()
                    .foregroundStyle(.red)
                    .frame(width: 12, height: 12)
                    .padding(.trailing, 4)

                Text(statusPillText)
                    .typographyV1(.caption6)
                    .foregroundStyle(.red)
                    .lineLimit(2)
            }
            .padding(.vertical, 4)
            .padding(.horizontal, 8)
            .background(Color.black.opacity(0.75))
            .clipShape(.capsule)
        }
    }
}

struct HookCard_Previews: PreviewProvider {
    static let now = Date()
    static let oneHourAgo = now - 3600
    static let oneDayAgo = now - 86400

    static var previews: some View {
        mockRow
            .previewLayout(.sizeThatFits)
    }

    static var mockRow: some View {
        HStack(spacing: 12) {
            HookCard(
                thumbnailUrlString: nil,
                createdAt: Date(),
                clipName: "THIS IS THE NAME OF MY CLIP",
                playCount: 0,
                statusPillText: nil,
                cardTapped: {},
                moreTapped: {},
                statusPillTapped: {}
            )

            HookCard(
                thumbnailUrlString: nil,
                createdAt: oneHourAgo,
                clipName: "THIS IS THE NAME OF MY CLIP",
                playCount: 1,
                statusPillText: nil,
                cardTapped: {},
                moreTapped: {},
                statusPillTapped: {}
            )

            HookCard(
                thumbnailUrlString: nil,
                createdAt: oneDayAgo,
                clipName: "THIS IS THE NAME OF MY CLIP",
                playCount: 5000,
                statusPillText: "ahhh not posted",
                cardTapped: {},
                moreTapped: {},
                statusPillTapped: {}
            )
        }
        .padding(.vertical, 12)
        .background(Color.SemanticV1.backgroundPrimary)
        .colorScheme(.dark)
    }
}
