import AppKit
import SwiftUI
import WebKit

/// Google Photos: medium embedded recent gallery with Albums / Updates / Search shortcuts.
struct PhotosDesktopWidgetView: View {
    let app: LauncherApp
    var isPreview: Bool = false

    private var baseURL: URL {
        app.webURL ?? URL(string: "https://photos.google.com/")!
    }

    /// Google Photos–style dark shell (deep blue-grey).
    private var shellGradient: LinearGradient {
        LinearGradient(
            colors: [
                Color(red: 0.07, green: 0.10, blue: 0.14),
                Color(red: 0.05, green: 0.07, blue: 0.11),
            ],
            startPoint: .topLeading,
            endPoint: .bottomTrailing
        )
    }

    var body: some View {
        Group {
            if isPreview {
                photosPreviewChrome
            } else {
                ZStack {
                    RoundedRectangle(cornerRadius: 22, style: .continuous)
                        .fill(shellGradient)

                    VStack(spacing: 0) {
                        galleryChromeHeader
                        headerDivider
                        GooglePhotosEmbeddedWebView(startURL: baseURL)
                            .frame(maxWidth: .infinity, maxHeight: .infinity)
                        bottomChromeBar
                    }
                }
            }
        }
        .clipShape(RoundedRectangle(cornerRadius: 22, style: .continuous))
        .overlay(
            RoundedRectangle(cornerRadius: 22, style: .continuous)
                .strokeBorder(Color.white.opacity(0.10), lineWidth: 1)
        )
    }

    private var headerDivider: some View {
        Rectangle()
            .fill(
                LinearGradient(
                    colors: [Color.white.opacity(0.14), Color.white.opacity(0.05)],
                    startPoint: .leading,
                    endPoint: .trailing
                )
            )
            .frame(height: 1)
    }

    private var galleryChromeHeader: some View {
        HStack(alignment: .center, spacing: 12) {
            ZStack {
                RoundedRectangle(cornerRadius: 10, style: .continuous)
                    .fill(
                        LinearGradient(
                            colors: [Color.white.opacity(0.14), Color.white.opacity(0.06)],
                            startPoint: .topLeading,
                            endPoint: .bottomTrailing
                        )
                    )
                    .frame(width: 40, height: 40)
                    .overlay(
                        RoundedRectangle(cornerRadius: 10, style: .continuous)
                            .stroke(Color.white.opacity(0.12), lineWidth: 1)
                    )
                AppIconView(app: app, size: 30, showAppBackground: false, iconPaddingFactor: 0.08)
            }

            VStack(alignment: .leading, spacing: 3) {
                Text(app.name)
                    .font(.system(size: 15, weight: .bold, design: .rounded))
                    .foregroundStyle(.white.opacity(0.96))
                HStack(spacing: 6) {
                    Text("Recent")
                        .font(.system(size: 11, weight: .semibold, design: .rounded))
                        .foregroundStyle(Color(red: 0.55, green: 0.82, blue: 0.95).opacity(0.95))
                    Text("·")
                        .foregroundStyle(.white.opacity(0.35))
                    Text("Library")
                        .font(.system(size: 11, weight: .medium, design: .rounded))
                        .foregroundStyle(.white.opacity(0.55))
                }
            }

            Spacer(minLength: 8)

            Button(action: openPhotosHome) {
                HStack(spacing: 5) {
                    Text("Open")
                        .font(.system(size: 12, weight: .bold, design: .rounded))
                    Image(systemName: "arrow.up.right.circle.fill")
                        .font(.system(size: 14, weight: .semibold))
                }
                .foregroundStyle(.white.opacity(0.95))
                .padding(.horizontal, 11)
                .padding(.vertical, 7)
                .background(
                    Capsule(style: .continuous)
                        .fill(
                            LinearGradient(
                                colors: [Color.white.opacity(0.22), Color.white.opacity(0.10)],
                                startPoint: .top,
                                endPoint: .bottom
                            )
                        )
                )
                .overlay(
                    Capsule(style: .continuous)
                        .stroke(Color.white.opacity(0.18), lineWidth: 1)
                )
            }
            .buttonStyle(.plain)
        }
        .padding(.horizontal, 14)
        .padding(.vertical, 12)
        .background(
            LinearGradient(
                colors: [Color.black.opacity(0.42), Color.black.opacity(0.22)],
                startPoint: .top,
                endPoint: .bottom
            )
        )
    }

    /// Subtle multi-hue strip echoing Google Photos branding.
    private var photosAccentStrip: some View {
        LinearGradient(
            colors: [
                Color(red: 0.26, green: 0.52, blue: 0.96),
                Color(red: 0.18, green: 0.72, blue: 0.45),
                Color(red: 0.98, green: 0.75, blue: 0.18),
                Color(red: 0.92, green: 0.35, blue: 0.25),
            ],
            startPoint: .leading,
            endPoint: .trailing
        )
        .frame(height: 2)
        .opacity(0.85)
    }

    private var bottomChromeBar: some View {
        VStack(spacing: 0) {
            photosAccentStrip
            HStack(spacing: 10) {
                PhotosShortcutChip(title: "Albums", systemImage: "rectangle.stack.fill") {
                    openPhotosPath("/albums")
                }
                PhotosShortcutChip(title: "Updates", systemImage: "bell.fill") {
                    openPhotosPath("/updates")
                }
                PhotosShortcutChip(title: "Search", systemImage: "magnifyingglass") {
                    openPhotosPath("/search")
                }
            }
            .padding(.horizontal, 12)
            .padding(.vertical, 12)
            .background(
                LinearGradient(
                    colors: [Color.black.opacity(0.55), Color.black.opacity(0.38)],
                    startPoint: .top,
                    endPoint: .bottom
                )
            )
        }
    }

    private struct PhotosShortcutChip: View {
        let title: String
        let systemImage: String
        let action: () -> Void

        var body: some View {
            Button(action: action) {
                VStack(spacing: 6) {
                    Image(systemName: systemImage)
                        .font(.system(size: 15, weight: .semibold))
                        .foregroundStyle(
                            LinearGradient(
                                colors: [
                                    Color.white.opacity(0.95),
                                    Color.white.opacity(0.72),
                                ],
                                startPoint: .top,
                                endPoint: .bottom
                            )
                        )
                    Text(title)
                        .font(.system(size: 10, weight: .bold, design: .rounded))
                        .foregroundStyle(.white.opacity(0.88))
                        .lineLimit(1)
                        .minimumScaleFactor(0.85)
                }
                .frame(maxWidth: .infinity)
                .padding(.vertical, 11)
                .padding(.horizontal, 6)
                .background(
                    RoundedRectangle(cornerRadius: 14, style: .continuous)
                        .fill(
                            LinearGradient(
                                colors: [Color.white.opacity(0.14), Color.white.opacity(0.05)],
                                startPoint: .top,
                                endPoint: .bottom
                            )
                        )
                )
                .overlay(
                    RoundedRectangle(cornerRadius: 14, style: .continuous)
                        .stroke(Color.white.opacity(0.14), lineWidth: 1)
                )
            }
            .buttonStyle(.plain)
        }
    }

    private var photosPreviewChrome: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 22, style: .continuous)
                .fill(
                    LinearGradient(
                        colors: [
                            Color(red: 0.10, green: 0.14, blue: 0.20),
                            Color(red: 0.04, green: 0.06, blue: 0.10),
                        ],
                        startPoint: .topLeading,
                        endPoint: .bottomTrailing
                    )
                )
            VStack(spacing: 14) {
                ZStack {
                    Circle()
                        .fill(
                            LinearGradient(
                                colors: [Color.white.opacity(0.12), Color.white.opacity(0.04)],
                                startPoint: .topLeading,
                                endPoint: .bottomTrailing
                            )
                        )
                        .frame(width: 72, height: 72)
                        .overlay(Circle().stroke(Color.white.opacity(0.14), lineWidth: 1))
                    AppIconView(app: app, size: 44, showAppBackground: false, iconPaddingFactor: 0.08)
                }
                Text("Recent gallery")
                    .font(.system(size: 16, weight: .bold, design: .rounded))
                    .foregroundStyle(.white.opacity(0.94))
                Text("Your library appears here after you sign in to Google Photos in the panel.")
                    .font(.system(size: 11, weight: .medium, design: .rounded))
                    .foregroundStyle(.white.opacity(0.62))
                    .multilineTextAlignment(.center)
                    .lineSpacing(2)
                    .padding(.horizontal, 18)
            }
            .padding(20)
        }
        .overlay(
            RoundedRectangle(cornerRadius: 22, style: .continuous)
                .strokeBorder(Color.white.opacity(0.10), lineWidth: 1)
        )
    }

    private func openPhotosHome() {
        NSApp.activate(ignoringOtherApps: true)
        InAppBrowserWindowManager.shared.open(url: baseURL, title: app.name)
    }

    private func openPhotosPath(_ path: String) {
        let url = WidgetDeepLinkURL.resolved(base: baseURL, actionPath: path, accountSlot: 0)
        NSApp.activate(ignoringOtherApps: true)
        InAppBrowserWindowManager.shared.open(url: url, title: app.name)
    }
}

// MARK: - WKWebView

private final class PhotosWebViewClippingContainer: NSView {
    override var isFlipped: Bool { true }
}

private struct GooglePhotosEmbeddedWebView: NSViewRepresentable {
    let startURL: URL

    func makeCoordinator() -> Coordinator {
        Coordinator()
    }

    func makeNSView(context: Context) -> NSView {
        let container = PhotosWebViewClippingContainer()
        container.wantsLayer = true
        container.layer?.masksToBounds = true

        let config = WKWebViewConfiguration()
        config.defaultWebpagePreferences.allowsContentJavaScript = true
        let embedded = WKWebView(frame: .zero, configuration: config)
        embedded.translatesAutoresizingMaskIntoConstraints = false
        embedded.focusRingType = .none
        embedded.navigationDelegate = context.coordinator
        context.coordinator.embeddedWebView = embedded
        context.coordinator.pageURL = startURL
        context.coordinator.reload()

        container.addSubview(embedded)
        NSLayoutConstraint.activate([
            embedded.leadingAnchor.constraint(equalTo: container.leadingAnchor),
            embedded.trailingAnchor.constraint(equalTo: container.trailingAnchor),
            embedded.topAnchor.constraint(equalTo: container.topAnchor),
            embedded.bottomAnchor.constraint(equalTo: container.bottomAnchor),
        ])

        DispatchQueue.main.async {
            Self.stripWebKitOuterChrome(embedded)
        }
        return container
    }

    func updateNSView(_ container: NSView, context: Context) {
        guard context.coordinator.pageURL != startURL else { return }
        context.coordinator.pageURL = startURL
        context.coordinator.reload()
    }

    private static func stripWebKitOuterChrome(_ root: WKWebView) {
        func walk(_ view: NSView) {
            view.focusRingType = .none
            view.layer?.borderWidth = 0
            view.layer?.borderColor = NSColor.clear.cgColor
            if let scroll = view as? NSScrollView {
                scroll.borderType = .noBorder
                scroll.drawsBackground = false
                scroll.scrollerStyle = .overlay
            }
            if let clip = view as? NSClipView {
                clip.drawsBackground = false
            }
            for sub in view.subviews {
                walk(sub)
            }
        }
        walk(root)
    }

    final class Coordinator: NSObject, WKNavigationDelegate {
        weak var embeddedWebView: WKWebView?
        var pageURL = URL(string: "https://photos.google.com/")!

        func reload() {
            guard let embeddedWebView else { return }
            embeddedWebView.load(URLRequest(url: pageURL))
        }

        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            DispatchQueue.main.async {
                GooglePhotosEmbeddedWebView.stripWebKitOuterChrome(webView)
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                    GooglePhotosEmbeddedWebView.stripWebKitOuterChrome(webView)
                }
            }
        }
    }
}
