// Copyright (C) 2024 Apple Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.

import CoreTransferable
import Foundation
import os
import Observation
import UniformTypeIdentifiers
@_spi(Private) import WebKit

struct PDF {
    let data: Data
    let title: String?
}

extension PDF: Transferable {
    static var transferRepresentation: some TransferRepresentation {
        DataRepresentation(exportedContentType: .pdf, exporting: \.data)
    }
}

struct OpenRequest: Equatable {
    let request: URLRequest
}

@Observable
@MainActor
final class BrowserViewModel {
    private static let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: String(describing: BrowserViewModel.self))

    private static func decideSensorAuthorization(permission: WebPage.DeviceSensorAuthorization.Permission, frame: WebPage.FrameInfo, origin: WKSecurityOrigin) async -> WKPermissionDecision {
        let mediaCaptureAuthorization = WKPermissionDecision(rawValue: UserDefaults.standard.integer(forKey: AppStorageKeys.mediaCaptureAuthorization))!
        let orientationAndMotionAuthorization = WKPermissionDecision(rawValue: UserDefaults.standard.integer(forKey: AppStorageKeys.orientationAndMotionAuthorization))!

        return switch permission {
        case .deviceOrientationAndMotion: orientationAndMotionAuthorization
        case .mediaCapture: mediaCaptureAuthorization
        @unknown default:
            fatalError()
        }
    }

    init() {
        var configuration = WebPage.Configuration()
        configuration.deviceSensorAuthorization = WebPage.DeviceSensorAuthorization(decisionHandler: Self.decideSensorAuthorization(permission:frame:origin:))

        self.page = WebPage(configuration: configuration, navigationDecider: self.navigationDecider, dialogPresenter: self.dialogPresenter)

        self.navigationDecider.owner = self
        self.dialogPresenter.owner = self
    }

    let page: WebPage

    private let dialogPresenter = DialogPresenter()
    private let navigationDecider = NavigationDecider()

    var displayedURL: String = ""

    var currentOpenRequest: OpenRequest? = nil

    // MARK: PDF properties

    var pdfExporterIsPresented = false {
        didSet {
            if !pdfExporterIsPresented {
                exportedPDF = nil
            }
        }
    }

    private(set) var exportedPDF: PDF? = nil {
        didSet {
            if exportedPDF != nil {
                pdfExporterIsPresented = true
            }
        }
    }

    // MARK: Dialog properties

    var isPresentingDialog = false {
        didSet {
            if !isPresentingDialog {
                currentDialog = nil
            }
        }
    }

    var currentDialog: DialogPresenter.Dialog? = nil {
        didSet {
            if currentDialog != nil {
                isPresentingDialog = true
            }
        }
    }

    var isPresentingFilePicker = false

    var currentFilePicker: DialogPresenter.FilePicker? = nil {
        didSet {
            if currentFilePicker != nil {
                isPresentingFilePicker = true
            }
        }
    }

    // MARK: View model functions

    func openURL(_ url: URL) {
        assert(url.isFileURL)

        let data = try! Data(contentsOf: url)
        page.load(data, mimeType: "text/html", characterEncoding: .utf8, baseURL: URL(string: "about:blank")!)
    }

    func didReceiveNavigationEvent(_ event: WebPage.NavigationEvent) {
        Self.logger.info("Did receive navigation event \(String(describing: event))")

        if event == .committed {
            displayedURL = page.url?.absoluteString ?? ""
        }
    }

    func navigateToSubmittedURL() {
        guard let url = URL(string: displayedURL) else {
            return
        }

        let request = URLRequest(url: url)
        page.load(request)
    }

    func exportAsPDF() {
        Task {
            let data = try await page.exported(as: .pdf)
            exportedPDF = PDF(data: data, title: !page.title.isEmpty ? page.title : nil)
        }
    }

    func didExportPDF(result: Result<URL, any Error>) {
        switch result {
        case let .success(url):
            Self.logger.info("Exported PDF to \(url)")

        case let .failure(error):
            Self.logger.error("Failed to export PDF: \(error)")
        }
    }

    func didImportFiles(result: Result<[URL], any Error>) {
        precondition(currentFilePicker != nil)

        switch result {
        case let .success(urls):
            currentFilePicker!.completion(.selected(urls))

        case .failure:
            currentFilePicker!.completion(.cancel)
        }

        currentFilePicker = nil
    }

    func setCameraCaptureState(_ state: WKMediaCaptureState) {
        Task { @MainActor in
            await page.setCameraCaptureState(state)
        }
    }

    func setMicrophoneCaptureState(_ state: WKMediaCaptureState) {
        Task { @MainActor in
            await page.setMicrophoneCaptureState(state)
        }
    }
}
