//
//  ShareViewController.swift
//  GIFCollectorShare
//

import MobileCoreServices
import Social
import UIKit
import UniformTypeIdentifiers

class ShareViewController: SLComposeServiceViewController {

  private var receivedURL: URL?
  private var gifData: Data?
  private var isProcessing = false
  private var originalURL: String = ""
  private var debugMessages: [String] = []

  // Use the same constants as in the main app
  private let appGroupID = "group."+Bundle.main.bundleIdentifier.unsafelyUnwrapped.replacing(".Share", with:"")
  private let pendingGIFsKey = "pendingGIFs"

  override func viewDidLoad() {
    super.viewDidLoad()
    title = "Save to GIF Collector"
    placeholder = "Add a note (optional)"

    // Add debug button in development
    #if DEBUG
      let debugButton = UIBarButtonItem(
        title: "Debug", style: .plain, target: self, action: #selector(showDebugInfo))
      navigationItem.leftBarButtonItem = debugButton
    #endif

    // Start processing the shared item
    processSharedItem()

    addDebugMessage("ShareViewController loaded")
  }

  override func isContentValid() -> Bool {
    // No validation needed for the text field, we just want the GIF
    return true
  }

  override func didSelectPost() {
    // Show loading
    isProcessing = true
    navigationController?.navigationBar.isUserInteractionEnabled = false

    // If we have a URL but no data, we need to download it
    if let receivedURL = receivedURL, gifData == nil {
      downloadGIF(from: receivedURL) { [weak self] data, error in
        guard let self = self else { return }

        if let data = data {
          self.gifData = data
          self.saveGIF()
        } else {
          self.showError(
            message: "Could not download GIF: \(error?.localizedDescription ?? "Unknown error")")
        }
      }
    } else if let gifData = gifData {
      // We already have the data, save it directly
      saveGIF()
    } else {
      // No valid GIF was found
      showError(message: "No valid GIF found in the shared content")
    }
  }

  override func didSelectCancel() {
    // User canceled, close the extension
    completeRequest()
  }

  // MARK: - Private Methods

  private func processSharedItem() {
    addDebugMessage("Starting to process shared item")

    // Log extension context info
    if let context = extensionContext {
      addDebugMessage("Extension context exists")
      addDebugMessage("Input items count: \(context.inputItems.count)")
    } else {
      addDebugMessage("Extension context is nil")
    }

    guard let extensionItem = extensionContext?.inputItems.first as? NSExtensionItem else {
      addDebugMessage("No extension item found")
      showError(message: "No shared content found")
      return
    }

    guard let attachments = extensionItem.attachments else {
      addDebugMessage("No attachments found")
      showError(message: "No attachments found")
      return
    }

    addDebugMessage("Found \(attachments.count) attachments")

    // Process each attachment
    for attachment in attachments {
      // Log attachment types
      let typeIdentifiers = attachment.registeredTypeIdentifiers
      addDebugMessage("Attachment types: \(typeIdentifiers.joined(separator: ", "))")

      // Check for URLs first (for web links to GIFs)
      if attachment.hasItemConformingToTypeIdentifier(UTType.url.identifier) {
        addDebugMessage("Processing URL type attachment")
        attachment.loadItem(forTypeIdentifier: UTType.url.identifier, options: nil) {
          [weak self] item, error in
          guard let self = self else { return }

          if let url = item as? URL, url.absoluteString.lowercased().hasSuffix(".gif") {
            DispatchQueue.main.async {
              self.receivedURL = url
              self.originalURL = url.absoluteString
              self.updateUI()
            }
          } else if let url = item as? URL {
            // It's a URL but not directly to a GIF, might be a webpage containing a GIF
            DispatchQueue.main.async {
              self.originalURL = url.absoluteString
              self.receivedURL = url
              self.updateUI()
              self.addDebugMessage("URL processed: \(url.absoluteString)")
            }
          }
        }
        continue
      }

      // Check for GIF files
      if attachment.hasItemConformingToTypeIdentifier("com.compuserve.gif")
        || attachment.hasItemConformingToTypeIdentifier("public.gif")
      {
        addDebugMessage("Processing GIF type attachment")
        attachment.loadItem(forTypeIdentifier: "com.compuserve.gif", options: nil) {
          [weak self] item, error in
          guard let self = self else { return }

          if let url = item as? URL {
            DispatchQueue.main.async {
              self.receivedURL = url
              self.originalURL = url.absoluteString
              self.loadGIFData(from: url)
              self.updateUI()
            }
          } else if let data = item as? Data {
            DispatchQueue.main.async {
              self.gifData = data
              self.updateUI()
            }
          }
        }
        continue
      }

      // Check for images that might be GIFs
      if attachment.hasItemConformingToTypeIdentifier(UTType.image.identifier) {
        attachment.loadItem(forTypeIdentifier: UTType.image.identifier, options: nil) {
          [weak self] item, error in
          guard let self = self else { return }

          if let url = item as? URL, url.pathExtension.lowercased() == "gif" {
            DispatchQueue.main.async {
              self.receivedURL = url
              self.originalURL = url.absoluteString
              self.loadGIFData(from: url)
              self.updateUI()
            }
          } else if let data = item as? Data, self.isGIFData(data) {
            DispatchQueue.main.async {
              self.gifData = data
              self.updateUI()
            }
          }
        }
      }
    }
  }

  private func updateUI() {
    // Enable the Post button if we have a URL or data
    navigationItem.rightBarButtonItem?.isEnabled = (receivedURL != nil || gifData != nil)

    // Update content area
    if let url = receivedURL {
      let displayText = "GIF from: \(url.host ?? "URL")"
      if contentText.isEmpty {

      }
    }
  }

  private func loadGIFData(from url: URL) {
    do {
      let data = try Data(contentsOf: url)
      if isGIFData(data) {
        gifData = data
      }
    } catch {
      print("Error loading GIF data: \(error)")
    }
  }

  private func isGIFData(_ data: Data) -> Bool {
    // Simple check for GIF file signature: "GIF87a" or "GIF89a"
    guard data.count > 6 else { return false }

    let header = data.prefix(6)
    let gif87a = Data([0x47, 0x49, 0x46, 0x38, 0x37, 0x61])  // "GIF87a"
    let gif89a = Data([0x47, 0x49, 0x46, 0x38, 0x39, 0x61])  // "GIF89a"

    return header == gif87a || header == gif89a
  }

  private func downloadGIF(from url: URL, completion: @escaping (Data?, Error?) -> Void) {
    URLSession.shared.dataTask(with: url) { data, response, error in
      DispatchQueue.main.async {
        if let data = data, self.isGIFData(data) {
          completion(data, nil)
        } else {
          completion(
            nil,
            error
              ?? NSError(
                domain: "GIFShare", code: -1,
                userInfo: [NSLocalizedDescriptionKey: "Invalid GIF data"]))
        }
      }
    }.resume()
  }

  private func saveGIF() {
    guard let gifData = gifData else {
      showError(message: "No GIF data to save")
      return
    }

    addDebugMessage("Starting to save GIF, size: \(gifData.count) bytes")

    // Save the GIF using the shared App Group container
    let userDefaults = UserDefaults(suiteName: appGroupID)
    let fileManager = FileManager.default

    // IMPORTANT: Use the same path conventions as GIFFileManager
    guard
      let containerURL = fileManager.containerURL(forSecurityApplicationGroupIdentifier: appGroupID)
    else {
      showError(message: "Could not access shared container")
      return
    }

    // Use the same folder name as in GIFFileManager
    let gifsFolder = containerURL.appendingPathComponent("SharedGIFs", isDirectory: true)

    // Create GIFs directory if needed
    if !fileManager.fileExists(atPath: gifsFolder.path) {
      do {
        try fileManager.createDirectory(at: gifsFolder, withIntermediateDirectories: true)
        addDebugMessage("Created shared GIFs directory")
      } catch {
        showError(message: "Could not create GIFs directory: \(error.localizedDescription)")
        return
      }
    }

    // Create a unique filename using the same pattern as GIFFileManager
    let urlHash = originalURL.hashValue
    let timestamp = Int(Date().timeIntervalSince1970)
    let filename = "gif_\(urlHash)_\(timestamp).gif"
    let fileURL = gifsFolder.appendingPathComponent(filename)

    // Save the GIF file
    do {
      try gifData.write(to: fileURL)
      addDebugMessage("GIF saved to: \(fileURL.path)")

      // Create a UUID that will be used consistently across the app
      let gifId = UUID()

      // Store GIF entry in UserDefaults to notify main app
      let gifInfo: [String: Any] = [
        "localFilePath": fileURL.path,
        "originalURL": originalURL,
        "createdAt": Date().timeIntervalSince1970,
        "id": gifId.uuidString,
      ]

      // Add to pending GIFs list (using the same key as in GIFStorageService)
      var pendingGIFs = userDefaults?.array(forKey: pendingGIFsKey) as? [[String: Any]] ?? []
      pendingGIFs.append(gifInfo)
      userDefaults?.set(pendingGIFs, forKey: pendingGIFsKey)

      // Force synchronize to ensure changes are visible immediately
      userDefaults?.synchronize()
      addDebugMessage("GIF info saved to UserDefaults")

      // Success
      completeRequest()

    } catch {
      showError(message: "Error saving GIF: \(error.localizedDescription)")
    }
  }

  private func addDebugMessage(_ message: String) {
    let timestamp = DateFormatter.localizedString(
      from: Date(), dateStyle: .none, timeStyle: .medium)
    debugMessages.append("[\(timestamp)] \(message)")
    print("GIFCollector Debug: \(message)")
  }

  @objc private func showDebugInfo() {
    let debugText = debugMessages.joined(separator: "\n\n")
    let alert = UIAlertController(
      title: "Debug Information", message: debugText, preferredStyle: .alert)
    alert.addAction(
      UIAlertAction(title: "Copy", style: .default) { _ in
        UIPasteboard.general.string = debugText
      })
    alert.addAction(UIAlertAction(title: "OK", style: .cancel))
    present(alert, animated: true)
  }

  private func showError(message: String) {
    addDebugMessage("ERROR: \(message)")
    let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
    alert.addAction(
      UIAlertAction(title: "OK", style: .default) { [weak self] _ in
        self?.completeRequest()
      })

    // Add debug info button
    #if DEBUG
      alert.addAction(
        UIAlertAction(title: "Debug Info", style: .default) { [weak self] _ in
          self?.showDebugInfo()
        })
    #endif

    present(alert, animated: true)
  }

  private func completeRequest() {
    addDebugMessage("Completing extension request")
    extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
  }
}
