import SwiftUI
import SFSafeSymbols

@main
struct MainView: App {

    private let sidebarWidth: CGFloat = 250

    private let detailWidth: CGFloat = 300

    @StateObject
    private var server: WebServer = .init(port: 8000)

    @StateObject
    private var content: Content = .init()

    @StateObject
    private var upload: RemotePush = .init()

    @StateObject
    private var notifications: NotificationSender = .init()

    @StateObject
    private var selection: SelectedContent = .init()

    @State
    private var showAddSheet = false

    @State
    private var showStorageStatusSheet = false

    @State
    private var showSettingsSheet = false

    @State
    private var showGenerationSheet = false

    @State
    private var showPreviewSheet = false

    @State
    private var showUploadSheet = false

    @State
    private var showNotificationsSheet = false

    @ViewBuilder
    var sidebar: some View {
        switch selection.tab {
        case .posts: PostListView()
        case .pages: PageListView()
        case .tags: TagListView()
        case .files: FileListView(selectedFile: $selection.file)
        }
    }

    @ViewBuilder
    var viewContent: some View {
        switch selection.tab {
        case .posts:
            SelectedContentView<PostContentView>(selected: $selection.post)
        case .pages:
            SelectedContentView<PageContentView>(selected: $selection.page)
        case .tags:
            SelectedContentView<TagContentView>(selected: $selection.tag)
        case .files:
            SelectedContentView<FileContentView>(selected: $selection.file)
        }
    }

    @ViewBuilder
    var detail: some View {
        switch selection.tab {
        case .posts:
            SelectedDetailView<PostDetailView>(selected: $selection.post)
        case .pages:
            SelectedDetailView<PageDetailView>(selected: $selection.page)
        case .tags:
            SelectedDetailView<TagDetailView>(selected: $selection.tag)
        case .files:
            SelectedDetailView<FileDetailView>(selected: $selection.file)
        }
    }

    @ViewBuilder
    var addItemSheet: some View {
        switch selection.tab {
        case .posts:
            AddPostView(selected: $selection.post)
        case .pages:
            AddPageView(selected: $selection.page)
        case .tags:
            AddTagView(selected: $selection.tag)
        case .files:
            AddFileView(selectedFile: $selection.file)
        }
    }

    var body: some Scene {
        WindowGroup {
            NavigationSplitView {
                sidebar
                    .navigationSplitViewColumnWidth(min: sidebarWidth, ideal: sidebarWidth, max: sidebarWidth)
                    .toolbar {
                        ToolbarItem(placement: .automatic) {
                            Button(action: { showAddSheet = true }) {
                                Label("Add", systemSymbol: .plus)
                            }
                        }
                    }
            } content: {
                viewContent
                    .toolbar {
                        ToolbarItem(placement: .navigation) {
                            HStack {
                                Picker("", selection: $selection.tab) {
                                    Text("Posts").tag(MainViewTab.posts)
                                    Text("Pages").tag(MainViewTab.pages)
                                    Text("Tags").tag(MainViewTab.tags)
                                    Text("Files").tag(MainViewTab.files)
                                }.pickerStyle(.segmented)
                            }.frame(minWidth: 400)
                        }
                    }
            } detail: {
                detail
                    .navigationSplitViewColumnWidth(min: detailWidth, ideal: detailWidth, max: detailWidth)
            }
            .toolbar {
                ToolbarItem {
                    Picker("", selection: $selection.language) {
                        Text("English")
                            .tag(ContentLanguage.english)
                        Text("German")
                            .tag(ContentLanguage.german)
                    }
                    .pickerStyle(.segmented)
                    .frame(minWidth: 200)
                }
                ToolbarItem {
                    Button(action: { showSettingsSheet = true }) {
                        Image(systemSymbol: .gearshape)
                    }
                }
                ToolbarItem {
                    Button(action: { showGenerationSheet = true }) {
                        if content.isGeneratingWebsite {
                            ProgressView()
                                .scaleEffect(0.6)
                                .frame(width: 20, height: 20, alignment: .center)
                        } else {
                            Image(systemSymbol: .globe)
                                .frame(width: 20, height: 20, alignment: .center)
                        }
                    }
                }
                ToolbarItem {
                    Button(action: { showPreviewSheet = true }) {
                        Image(systemSymbol: .eye)
                    }
                }
                ToolbarItem {
                    Button(action: { showUploadSheet = true }) {
                        Image(systemSymbol: .squareAndArrowUp)
                    }
                }
                ToolbarItem {
                    Button(action: { showNotificationsSheet = true }) {
                        Image(systemSymbol: .bell)
                    }
                }
                ToolbarItem {
                    Button(action: {  showStorageStatusSheet = true }) {
                        Image(systemSymbol: content.saveState.symbol)
                            .foregroundStyle(content.saveState.color)
                    }
                }
            }
            .navigationTitle("")
            .environment(\.language, selection.language)
            .environmentObject(content)
            .environmentObject(selection)
            .onAppear(perform: loadContent)
            .sheet(isPresented: $showAddSheet) {
                addItemSheet
                    .environment(\.language, selection.language)
                    .environmentObject(content)
                    .environmentObject(selection)
            }
            .sheet(isPresented: $showStorageStatusSheet) {
                StorageStatusView(isPresented: $showStorageStatusSheet)
                    .environmentObject(content)
            }
            .sheet(isPresented: $showSettingsSheet) {
                SettingsSheet(language: $selection.language)
                    .environmentObject(content)
                    .presentedWindowStyle(.titleBar)
            }
            .sheet(isPresented: $showGenerationSheet) {
                GenerationContentView()
                    .environmentObject(content)
                    .environmentObject(selection)
            }
            .sheet(isPresented: $showPreviewSheet) {
                WebsitePreviewSheet()
                    .environmentObject(content)
                    .environmentObject(server)
            }
            .sheet(isPresented: $showUploadSheet) {
                UploadSheet()
                    .environmentObject(content)
                    .environmentObject(upload)
            }
            .sheet(isPresented: $showNotificationsSheet) {
                NotificationSheet()
                    .environmentObject(content)
                    .environmentObject(notifications)
            }
        }
    }

    private func loadContent() {
        guard content.storage.contentScope != nil else {
            showStorageStatusSheet = true
            return
        }
        content.loadFromDisk {
            prepareAfterLoad()
            if !content.storageErrors.isEmpty {
                self.showStorageStatusSheet = true
            }
        }
    }

    private func prepareAfterLoad() {
        if selection.post == nil {
            selection.post = content.posts.first
        }
        if selection.page == nil {
            selection.page = content.pages.first
        }
        if selection.tag == nil {
            selection.tag = content.tags.first
        }
        if selection.file == nil {
            selection.file = content.files.first
        }
    }
}

