import AppAccount
import DesignSystem
import EmojiText
import Env
import Models
import Network
import NukeUI
import PhotosUI
import StoreKit
import SwiftUI
import UIKit

extension StatusEditor {
  @MainActor
  public struct MainView: View {
    @Environment(AppAccountsManager.self) private var appAccounts
    @Environment(CurrentAccount.self) private var currentAccount
    @Environment(Theme.self) private var theme

    @State private var presentationDetent: PresentationDetent = .large
    @State private var mainSEVM: ViewModel
    @State private var followUpSEVMs: [ViewModel] = []
    @FocusState private var isSpoilerTextFocused: UUID? // connect CoreEditor and StatusEditorAccessoryView
    @State private var editingMediaContainer: MediaContainer?
    @State private var scrollID: UUID?

    @FocusState private var editorFocusState: EditorFocusState?

    private var focusedSEVM: ViewModel {
      if case let .followUp(id) = editorFocusState,
         let sevm = followUpSEVMs.first(where: { $0.id == id })
      { return sevm }

      return mainSEVM
    }

    public init(mode: ViewModel.Mode) {
      _mainSEVM = State(initialValue: ViewModel(mode: mode))
    }

    public var body: some View {
      @Bindable var focusedSEVM = focusedSEVM

      NavigationStack {
        ScrollView {
          VStackLayout(spacing: 0) {
            EditorView(
              viewModel: mainSEVM,
              followUpSEVMs: $followUpSEVMs,
              editingMediaContainer: $editingMediaContainer,
              isSpoilerTextFocused: $isSpoilerTextFocused,
              editorFocusState: $editorFocusState,
              assignedFocusState: .main,
              isMain: true
            )
            .id(mainSEVM.id)

            ForEach(followUpSEVMs) { sevm in
              @Bindable var sevm: ViewModel = sevm

              EditorView(
                viewModel: sevm,
                followUpSEVMs: $followUpSEVMs,
                editingMediaContainer: $editingMediaContainer,
                isSpoilerTextFocused: $isSpoilerTextFocused,
                editorFocusState: $editorFocusState,
                assignedFocusState: .followUp(index: sevm.id),
                isMain: false
              )
              .id(sevm.id)
            }
          }
          .scrollTargetLayout()
        }
        .scrollPosition(id: $scrollID, anchor: .top)
        .animation(.bouncy(duration: 0.3), value: editorFocusState)
        .animation(.bouncy(duration: 0.3), value: followUpSEVMs)
        #if !os(visionOS)
        .background(theme.primaryBackgroundColor)
        #endif
        .safeAreaInset(edge: .bottom) {
          AutoCompleteView(viewModel: focusedSEVM)
        }
        #if os(visionOS)
        .ornament(attachmentAnchor: .scene(.bottom)) {
          AccessoryView(isSpoilerTextFocused: $isSpoilerTextFocused, focusedSEVM: focusedSEVM, followUpSEVMs: $followUpSEVMs)
            }
        #else
        .safeAreaInset(edge: .bottom) {
          if presentationDetent == .large || presentationDetent == .medium {
            AccessoryView(isSpoilerTextFocused: $isSpoilerTextFocused, focusedSEVM: focusedSEVM, followUpSEVMs: $followUpSEVMs)
          }
        }
        #endif
        .accessibilitySortPriority(1) // Ensure that all elements inside the `ScrollView` occur earlier than the accessory views
        .navigationTitle(focusedSEVM.mode.title)
        .navigationBarTitleDisplayMode(.inline)
        .toolbar { ToolbarItems(mainSEVM: mainSEVM,
                                focusedSEVM: focusedSEVM,
                                followUpSEVMs: followUpSEVMs) }
        .toolbarBackground(.visible, for: .navigationBar)
        .alert(
          "status.error.posting.title",
          isPresented: $focusedSEVM.showPostingErrorAlert,
          actions: {
            Button("OK") {}
          }, message: {
            Text(mainSEVM.postingError ?? "")
          }
        )
        .interactiveDismissDisabled(mainSEVM.shouldDisplayDismissWarning)
        .onChange(of: appAccounts.currentClient) { _, newValue in
          if mainSEVM.mode.isInShareExtension {
            currentAccount.setClient(client: newValue)
            mainSEVM.client = newValue
            for post in followUpSEVMs {
              post.client = newValue
            }
          }
        }
        .onDrop(of: StatusEditor.UTTypeSupported.types(), delegate: focusedSEVM)
        .onChange(of: currentAccount.account?.id) {
          mainSEVM.currentAccount = currentAccount.account
          for p in followUpSEVMs {
            p.currentAccount = mainSEVM.currentAccount
          }
        }
        .onChange(of: mainSEVM.visibility) {
          for p in followUpSEVMs {
            p.visibility = mainSEVM.visibility
          }
        }
        .onChange(of: followUpSEVMs.count) { oldValue, newValue in
          if oldValue < newValue {
            Task {
              try? await Task.sleep(for: .seconds(0.1))
              withAnimation(.bouncy(duration: 0.5)) {
                scrollID = followUpSEVMs.last?.id
              }
            }
          }
        }
      }
      .sheet(item: $editingMediaContainer) { container in
        StatusEditor.MediaEditView(viewModel: focusedSEVM, container: container)
      }
      .presentationDetents([.large, .height(100)], selection: $presentationDetent)
      .presentationBackgroundInteraction(.enabled)
    }
  }

}
