import SwiftUI
import Speech

enum MediaInputType {
    case none
    case camera
    case photoLibrary
    case fileImport
}

struct ChatInputView: View {
    @EnvironmentObject private var sceneDelegate: SceneDelegate
    @ObservedObject var sessionUploadImage = SessionUploadImage()
    @StateObject private var speechRecognizer = SpeechRecognizer()

    @State private var inputText = ""
    @State private var isChatAlert = false
    @State private var imageData: Data = .init(capacity: 0)
    @State private var mediaInputType: MediaInputType = .none
    @State private var isImagePickerPresented = false
    @State private var isFileImporterPresented = false
    @State private var source: UIImagePickerController.SourceType = .photoLibrary
    @State private var isSignalrRestart = false
    @State private var isUploadingDialogPresented = false
    @State private var failedUploadImage: ReqUploadImage? = nil
    @State private var isRetryDialogPresented = false
    @State private var isRecording = false
    @FocusState private var isKeyboardFocused: Bool
    @Binding var isFocus: Bool

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

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

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

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

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

                //MARK: - テキスト入力
                TextField("", text: $inputText, onEditingChanged: { isEditing in
                    sceneDelegate.tabWindow?.isHidden = isEditing
                    isFocus = true
                })
                .focused($isKeyboardFocused)
                .font(FontStyle.SupplementText.font)
                .foregroundColor(ColorSet.BodyChat.color)
                .padding(10)
                .background(ColorSet.ChatForm.color)
                .cornerRadius(5)
                .padding(.vertical, 10)
                .padding(.leading, 10)

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

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

                if let image = UIImage(data: imageData),
                   let jpegData = image.jpegData(compressionQuality: 1.0) {

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

                    sendChatImage(uploadImage)
                }
            }) {
                CameraView(imageData: $imageData, source: $source, isActionSheet: .constant(false), isImagePicker: $isImagePickerPresented)
            }

            //MARK: - File Importer
            .fileImporter(isPresented: $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
                    )

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

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

            .onReceive(speechRecognizer.$transcribedText) { newText in
                if isRecording {
                    inputText = newText
                }
            }
        }
        .frame(maxHeight: 55)
        .alert("Error", isPresented: $isChatAlert) {
            Button("OK") {
                if isSignalrRestart {
                    SignalR().startConnection()
                    isSignalrRestart = false
                }
            }
        } message: {
            Text("The message could not be sent.")
        }
        .alert("Uploading...", isPresented: $isUploadingDialogPresented) {
            ProgressView(value: sessionUploadImage.progress)
                .progressViewStyle(LinearProgressViewStyle())
                .padding()

            Button("Cancel") {
                sessionUploadImage.cancelUpload()
                isUploadingDialogPresented = false
            }
        }
        .alert("Upload failed", isPresented: $isRetryDialogPresented) {
            Button("retry") {
                if let imageToRetry = failedUploadImage {
                    sendChatImage(imageToRetry)
                }
            }

            Button("Cancel", role: .cancel) {
                failedUploadImage = nil
                isRetryDialogPresented = false
            }
        } message: {
            Text("Image upload failed. Would you like to try again?")
        }
    }

    // MARK: - Send Chat Image
    func sendChatImage(_ uploadImage: ReqUploadImage) {
        Task {
            do {
                isUploadingDialogPresented = true
                let response = try await sessionUploadImage.requestUploadImage(uploadImage)
                print("Upload success: \(response)")

                let serverSession = ServerSession()
                _ = serverSession.fromJSON(resultData: response, resltType: ResLogin.self)

                sessionUploadImage.progress = 0.0 // 完了後リセット
                isUploadingDialogPresented = false
            } catch {
                print("Upload failed: \(error)")
                sessionUploadImage.progress = 0.0 // エラー時もリセット

                isUploadingDialogPresented = false
                failedUploadImage = uploadImage
                isRetryDialogPresented = true
            }
        }
    }

    // MARK: - Send Chat Message
    func sendChatMessage() {
        guard !SharingData.message.sendInf else { return }

        isRecording = false

        SignalR().chatMessage(message: inputText, completion: responseChatMessage)
        SharingData.message.sendInf = true

        DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
            restartChatMessage()
        }
    }

    // MARK: - Chat Response
    func responseChatMessage(error: Error?) {
        SharingData.message.sendInf = false

        if let error = error {
            print("Chat error: \(error)")
            isChatAlert = true
        } else {
            isKeyboardFocused = false
            inputText = ""
        }
    }

    // MARK: - Restart Chat if No Response
    func restartChatMessage() {
        if SharingData.message.sendInf {
            SignalR().stopConnection()
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                isSignalrRestart = true
            }
        }
    }
}

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