import CodexBarCore
import SwiftUI

@MainActor
struct MenuBarPane: View {
    private static let maxOverviewProviders = SettingsStore.mergedOverviewProviderLimit

    @State private var isOverviewProviderPopoverPresented = false
    @Bindable var settings: SettingsStore
    @Bindable var store: UsageStore

    static func overviewProviderLimitText(limit: Int = Self.maxOverviewProviders) -> String {
        L("overview_choose_providers", String(limit))
    }

    static func inactiveDisplayContrastAvailable(for style: MenuBarIconStyle) -> Bool {
        style == .iconAndPercent
    }

    var body: some View {
        Form {
            Section {
                SettingsMenuPicker(
                    selection: self.$settings.menuBarIconStyle,
                    options: MenuBarSettingsMenuOptions.iconStyles,
                    label: {
                        SettingsRowLabel(
                            L("menu_bar_style_title"),
                            subtitle: L("menu_bar_style_subtitle"))
                    },
                    optionLabel: { style in
                        Text(style.label)
                    })

                Toggle(isOn: self.$settings.menuBarHighContrastOnInactiveDisplays) {
                    SettingsRowLabel(
                        L("menu_bar_inactive_display_contrast_title"),
                        subtitle: "\(MenuBarIconStyle.iconAndPercent.label): "
                            + L("menu_bar_inactive_display_contrast_subtitle"))
                }
                .disabled(!Self.inactiveDisplayContrastAvailable(for: self.settings.menuBarIconStyle))
            } header: {
                Text(L("section_icon"))
            }

            Section {
                MenuBarLayoutEditor(settings: self.settings, store: self.store)
                    .disabled(self.settings.menuBarIconStyle != .iconAndPercent)
            } header: {
                Text(L("menu_bar_layout_title"))
            } footer: {
                SettingsSectionFooter(L("menu_bar_layout_footer"))
            }

            Section {
                Toggle(isOn: self.$settings.mergeIcons) {
                    SettingsRowLabel(L("merge_icons_title"), subtitle: L("merge_icons_subtitle"))
                }

                SettingsMenuPicker(
                    selection: self.$settings.switcherRowsOption,
                    options: MenuBarSettingsMenuOptions.switcherRows,
                    label: { Text(L("switcher_rows_title")) },
                    optionLabel: { option in
                        Text(option.label)
                    })
                    .disabled(!self.settings.mergeIcons)

                Toggle(isOn: self.$settings.menuBarShowsHighestUsage) {
                    SettingsRowLabel(
                        L("show_most_used_provider_title"),
                        subtitle: L("show_most_used_provider_subtitle"))
                }
                .disabled(!self.settings.mergeIcons)

                self.overviewProviderRow
                    .disabled(!self.settings.mergeIcons)
            } header: {
                Text(L("section_combined_icon"))
            }

            Section {
                Toggle(isOn: self.$settings.randomBlinkEnabled) {
                    SettingsRowLabel(L("surprise_me_title"), subtitle: L("surprise_me_subtitle"))
                }
            } header: {
                Text(L("section_animation"))
            }
        }
        .formStyle(.grouped)
        .toggleStyle(.switch)
        .scrollContentBackground(.hidden)
        .onAppear {
            self.reconcileOverviewSelection()
        }
        .onChange(of: self.settings.mergeIcons) { _, isEnabled in
            guard isEnabled else {
                self.isOverviewProviderPopoverPresented = false
                return
            }
            self.reconcileOverviewSelection()
        }
        .onChange(of: self.activeProvidersInOrder) { _, _ in
            if self.activeProvidersInOrder.isEmpty {
                self.isOverviewProviderPopoverPresented = false
            }
            self.reconcileOverviewSelection()
        }
    }

    private var overviewProviderRow: some View {
        LabeledContent {
            if self.showsOverviewConfigureButton {
                Button(L("configure")) {
                    self.isOverviewProviderPopoverPresented = true
                }
                .popover(isPresented: self.$isOverviewProviderPopoverPresented, arrowEdge: .bottom) {
                    self.overviewProviderPopover
                }
            }
        } label: {
            SettingsRowLabel(L("overview_tab_providers_title"), subtitle: self.overviewProviderSubtitle)
        }
    }

    private var overviewProviderSubtitle: String {
        if !self.settings.mergeIcons {
            L("overview_enable_merge_icons_hint")
        } else if self.activeProvidersInOrder.isEmpty {
            L("overview_no_providers_hint")
        } else {
            self.overviewProviderSelectionSummary
        }
    }

    private var overviewProviderPopover: some View {
        VStack(alignment: .leading, spacing: 10) {
            Text(Self.overviewProviderLimitText())
                .font(.headline)
            Text(L("overview_rows_follow_order"))
                .font(.footnote)
                .foregroundStyle(.tertiary)

            ScrollView(.vertical, showsIndicators: true) {
                VStack(alignment: .leading, spacing: 6) {
                    ForEach(self.activeProvidersInOrder, id: \.self) { provider in
                        Toggle(
                            isOn: Binding(
                                get: { self.overviewSelectedProviders.contains(provider) },
                                set: { shouldSelect in
                                    self.setOverviewProviderSelection(provider: provider, isSelected: shouldSelect)
                                })) {
                            Text(self.providerDisplayName(provider))
                                .font(.body)
                        }
                        .toggleStyle(.checkbox)
                        .disabled(
                            !self.overviewSelectedProviders.contains(provider) &&
                                self.overviewSelectedProviders.count >= Self.maxOverviewProviders)
                    }
                }
            }
            .frame(maxHeight: 220)
        }
        .padding(12)
        .frame(width: 280)
    }

    private var activeProvidersInOrder: [UsageProvider] {
        self.store.enabledFirstPartyProviders()
    }

    private var overviewSelectedProviders: [UsageProvider] {
        self.settings.resolvedMergedOverviewProviders(
            activeProviders: self.activeProvidersInOrder,
            maxVisibleProviders: Self.maxOverviewProviders)
    }

    private var showsOverviewConfigureButton: Bool {
        self.settings.mergeIcons && !self.activeProvidersInOrder.isEmpty
    }

    private var overviewProviderSelectionSummary: String {
        let selectedNames = self.overviewSelectedProviders.map(self.providerDisplayName)
        guard !selectedNames.isEmpty else { return L("overview_no_providers_selected") }
        return selectedNames.joined(separator: ", ")
    }

    private func providerDisplayName(_ provider: UsageProvider) -> String {
        ProviderDescriptorRegistry.descriptor(for: provider).metadata.displayName
    }

    private func setOverviewProviderSelection(provider: UsageProvider, isSelected: Bool) {
        _ = self.settings.setMergedOverviewProviderSelection(
            provider: provider,
            isSelected: isSelected,
            activeProviders: self.activeProvidersInOrder,
            maxVisibleProviders: Self.maxOverviewProviders)
    }

    private func reconcileOverviewSelection() {
        _ = self.settings.reconcileMergedOverviewSelectedProviders(
            activeProviders: self.activeProvidersInOrder,
            maxVisibleProviders: Self.maxOverviewProviders)
    }
}
