import SwiftUI
import Speech

struct ChatInputView: View {
    @EnvironmentObject private var sceneDelegate: SceneDelegate
    @StateObject private var speechRecognizer = SpeechRecognizer()
    @StateObject private var viewModel: ChatInputViewModel
    @State private var imageData: Data = .init(capacity: 0)
    @State private var source: UIImagePickerController.SourceType = .photoLibrary

    @FocusState var isKeyboardFocused: Bool
    @Binding private var isFocus: Bool
    @Binding var isUploadingDialogPresented: Bool

    init(isFocus: Binding<Bool>, isUploadingDialogPresented: Binding<Bool>) {
        self._isFocus = isFocus
        self._isUploadingDialogPresented = isUploadingDialogPresented
        self._viewModel = StateObject(wrappedValue: ChatInputViewModel())
    }

    var body: some View {
        VStack(spacing: 0) {
            Spacer()
            Divider()

            HStack(spacing: 10) {
                Spacer(minLength: 10)

                // MARK: - カメラボタン
                Button {
                    sceneDelegate.tabWindow?.isHidden = true
                    source = .camera
                    viewModel.handleMediaInput(type: .camera)
                } label: {
                    Image(systemName: "camera")
                        .resizable()
                        .frame(width: 20, height: 20)
                        .padding(5)
                }

                //MARK: - メディア選択メニュー
                Menu {
                    Button {
                        sceneDelegate.tabWindow?.isHidden = true
                        source = .photoLibrary
                        viewModel.handleMediaInput(type: .photoLibrary)
                    } label: {
                        Label("Photo Library", systemImage: "photo.on.rectangle")
                    }

                    Button {
                        sceneDelegate.tabWindow?.isHidden = true
                        viewModel.handleMediaInput(type: .photoLibrary)
                    } label: {
                        Label("Choose File", systemImage: "folder")
                    }
                } label: {
                    Image(systemName: "photo")
                        .resizable()
                        .frame(width: 20, height: 20)
                        .padding(5)
                }

                //MARK: - 音声入力ボタン
                Button {
                    viewModel.isRecording.toggle()
                    if viewModel.isRecording {
                        speechRecognizer.transcribedText = ""
                        speechRecognizer.startRecording()
                    } else {
                        speechRecognizer.stopRecording()
                        viewModel.inputText = speechRecognizer.transcribedText
                    }
                } label: {
                    Image(systemName: viewModel.isRecording ? "mic.fill" : "mic")
                        .resizable()
                        .frame(width: 20, height: 20)
                        .padding(5)
                }

                //MARK: - テキスト入力
                TextEditor(text: $viewModel.inputText)
                    .focused($isKeyboardFocused)
                    .font(FontStyle.DefaultText.font)
                    .scrollContentBackground(Visibility.hidden)
                    .foregroundColor(ColorSet.BodyChat.color)
                    .background(ColorSet.ChatBaloon.color)
                    .cornerRadius(5)
                    .frame(height: viewModel.textViewHeight)
                    .onAppear {
                        viewModel.recalculateHeight()
                    }
                    .onChange(of: viewModel.inputText) { _ in
                        viewModel.recalculateHeight()
                    }
                    .overlay(alignment: .topLeading) {
                        if viewModel.inputText.isEmpty {
                            Text("Enter your message")
                                .font(FontStyle.DefaultText.font)
                                .foregroundColor(ColorSet.BodyNotice.color)
                                .background(ColorSet.ChatBaloon.color)
                                .padding(10)
                        }
                    }
                    .padding(EdgeInsets(top: 2, leading: 10, bottom: 3, trailing: 0))
                    .onChange(of: isKeyboardFocused) { isFocused in
                        sceneDelegate.tabWindow?.isHidden = isFocused
                        viewModel.isKeyboardFocused = isFocused
                        isFocus = isFocused
                    }
                    .onChange(of: viewModel.isKeyboardFocused) { isFocused in
                        isKeyboardFocused = isFocused
                    }

                //MARK: - 送信ボタン
                Button {
                    viewModel.sendChatMessage()
                } label: {
                    Image("send")
                        .resizable()
                        .frame(width: 20, height: 20)
                        .padding(5)
                        .opacity(viewModel.inputText.isEmpty ? 0.5 : 1.0)
                }
                .padding(.vertical, 6)
                .padding(.trailing, 11)
                .disabled(viewModel.inputText.isEmpty)
            }
            .background(ColorSet.BackgroundSecondary.color)

            // MARK: - 画像ピッカー
            .fullScreenCover(isPresented: $viewModel.isImagePickerPresented, onDismiss: {
                sceneDelegate.tabWindow?.isHidden = false
                isKeyboardFocused = false
                viewModel.isKeyboardFocused = false

                if let image = UIImage(data: imageData) {
                    viewModel.sendImageToTemporary(image)
                } else if !imageData.isEmpty {
                    viewModel.sendVideoToTemporary(imageData)
                }
            }) {
                CameraView(imageData: $imageData, source: $source, isActionSheet: .constant(false), isImagePicker: $viewModel.isImagePickerPresented)
            }

            //MARK: - File Importer
            .fileImporter(isPresented: $viewModel.isFileImporterPresented, allowedContentTypes: [.png, .jpeg, .pdf]) { result in
                switch result {
                case .success(let url):
                    guard let data = try? Data(contentsOf: url),
                          let image = UIImage(data: data),
                          let jpegData = image.jpegData(compressionQuality: 1.0) else { return }

                    let uploadImage = ReqUploadImage(
                        shipId: Preferences.shipId,
                        messageId: UUID().uuidString,
                        location: 2,
                        from: Preferences.UserName,
                        fromId: String(SharingData.my.id),
                        files: jpegData
                    )

                    viewModel.sendChatImage(uploadImage)
                case .failure:
                    print("File import failed")
                }
            }

            .onChange(of: isFocus) { focus in
                if !focus {
                    isKeyboardFocused = false
                    viewModel.isKeyboardFocused = false
                }
            }

            .onReceive(speechRecognizer.$transcribedText) { newText in
                if viewModel.isRecording {
                    viewModel.inputText = newText
                }
            }
        }
        .onAppear {
            isKeyboardFocused = viewModel.isKeyboardFocused
        }
        .frame(maxHeight: 55)
        .alert("Error", isPresented: $viewModel.isChatAlert) {
            Button("OK") {
                if viewModel.isSignalrRestart {
                    SignalR().startConnection()
                    viewModel.isSignalrRestart = false
                }
            }
        } message: {
            Text("The message could not be sent.")
        }
        .alert("Upload failed", isPresented: $viewModel.isRetryDialogPresented) {
            Button("retry") {
                if let imageToRetry = viewModel.failedUploadImage {
                    viewModel.sendChatImage(imageToRetry)
                }
            }

            Button("Cancel", role: .cancel) {
                viewModel.failedUploadImage = nil
                viewModel.isRetryDialogPresented = false
                SharingData.message.messages.removeAll { $0.messageId.caseInsensitiveCompare(viewModel.tempId) == .orderedSame }
            }
        } message: {
            Text("Image upload failed. Would you like to try again?")
        }
        .alert("Upload failed", isPresented: $viewModel.isRetryDialogPresented) {
            Button("retry") {
                if let videoToRetry = viewModel.failedUploadImage {
                    viewModel.sendChatVideo(videoToRetry)
                }
            }

            Button("Cancel", role: .cancel) {
                viewModel.failedUploadImage = nil
                viewModel.isRetryDialogPresented = false
                SharingData.message.messages.removeAll { $0.messageId.caseInsensitiveCompare(viewModel.tempId) == .orderedSame }
            }
        } message: {
            Text("Video upload failed. Would you like to try again?")
        }
    }
}

#Preview {
    ChatInputView(isFocus: .constant(false), isUploadingDialogPresented: .constant(false))
        .environmentObject(SceneDelegate())
}
