import Env
import Models
import StoreKit
import SwiftUI
import DesignSystem

extension StatusEditor {
  @MainActor
  struct ToolbarItems: ToolbarContent {
    @State private var isLanguageConfirmPresented = false
    @State private var isDismissAlertPresented: Bool = false
    @State private var isDraftsSheetDisplayed: Bool = false
    
    let mainSEVM: ViewModel
    let focusedSEVM: ViewModel
    let followUpSEVMs: [ViewModel]

    @Environment(\.modelContext) private var context
    @Environment(UserPreferences.self) private var preferences
    @Environment(Theme.self) private var theme
    
    #if targetEnvironment(macCatalyst)
      @Environment(\.dismissWindow) private var dismissWindow
    #else
      @Environment(\.dismiss) private var dismiss
    #endif

    var body: some ToolbarContent {
      if !mainSEVM.mode.isInShareExtension {
        ToolbarItem(placement: .navigationBarTrailing) {
          Button {
            isDraftsSheetDisplayed = true
          } label: {
            Image(systemName: "pencil.and.list.clipboard")
          }
          .accessibilityLabel("accessibility.editor.button.drafts")
          .popover(isPresented: $isDraftsSheetDisplayed) {
            if UIDevice.current.userInterfaceIdiom == .phone {
              draftsListView
                .presentationDetents([.medium])
            } else {
              draftsListView
                .frame(width: 400, height: 500)
            }
          }
        }
      }
        
      ToolbarItem(placement: .navigationBarTrailing) {
        Button {
          Task {
            mainSEVM.evaluateLanguages()
            if preferences.autoDetectPostLanguage, let _ = mainSEVM.languageConfirmationDialogLanguages {
              isLanguageConfirmPresented = true
            } else {
              await postAllStatus()
            }
          }
        } label: {
          Image(systemName: "paperplane.fill")
            .bold()
        }
        .buttonStyle(.borderedProminent)
        .disabled(!mainSEVM.canPost || mainSEVM.isPosting)
        .keyboardShortcut(.return, modifiers: .command)
        .confirmationDialog("", isPresented: $isLanguageConfirmPresented, actions: {
          languageConfirmationDialog
        })
      }

      ToolbarItem(placement: .navigationBarLeading) {
        Button {
          if mainSEVM.shouldDisplayDismissWarning {
            isDismissAlertPresented = true
          } else {
            close()
            NotificationCenter.default.post(name: .shareSheetClose,
                                            object: nil)
          }
        } label: {
          Image(systemName: "xmark")
        }
        .keyboardShortcut(.cancelAction)
        .confirmationDialog(
          "",
          isPresented: $isDismissAlertPresented,
          actions: {
            Button("status.draft.delete", role: .destructive) {
              close()
              NotificationCenter.default.post(name: .shareSheetClose,
                                              object: nil)
            }
            Button("status.draft.save") {
              context.insert(Draft(content: mainSEVM.statusText.string))
              close()
              NotificationCenter.default.post(name: .shareSheetClose,
                                              object: nil)
            }
            Button("action.cancel", role: .cancel) {}
          }
        )
      }
    }

    @discardableResult
    private func postStatus(with model: ViewModel, isMainPost: Bool) async -> Status? {
      let status = await model.postStatus()

      if status != nil, isMainPost {
        close()
        SoundEffectManager.shared.playSound(.tootSent)
        NotificationCenter.default.post(name: .shareSheetClose, object: nil)
        #if !targetEnvironment(macCatalyst)
          if !mainSEVM.mode.isInShareExtension, !preferences.requestedReview {
            if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
              SKStoreReviewController.requestReview(in: scene)
            }
            preferences.requestedReview = true
          }
        #endif
      }

      return status
    }

    private func postAllStatus() async {
      guard var latestPost = await postStatus(with: mainSEVM, isMainPost: true) else { return }
      for p in followUpSEVMs {
        p.mode = .replyTo(status: latestPost)
        guard let post = await postStatus(with: p, isMainPost: false) else {
          break
        }
        latestPost = post
      }
    }

    #if targetEnvironment(macCatalyst)
      private func close() { dismissWindow() }
    #else
      private func close() { dismiss() }
    #endif

    @ViewBuilder
    private var languageConfirmationDialog: some View {
      if let (detected: detected, selected: selected) = mainSEVM.languageConfirmationDialogLanguages,
         let detectedLong = Locale.current.localizedString(forLanguageCode: detected),
         let selectedLong = Locale.current.localizedString(forLanguageCode: selected)
      {
        Button("status.editor.language-select.confirmation.detected-\(detectedLong)") {
          mainSEVM.selectedLanguage = detected
          Task { await postAllStatus() }
        }
        Button("status.editor.language-select.confirmation.selected-\(selectedLong)") {
          mainSEVM.selectedLanguage = selected
          Task { await postAllStatus() }
        }
        Button("action.cancel", role: .cancel) {
          mainSEVM.languageConfirmationDialogLanguages = nil
        }
      } else {
        EmptyView()
      }
    }
    
    private var draftsListView: some View {
      DraftsListView(selectedDraft: .init(get: {
        nil
      }, set: { draft in
        if let draft {
          focusedSEVM.insertStatusText(text: draft.content)
        }
      }))
    }
  }
}
