//
//  ShareViewController.swift
//  Haystack
//
//  Created by Rio Keefe on 03/05/2025.
//

import UIKit
import Social
import MobileCoreServices

class ShareViewController: SLComposeServiceViewController {

    let appGroupName = "group.com.haystack.app" // Replace with your actual App Group identifier
    let tokenKey = "sharedAuthToken"
    let uploadURL = URL(string: "https://haystack.johncosta.tech/image/")!

    var bearerToken: String?
    // Store the item provider to access it later in didSelectPost
    private var imageItemProvider: NSItemProvider?
    private var extractedImageName: String = "image" // Default name

    override func viewDidLoad() {
        super.viewDidLoad()

        // Load the bearer token from the App Group in viewDidLoad
        // This is okay as reading from UserDefaults is fast
        if let sharedDefaults = UserDefaults(suiteName: appGroupName) {
            bearerToken = sharedDefaults.string(forKey: tokenKey)
            print("Retrieved bearer token: \(bearerToken ?? "nil")")
        } else {
            print("Error accessing App Group UserDefaults.")
            // Optionally inform the user or disable posting if token is crucial
            // self.isContentValid() could check if bearerToken is nil
        }

        // Store the item provider, but don't load the data synchronously yet
        if let item = extensionContext?.inputItems.first as? NSExtensionItem,
           let provider = item.attachments?.first as? NSItemProvider {
            if provider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {
                self.imageItemProvider = provider
                // Attempt to get a suggested name early if available
                 extractedImageName = provider.suggestedName ?? "image"
                 if let dotRange = extractedImageName.range(of: ".", options: .backwards) {
                     extractedImageName = String(extractedImageName[..<dotRange.lowerBound])
                 }

            } else {
                print("No image found.")
                // If no image is found, the content is not valid for this extension
                // You might want to adjust isContentValid() based on this
            }
        }
    }

    override func isContentValid() -> Bool {
        // Content is valid only if we have an item provider for an image AND a bearer token
        return imageItemProvider != nil && bearerToken != nil
    }

    override func didSelectPost() {
        // This method is called when the user taps the "Post" button.
        // Start the asynchronous operation here.

        guard let provider = imageItemProvider else {
            print("Error: No image item provider found when posting.")
            // Inform the user or log an error
            extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
            return
        }

        guard let token = bearerToken else {
             print("Error: Bearer token is missing when posting.")
             // Inform the user or log an error
             extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
             return
        }

        // Load the image data asynchronously
        provider.loadItem(forTypeIdentifier: kUTTypeImage as String, options: nil) { [weak self] (item, error) in
            guard let self = self else { return }

            if let error = error {
                print("Error loading image data for upload: \(error.localizedDescription)")
                // Inform the user about the failure
                self.extensionContext!.cancelRequest(withError: error)
                return
            }

            var rawImageData: Data?
            var finalImageName = self.extractedImageName // Use the name extracted earlier

            if let url = item as? URL, let data = try? Data(contentsOf: url) {
                 rawImageData = data
                 // Refine the name extraction here if necessary, though doing it in viewDidLoad is also an option
                 finalImageName = url.lastPathComponent
                 if let dotRange = finalImageName.range(of: ".", options: .backwards) {
                      finalImageName = String(finalImageName[..<dotRange.lowerBound])
                 }

            } else if let data = item as? Data {
                 rawImageData = data
                 // Use the suggested name if available, fallback to default
                 finalImageName = provider.suggestedName ?? "image"
            } else {
                print("Error: Could not get image data in a usable format.")
                 // Inform the user about the failure
                 self.extensionContext!.cancelRequest(withError: NSError(domain: "ShareExtension", code: -4, userInfo: [NSLocalizedDescriptionKey: "Could not process image data."]))
                 return
            }


            guard let dataToUpload = rawImageData else {
                 print("Error: No image data to upload.")
                 // Inform the user about the failure
                 self.extensionContext!.cancelRequest(withError: NSError(domain: "ShareExtension", code: -5, userInfo: [NSLocalizedDescriptionKey: "Image data is missing."]))
                 return
            }

            // Now perform the upload asynchronously
            self.uploadRawData(dataToUpload, imageName: finalImageName, bearerToken: token)
        }

        // Do not complete the request here.
        // The request will be completed in the uploadRawData completion handler.
    }

    func uploadRawData(_ rawData: Data, imageName: String, bearerToken: String) {
        // bearerToken is guaranteed to be non-nil here due to the guard in didSelectPost

        let uploadURLwithName = uploadURL.appendingPathComponent(imageName)

        var request = URLRequest(url: uploadURLwithName)
        request.httpMethod = "POST"
        request.httpBody = rawData
        request.setValue("application/oclet-stream", forHTTPHeaderField: "Content-Type")
        request.setValue("Bearer \(bearerToken)", forHTTPHeaderField: "Authorization")

        let task = URLSession.shared.dataTask(with: request) { [weak self] (data, response, error) in
            // **IMPORTANT:** Complete the extension request on the main thread
            DispatchQueue.main.async {
                print("Upload finished. Error: \(error?.localizedDescription ?? "None"), Response: \(response?.description ?? "None")")

                if let error = error {
                    // Handle upload error (e.g., show an alert to the user)
                    print("Upload failed: \(error.localizedDescription)")
                     self?.extensionContext!.cancelRequest(withError: error)
                } else if let httpResponse = response as? HTTPURLResponse, !(200...299).contains(httpResponse.statusCode) {
                    // Handle non-success HTTP status codes
                    let errorDescription = "Server returned status code \(httpResponse.statusCode)"
                    print(errorDescription)
                     self?.extensionContext!.cancelRequest(withError: NSError(domain: "ShareExtension", code: httpResponse.statusCode, userInfo: [NSLocalizedDescriptionKey: errorDescription]))
                }
                else {
                    // Upload was successful
                    print("Upload successful")
                    // Complete the request when the upload is done
                    self?.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
                }
            }
        }
        task.resume()
    }

    override func configurationItems() -> [Any]! {
        // You can add items here if you want to allow the user to enter additional info
        // e.g., a text field for a caption.
        // This example only handles image upload, so no config items are needed.
        return []
    }
}
