import SwiftUI
import SFSafeSymbols

/**
    **Content**
 - iPhone Backgrounds: Add page, html

    **UI**
 - Image search: Add view to see all images and filter
 - Pages: Show linking posts
 - Page Content: Show all results of `PageGenerationResults`
 - Files: Show usages of file
 - Images: Show list of generated versions

    **Features**
 - Files: Optional Property `customFilePath` for external files to place them in another location
 - Files: Property `version` and `sourceUrl` to track asset files
 - Posts: Generate separate pages for posts to link to
 - Settings: Introduce `Authors` (`name`, `image`, `description`)
 - Page: Property `author`
 - Video: Specify versions -> Block

    **Generation**
 - ImageSet: Specify image aspect ratio (width, height) to prevent page jumps
 - Consistency: Check output folder for unused files
 - Empty properties: Show warnings for empty link previews, etc.

    **Fixes**
 - Files: Id change: Check all page contents for links to the renamed file and replace occurences
 - Database: Show errors during loading
 - Mock content: Clean and improve
 */

@main
struct MainView: App {

    private let sidebarWidth: CGFloat = 250

    private let detailWidth: CGFloat = 300

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

    @State
    private var language: ContentLanguage = .english

    @State
    private var selectedTab: MainViewTab = .posts

    @State
    private var selectedPost: Post?

    @State
    private var selectedPage: Page?

    @State
    private var selectedTag: Tag?

    @State
    private var selectedFile: FileResource?

    @State
    private var selectedSection: SettingsSection = .folders

    @State
    private var showAddSheet = false

    @State
    private var showInitialSetupSheet = false

    @ViewBuilder
    var sidebar: some View {
        switch selectedTab {
        case .posts:
            PostListView(selectedPost: $selectedPost)
        case .pages:
            PageListView(selectedPage: $selectedPage)
        case .tags:
            TagListView(selectedTag: $selectedTag)
        case .files:
            FileListView(selectedFile: $selectedFile)
        case .generation:
            SettingsListView(selectedSection: $selectedSection)
        }
    }

    @ViewBuilder
    var viewContent: some View {
        switch selectedTab {
        case .posts:
            SelectedContentView<PostContentView>(selected: $selectedPost)
        case .pages:
            SelectedContentView<PageContentView>(selected: $selectedPage)
        case .tags:
            SelectedContentView<TagContentView>(selected: $selectedTag)
        case .files:
            SelectedContentView<FileContentView>(selected: $selectedFile)
        case .generation:
            GenerationContentView(selected: $selectedSection)
        }
    }

    @ViewBuilder
    var detail: some View {
        switch selectedTab {
        case .posts:
            SelectedDetailView<PostDetailView>(selected: $selectedPost)
        case .pages:
            SelectedDetailView<PageDetailView>(selected: $selectedPage)
        case .tags:
            SelectedDetailView<TagDetailView>(selected: $selectedTag)
        case .files:
            SelectedDetailView<FileDetailView>(selected: $selectedFile)
        case .generation:
            GenerationDetailView(section: selectedSection)
        }
    }

    @ViewBuilder
    var addItemSheet: some View {
        switch selectedTab {
        case .posts:
            AddPostView(selected: $selectedPost)
        case .pages:
            AddPageView(selected: $selectedPage)
        case .tags:
            AddTagView(selected: $selectedTag)
        case .files:
            AddFileView(selectedFile: $selectedFile)
        case .generation:
            Text("Not implemented")
        }
    }

    var body: some Scene {
        WindowGroup {
            NavigationSplitView {
                sidebar
                    .toolbar {
                        ToolbarItem(placement: .navigation) {
                            Picker("", selection: $selectedTab) {
                                Text("Posts").tag(MainViewTab.posts)
                                Text("Pages").tag(MainViewTab.pages)
                                Text("Tags").tag(MainViewTab.tags)
                                Text("Files").tag(MainViewTab.files)
                                Text("Generation").tag(MainViewTab.generation)
                            }.pickerStyle(.segmented)
                        }
                    }
                    .navigationSplitViewColumnWidth(min: sidebarWidth, ideal: sidebarWidth, max: sidebarWidth)
                    .toolbar {
                        ToolbarItem(placement: .primaryAction) {
                            Button(action: { showAddSheet = true }) {
                                Label("Add", systemSymbol: .plus)
                            }
                            .disabled(!selectedTab.canAddItems)
                        }
                    }
            } content: {
                viewContent
            } detail: {
                detail
                    .navigationSplitViewColumnWidth(min: detailWidth, ideal: detailWidth, max: detailWidth)
            }
            .toolbar {
                ToolbarItem(placement: .primaryAction) {
                    Picker("", selection: $language) {
                        Text("English")
                            .tag(ContentLanguage.english)
                        Text("German")
                            .tag(ContentLanguage.german)
                    }.pickerStyle(.segmented)
                }
                ToolbarItem(placement: .primaryAction) {
                    if content.storage.contentScope != nil {
                        Button(action: save) {
                            Text("Save")
                        }
                    } else {
                        Button(action: showInitialSheet) {
                            Text("Setup")
                        }
                        .background(RoundedRectangle(cornerRadius: 8).fill(Color.red))
                    }
                }
            }
            .navigationTitle("")
            .environment(\.language, language)
            .environmentObject(content)
            .onAppear(perform: loadContent)
            .onReceive(Timer.publish(every: 60.0, on: .main, in: .common).autoconnect()) { _ in
                save()
            }
            .sheet(isPresented: $showAddSheet) {
                addItemSheet
                    .environment(\.language, language)
                    .environmentObject(content)
            }
            .sheet(isPresented: $showInitialSetupSheet) {
                InitialSetupView()
                    .environment(\.language, language)
                    .environmentObject(content)
            }
        }
    }

    private func save() {
        do {
            try content.saveToDisk()
        } catch {
            print("Failed to save content: \(error.localizedDescription)")
        }
    }

    private func loadContent() {
        guard content.storage.contentScope != nil else {
            showInitialSheet()
            return
        }
        do {
            try content.loadFromDisk()
        } catch {
            print("Failed to load content: \(error.localizedDescription)")
        }
    }

    private func showInitialSheet() {
        DispatchQueue.main.async {
            selectedSection = .folders
            selectedTab = .generation
            showInitialSetupSheet = true
        }
    }
}

