import ComponentLibrary
import ComposableArchitecture
import Foundation
import SwiftUI

public struct HookArtistFollowButton: View {
    let imageUrlString: String?
    let isFollowing: Bool
    let followTapped: () -> Void
    let profileTapped: () -> Void

    @State private var isFollowToggled: Bool
    // This is used to rotate the '+' icon when the user taps to follow
    @State private var isAnimatingPlusIcon: Bool = false
    // We hide the follow button after the user taps + to follow,
    // and never show it on first load if already following
    @State private var hideFollowButton: Bool

    public init(
        imageUrlString: String?,
        isFollowing: Bool = false,
        followTapped: @escaping () -> Void,
        profileTapped: @escaping () -> Void
    ) {
        self.imageUrlString = imageUrlString
        self.isFollowing = isFollowing
        self.followTapped = followTapped
        self.profileTapped = profileTapped
        self.isFollowToggled = isFollowing
        self.hideFollowButton = isFollowing
    }

    private var animation: Animation {
        if !isFollowing {
            return .bouncy
        } else {
            return .easeInOut(duration: 0.3)
        }
    }

    public var body: some View {
        Button {
            profileTapped()
        } label: {
            artistImage
        }
        .buttonStyle(ScaleButtonStyle())
        .contentShape(.circle)
        .fixedSize(horizontal: true, vertical: false)
        .overlay(alignment: .bottom) {
            followButton
        }
        .onChange(of: isFollowing) { oldValue, newValue in
            guard newValue != oldValue else { return }
            // Reset status if we're navigating back in the NavigationStack
            isFollowToggled = newValue
            hideFollowButton = newValue
        }
    }

    private var artistImage: some View {
        RemoteImage(url: imageUrlString, fallbackId: nil)
            .frame(width: 44, height: 44)
            .cornerRadius(.infinity)
            .background {
                Circle()
                    .fill(Material.ultraThinMaterial)
                    .strokeBorder(Color.SemanticV2.backgroundGlassDense, lineWidth: 1, antialiased: false)
            }
    }

    @ViewBuilder
    private var followIcon: some View {
        // During animation, always show the plus icon to ensure animation plays on correct icon
        if isAnimatingPlusIcon {
            Image.Icon.plus
                .resizable()
                .foregroundStyle(.black)
        } else if isFollowToggled && !hideFollowButton {
            // Only show checkmark if user just tapped to follow
            Image.Icon.checkV1
                .resizable()
                .foregroundStyle(Color.SemanticV2.accentPink)
        } else {
            Image.Icon.plus
                .resizable()
                .foregroundStyle(.black)
        }
    }

    private var followButton: some View {
        Button {
            isFollowToggled.toggle()
            followTapped()
            isAnimatingPlusIcon = true
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                isAnimatingPlusIcon = false
                if isFollowToggled {
                    // Show checkmark briefly, then hide button
                    hideFollowButton = false
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) {
                        hideFollowButton = true
                    }
                }
            }
        } label: {
            Circle()
                .frame(width: 20, height: 20)
                .foregroundStyle(.white)
                .overlay {
                    followIcon
                        .frame(width: 17, height: 17)
                        .rotationEffect(isAnimatingPlusIcon ? .degrees(-10) : .zero)
                        .scaleEffect(isAnimatingPlusIcon ? 1.25 : 1.0)
                        .animation(animation, value: isAnimatingPlusIcon)
                }
                .offset(y: 10)
        }
        .buttonStyle(ScaleButtonStyle())
        .contentShape(.circle)
        .opacity(hideFollowButton ? 0 : 1)
        .animation(.easeInOut(duration: 0.3), value: hideFollowButton)
    }
}
