import SwiftUI

struct WidgetsRootView: View {
    @ObservedObject private var desktopWidgetManager = DesktopWidgetWindowManager.shared
    @Environment(\.colorScheme) private var colorScheme
    @State private var toastMessage: String?
    @State private var toastTask: Task<Void, Never>?
    let canAddWidgets: Bool
    let onAddBlocked: (() -> Void)?

    private let variants = WidgetTemplates.meetVariants

    init(canAddWidgets: Bool = true, onAddBlocked: (() -> Void)? = nil) {
        self.canAddWidgets = canAddWidgets
        self.onAddBlocked = onAddBlocked
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            HStack {
                VStack(alignment: .leading, spacing: 3) {
                    Text("Add Widget to Desktop")
                        .font(.system(size: 20, weight: .bold))
                    Text("Choose a size and add your Google Meet widget.")
                        .font(.system(size: 13, weight: .medium))
                        .foregroundStyle(secondaryTextColor)
                }
                Spacer()
            }

            GeometryReader { geo in
                let spacing: CGFloat = 18
                let rowWidth = variants.reduce(CGFloat(0)) { $0 + $1.previewCardSize.width } + CGFloat(max(variants.count - 1, 0)) * spacing
                let scale = max(0.40, min(1, (geo.size.width - 28) / max(1, rowWidth)))
                HStack(alignment: .top, spacing: spacing) {
                    ForEach(variants) { variant in
                        WidgetPreviewAddCard(
                            variant: variant,
                            layoutScale: scale,
                            isAdded: desktopWidgetManager.hasInstance(variantID: variant.id),
                            onToggle: { toggleWidget(variant: variant) }
                        )
                    }
                    Spacer(minLength: 0)
                }
                .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
            }
            .frame(height: variants.map(\.previewCardSize.height).max() ?? 320)

            Text("Tip: Right-click a desktop widget to remove it.")
                .font(.system(size: 12, weight: .medium))
                .foregroundStyle(secondaryTextColor)
        }
        .padding(18)
        .background(
            RoundedRectangle(cornerRadius: 18, style: .continuous)
                .fill(colorScheme == .dark ? Color.white.opacity(0.05) : Color.white.opacity(0.93))
        )
        .overlay(
            RoundedRectangle(cornerRadius: 18, style: .continuous)
                .stroke(colorScheme == .dark ? Color.white.opacity(0.09) : Color.black.opacity(0.08), lineWidth: 1)
        )
        .overlay(alignment: .top) {
            if let toastMessage {
                Text(toastMessage)
                    .font(.system(size: 13, weight: .semibold))
                    .foregroundStyle(colorScheme == .dark ? .white.opacity(0.95) : .primary.opacity(0.95))
                    .padding(.horizontal, 14)
                    .padding(.vertical, 9)
                    .background(
                        RoundedRectangle(cornerRadius: 12, style: .continuous)
                            .fill(colorScheme == .dark ? Color.black.opacity(0.82) : Color.white.opacity(0.95))
                    )
                    .overlay(
                        RoundedRectangle(cornerRadius: 12, style: .continuous)
                            .stroke(colorScheme == .dark ? Color.white.opacity(0.08) : Color.black.opacity(0.08), lineWidth: 1)
                    )
                    .padding(.top, 8)
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
    }

    private var secondaryTextColor: Color {
        colorScheme == .dark ? .white.opacity(0.72) : .primary.opacity(0.65)
    }

    private func toggleWidget(variant: WidgetVariant) {
        if desktopWidgetManager.hasInstance(variantID: variant.id) {
            let removed = desktopWidgetManager.removeInstances(variantID: variant.id)
            guard removed > 0 else { return }
            showToast("Removed \(variant.size.title) widget from desktop.")
        } else {
            guard canAddWidgets else {
                showToast("Widgets are Premium only. Upgrade to add widgets.")
                onAddBlocked?()
                return
            }
            desktopWidgetManager.show(
                instance: WidgetInstance(variantID: variant.id, size: variant.size, origin: nil)
            )
            showToast("Added \(variant.size.title) widget to desktop.")
        }
    }

    private func showToast(_ message: String) {
        toastTask?.cancel()
        toastMessage = message
        toastTask = Task { @MainActor in
            try? await Task.sleep(nanoseconds: 1_800_000_000)
            guard !Task.isCancelled else { return }
            toastMessage = nil
        }
    }
}

private struct WidgetPreviewAddCard: View {
    let variant: WidgetVariant
    var layoutScale: CGFloat = 1
    let isAdded: Bool
    let onToggle: () -> Void
    @State private var hovering = false

    var body: some View {
        ZStack(alignment: .topTrailing) {
            Button(action: onToggle) {
                WidgetPreviewCard(variant: variant, layoutScale: layoutScale)
                    .contentShape(RoundedRectangle(cornerRadius: 18, style: .continuous))
            }
            .buttonStyle(.plain)

            Button(action: onToggle) {
                Image(systemName: isAdded ? "minus" : "plus")
                    .font(.system(size: 12, weight: .bold))
                    .foregroundStyle(.white.opacity(0.95))
                    .frame(width: 26, height: 26)
                    .background(Circle().fill(isAdded ? Color.red.opacity(0.92) : Color.green.opacity(0.95)))
                    .shadow(color: .black.opacity(0.28), radius: 10, x: 0, y: 6)
            }
            .buttonStyle(.plain)
            .offset(x: 10 * layoutScale, y: -10 * layoutScale)
            .opacity(isAdded ? 1 : (hovering ? 1 : 0))
            .animation(.easeOut(duration: 0.12), value: hovering)
        }
        .onHover { hovering = $0 }
    }
}
