//
//  Components.swift
//  Pods
//
//  Created by sophia on 24/1/25.
//

import SwiftUI

// MARK: - Enums

public enum TitlePosition {
    case left, center
}

public enum HeaderType {
    case `default`, extended, none
}

public enum AnimatedHeaderRatio {
    case ratio16_9
    case ratio1_1
    case ratio3_2

    var value: CGFloat {
        switch self {
        case .ratio16_9: return 16.0 / 9.0
        case .ratio1_1:  return 1.0
        case .ratio3_2:  return 3.0 / 2.0
        }
    }
}


// MARK: - Animated Header Config

public struct AnimatedHeader {
    public var aspectRatio: AnimatedHeaderRatio = .ratio16_9
    public var isSurface: Bool = true
    public var composable: (_ scrollState: CGFloat) -> AnyView = { _ in AnyView(EmptyView()) }

    public init(
        aspectRatio: AnimatedHeaderRatio = .ratio16_9,
        isSurface: Bool = true,
        composable: @escaping (_ scrollState: CGFloat) -> AnyView = { _ in AnyView(EmptyView()) }
    ) {
        self.aspectRatio = aspectRatio
        self.isSurface = isSurface
        self.composable = composable
    }
}

// MARK: - Utils

func safeAreaTopInset() -> CGFloat {
    if #available(iOS 15.0, *) {
        return UIApplication.shared.connectedScenes
            .compactMap { ($0 as? UIWindowScene)?.keyWindow?.safeAreaInsets.top }
            .first ?? 0
    } else {
        return UIApplication.shared.connectedScenes
            .compactMap { ($0 as? UIWindowScene)?.windows.first?.safeAreaInsets.top }
            .first ?? 0
    }
}

// MARK: - Header Background

public struct HeaderBackground: View {
    var headerType: HeaderType = .default
    var scrollState: CGFloat
    var headerTransparent: Bool = false
    var fullScreenContent: Bool = false

    public init(
        headerType: HeaderType = .default,
        scrollState: CGFloat = 0,
        headerTransparent: Bool = false,
        fullScreenContent: Bool = false
    ) {
        self.headerType = headerType
        self.scrollState = scrollState
        self.headerTransparent = headerTransparent
        self.fullScreenContent = fullScreenContent
    }
    
    public var body: some View {
        
        let statusBarHeight = safeAreaTopInset()
        let opacity = max(0, 1 - scrollState / 200)
        let height = fullScreenContent ? 0 :  statusBarHeight + 52
        let backgroundColor = headerTransparent ? Color.clear : Colors.black01

        Group {
            switch headerType {
            case .default:
                ZStack(alignment: .bottom) {
                    Rectangle()
                        .fill(backgroundColor)
                        .opacity(headerTransparent ? 0 : opacity)
                        .frame(height: height)
                        .shadow(color: Colors.black20.opacity(0.2), radius: 10, x: 0, y: -2)
                        .background(backgroundColor)
                        .overlay(
                            headerTransparent ? AnyView(EmptyView()) :
                            AnyView(
                                Rectangle()
                                    .fill(LinearGradient(
                                        gradient: Gradient(colors: [
                                            Color(red: 1, green: 0.8, blue: 0.87),
                                            Color(red: 1, green: 0.8, blue: 0.87).opacity(0.5)
                                        ]),
                                        startPoint: .top,
                                        endPoint: .bottom))
                                    .opacity(opacity)
                                    .frame(height: height))
                        )

                    if !headerTransparent {
                        Rectangle()
                            .fill(Color.black.opacity(0.1))
                            .frame(height: 1)
                            .frame(maxWidth: .infinity)
                    }
                }

            case .extended:
                ZStack {
                    if !headerTransparent {
                        Colors.black01
                        LinearGradient(
                            gradient: Gradient(colors: [
                                Color(red: 1, green: 0.8, blue: 0.87),
                                Color(red: 1, green: 0.8, blue: 0.87).opacity(0)
                            ]),
                            startPoint: .top,
                            endPoint: .bottom
                        )
                        .opacity(opacity)
                        .frame(height: 154)
                    }
                }

            case .none:
                EmptyView()
            }
        }
    }
}

// MARK: - Header View

public struct Header: View {
    var headerType: HeaderType = .default
    var titlePosition: TitlePosition
    var title: String
    var headerRight:  (()->any View)? = {HeaderRight()}
    var goBack: (() -> Void)?
    var opacity: CGFloat = 1
    var animatedHeader: AnimatedHeader?
    var scrollState: CGFloat = 0
    var inputSearchProps: InputSearchProps?
    var tintColor: Color?

    public init(
        headerType: HeaderType = .default,
        titlePosition: TitlePosition,
        title: String,
        headerRight:  (()->any View)? = {HeaderRight()},
        goBack: (() -> Void)? = nil,
        opacity: CGFloat = 1,
        animatedHeader: AnimatedHeader? = nil,
        scrollState: CGFloat = 0,
        inputSearchProps: InputSearchProps? = nil,
        tintColor: Color? = nil
    ) {
        self.headerType = headerType
        self.titlePosition = titlePosition
        self.title = title
        self.headerRight = headerRight
        self.goBack = goBack
        self.opacity = opacity
        self.animatedHeader = animatedHeader
        self.scrollState = scrollState
        self.inputSearchProps = inputSearchProps
        self.tintColor = tintColor
    }
    
    public var body: some View {
        
        let backgroundButtonColor: Color = tintColor == Colors.black01 ? Colors.black20.opacity(0.6) : Colors.black01.opacity(0.6)
        let borderColor: Color = tintColor == Colors.black01 ? Colors.black01.opacity(0.2) : Colors.black20.opacity(0.2)

        if headerType != .none {
            VStack(spacing: 0) {
                ZStack {
                    // MARK: - Left and Right Controls
                    HStack {
                        if let goBack = goBack {
                            SwiftUI.Button(action: goBack) {
                                Circle()
                                    .stroke(borderColor, lineWidth: 0.2)
                                    .background(Circle().fill(backgroundButtonColor))
                                    .frame(width: 28, height: 28)
                                    .overlay(
                                            Icon(source: "arrow-back", size: 20, color: tintColor ?? Colors.black17)
                                    )
                            }
                        }

                        Spacer()

                        if let headerRight = headerRight {
                            AnyView(headerRight())
                        }
                    }
                    .padding(.horizontal, 12)

                    // MARK: - Title or Search
                    HStack {
                        if titlePosition == .left && goBack != nil {
                            Spacer().frame(width: 38)
                        }

                        if let inputProps = inputSearchProps {
                            InputSearch(
                                text: inputProps.$text,
                                buttonText: inputProps.buttonText,
                                showButtonText: inputProps.showButtonText,
                                showBorder: inputProps.showBorder,
                                placeholder: inputProps.placeholder,
                                onChangeText: inputProps.onChangeText,
                                onPressButtonText: inputProps.onPressButtonText,
                                error: inputProps.error,
                                disabled: inputProps.disabled,
                                icon: inputProps.icon,
                                iconColor: inputProps.iconColor,
                                onRightIconPressed: inputProps.onRightIconPressed,
                                onFocus: inputProps.onFocus,
                                onBlur: inputProps.onBlur,
                                loading: inputProps.loading,
                                fontWeight: inputProps.fontWeight,
                                keyboardType: inputProps.keyboardType
                            )
                        } else {
                            Text(title)
                                .font(.system(size: 17, weight: .bold))
                                .foregroundColor(tintColor ?? Colors.black17)
                                .frame(maxWidth: titlePosition == .center ? UIScreen.main.bounds.width - 252 : nil)
                                .frame(maxWidth: titlePosition == .center ? .infinity : UIScreen.main.bounds.width - 172, alignment: titlePosition == .center ? .center : .leading)
                                .lineLimit(1)
                        }

                        Spacer()
                    }
                    .padding(.horizontal)
                }
                .background(Color.clear)
                .frame(height: 52)
            }
        }
    }
}
