import ComponentLibrary
import Localization
import SwiftUI

struct CyclePlaceholderTextFieldStyle: TextFieldStyle {
    @FocusState private var focused: Bool
    @State private var placeholderIndex: Int = 0
    @State private var animate = false

    private let interval: TimeInterval = 2.5
    private let placeholders: [String]
    private let typography: TypographyV1
    private let maxWidth: CGFloat?
    private let maxHeight: CGFloat?

    public init(
        placeholders: [String],
        typography: TypographyV1 = .createClipTextPlaceholder,
        maxWidth: CGFloat? = .infinity,
        maxHeight: CGFloat? = .infinity
    ) {
        self.placeholders = placeholders.filter { !$0.isEmpty }
        self.typography = typography
        self.maxWidth = maxWidth
        self.maxHeight = maxHeight
    }

    func _body(configuration: TextField<_Label>) -> some View {
        let text = Mirror(reflecting: configuration)
            .descendant("_text") as! Binding<String>

        configuration
            .typographyV1(typography)
            .foregroundStyle(Color.SemanticV1.textPrimary)
            .accentColor(.SemanticV1.textLink)
            .focused($focused)
            .frame(maxWidth: maxWidth, maxHeight: maxHeight, alignment: .top)
            .overlay {
                if !focused {
                    Color.clear
                        .contentShape(.rect)
                        .onTapGesture { focused = true }
                }
            }
            .background(alignment: .top) {
                ZStack {
                    if text.wrappedValue.isEmpty {
                        let start = Date()
                        TimelineView(.periodic(from: start, by: interval)) { context in
                            let index = (Int(context.date.timeIntervalSince(start) / interval) % (placeholders.count))
                            ZStack {
                                Text(placeholders[index])
                                    .id(index)
                                    .transition(
                                        .asymmetric(
                                            insertion: .move(edge: .bottom).combined(with: .opacity),
                                            removal: .move(edge: .top).combined(with: .opacity)
                                        )
                                    )
                            }
                            .animation(.default, value: index)
                        }
                        .typographyV1(typography)
                        .foregroundStyle(Color.SemanticV1.textTertiary)
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .transition(.opacity)
                        .onAppear { startAnimation() }
                        .onDisappear { stopAnimation() }
                    }
                }
                .animation(.default, value: text.wrappedValue.isEmpty)
            }
            .clipped()
            .padding(8)
    }

    private func startAnimation() {
        placeholderIndex = 0
        animate = true
    }

    private func stopAnimation() {
        placeholderIndex = 0
        animate = false
    }
}

private extension TypographyV1 {
    static let createClipTextPlaceholder: TypographyV1 = .init(
        name: "Create Clip Text Placeholder",
        size: 24,
        style: .title,
        weight: .neueMontrealMedium,
        lineHeight: 32
    )
}
