//
//  DynamicTextInput.swift
//  lichunWebsocket
//
//  Dynamic text input using UITextView for precise height control
//

import SwiftUI
import UIKit

struct DynamicTextInput: View {
    @Binding var text: String
    let canSend: Bool
    let onSend: () -> Void
    var isInputFocused: Binding<Bool>?

    @FocusState private var isFocused: Bool
    @State private var isSending: Bool = false

    var body: some View {
        HStack(alignment: .bottom, spacing: AppSpacing.sm) {
            // Text input
            DynamicTextView(text: $text, isFocused: $isFocused, isInputFocused: isInputFocused)
                .background(
                    LinearGradient(
                        colors: [
                            AppColors.surfaceElevated,
                            AppColors.surfaceSubtle
                        ],
                        startPoint: .top,
                        endPoint: .bottom
                    )
                )
                .cornerRadius(AppSpacing.inputCornerRadius)
                .overlay(
                    RoundedRectangle(cornerRadius: AppSpacing.inputCornerRadius)
                        .strokeBorder(
                            isFocused ? AppColors.primary.opacity(0.25) : AppColors.secondaryText.opacity(0.12),
                            lineWidth: 1.5
                        )
                )
                .shadow(
                    color: isFocused ? AppColors.primary.opacity(0.08) : Color.black.opacity(0.03),
                    radius: isFocused ? 8 : 4,
                    x: 0,
                    y: 2
                )
                .animation(.spring(response: 0.3, dampingFraction: 0.7), value: isFocused)

            // Send button
            Button(action: {
                if canSend && !text.isEmpty {
                    // Haptic feedback
                    let generator = UIImpactFeedbackGenerator(style: .medium)
                    generator.impactOccurred()

                    // Scale animation
                    withAnimation(.spring(response: 0.3, dampingFraction: 0.5)) {
                        isSending = true
                    }

                    // Call send
                    onSend()

                    // Reset animation
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                        withAnimation {
                            isSending = false
                        }
                    }
                }
            }) {
                ZStack {
                    Circle()
                        .fill(
                            canSend && !text.isEmpty
                                ? LinearGradient(
                                    colors: [AppColors.primary, AppColors.accent],
                                    startPoint: .topLeading,
                                    endPoint: .bottomTrailing
                                )
                                : LinearGradient(
                                    colors: [AppColors.disabledText],
                                    startPoint: .topLeading,
                                    endPoint: .bottomTrailing
                                )
                        )
                        .frame(width: AppSpacing.sendButtonSize, height: AppSpacing.sendButtonSize)

                    Image(systemName: "arrow.up")
                        .font(.system(size: 18, weight: .bold))
                        .foregroundColor(.white)
                        .rotationEffect(.degrees(isSending ? -45 : 0))
                }
            }
            .disabled(!canSend || text.isEmpty || isSending)
            .accessibilityLabel("Send message")
            .accessibilityHint(canSend ? "Sends your typed message" : "You need 10 energy to send a message")
            .scaleEffect(isSending ? 0.85 : (canSend && !text.isEmpty ? 1.0 : 0.9))
            .animation(.spring(response: 0.3, dampingFraction: 0.6), value: canSend)
            .animation(.spring(response: 0.3, dampingFraction: 0.6), value: text.isEmpty)
            .animation(.spring(response: 0.3, dampingFraction: 0.5), value: isSending)
        }
        .padding(.horizontal, AppSpacing.md)
        .padding(.vertical, AppSpacing.sm)
        .background(
            ZStack {
                AppColors.background

                LinearGradient(
                    colors: [
                        Color.black.opacity(0.03),
                        Color.clear
                    ],
                    startPoint: .top,
                    endPoint: .bottom
                )
                .frame(height: 20)
                .offset(y: -10)
            }
        )
    }
}

// MARK: - DynamicTextView (UIViewRepresentable)

private struct DynamicTextView: UIViewRepresentable {
    @Binding var text: String
    @FocusState.Binding var isFocused: Bool
    var isInputFocused: Binding<Bool>?

    let minHeight: CGFloat = 40
    let maxHeight: CGFloat = 120

    func makeUIView(context: Context) -> UITextView {
        let textView = UITextView()
        textView.delegate = context.coordinator

        // Configure for dynamic sizing
        textView.isScrollEnabled = false
        textView.backgroundColor = .clear
        textView.textContainerInset = UIEdgeInsets(top: 10, left: 8, bottom: 10, right: 8)
        textView.textContainer.lineFragmentPadding = 0

        // Text appearance
        textView.font = UIFont.systemFont(ofSize: 17)
        textView.textColor = UIColor(AppColors.primaryText)
        textView.tintColor = UIColor(AppColors.primary)
        textView.autocorrectionType = .yes
        textView.autocapitalizationType = .sentences
        textView.keyboardType = .default
        textView.returnKeyType = .default

        // Setup placeholder
        context.coordinator.setupPlaceholder(in: textView)
        textView.accessibilityLabel = "Message"
        textView.accessibilityHint = "Type a message"

        return textView
    }

    func updateUIView(_ textView: UITextView, context: Context) {
        if textView.text != text {
            textView.text = text
            context.coordinator.updatePlaceholder()
        }
        // Keep the binding reference up to date
        context.coordinator.isInputFocused = isInputFocused
    }

    func sizeThatFits(_ proposal: ProposedViewSize, uiView: UITextView, context: Context) -> CGSize? {
        let width = proposal.width ?? 300

        let size = uiView.sizeThatFits(CGSize(width: width, height: .infinity))
        let height = max(minHeight, min(size.height, maxHeight))

        DispatchQueue.main.async {
            uiView.isScrollEnabled = size.height > maxHeight
        }

        return CGSize(width: width, height: height)
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(text: $text, isFocused: $isFocused, isInputFocused: isInputFocused)
    }

    class Coordinator: NSObject, UITextViewDelegate {
        @Binding var text: String
        @FocusState.Binding var isFocused: Bool
        var isInputFocused: Binding<Bool>?
        private var placeholderLabel: UILabel?

        init(text: Binding<String>, isFocused: FocusState<Bool>.Binding, isInputFocused: Binding<Bool>?) {
            self._text = text
            self._isFocused = isFocused
            self.isInputFocused = isInputFocused
        }

        func setupPlaceholder(in textView: UITextView) {
            let label = UILabel()
            label.text = "Type a message..."
            label.font = textView.font
            label.textColor = UIColor(AppColors.disabledText)
            label.translatesAutoresizingMaskIntoConstraints = false
            textView.addSubview(label)

            NSLayoutConstraint.activate([
                label.leadingAnchor.constraint(equalTo: textView.leadingAnchor, constant: 12),
                label.topAnchor.constraint(equalTo: textView.topAnchor, constant: 10)
            ])

            placeholderLabel = label
            updatePlaceholder()
        }

        func updatePlaceholder() {
            placeholderLabel?.isHidden = !text.isEmpty
        }

        func textViewDidChange(_ textView: UITextView) {
            text = textView.text
            updatePlaceholder()
        }

        func textViewDidBeginEditing(_ textView: UITextView) {
            isFocused = true
            isInputFocused?.wrappedValue = true
            updatePlaceholder()
        }

        func textViewDidEndEditing(_ textView: UITextView) {
            isFocused = false
            isInputFocused?.wrappedValue = false
        }
    }
}

// MARK: - Preview
#Preview {
    struct PreviewWrapper: View {
        @State private var text = ""

        var body: some View {
            VStack {
                Spacer()

                DynamicTextInput(
                    text: $text,
                    canSend: true,
                    onSend: {
                        print("Sent: \(text)")
                        text = ""
                    }
                )
            }
            .background(AppColors.background)
        }
    }

    return PreviewWrapper()
}
