//
//  Attachments.swift
//  kordophone2
//
//  Created by Assistant on 8/31/25.
//

import Foundation
import UniformTypeIdentifiers

enum AttachmentState
{
    case staged
    case uploading(progress: Double)
    case uploaded(String) // fileTransferGUID
    case failed
}

@Observable
class OutgoingAttachment: Identifiable, Hashable
{
    let id: String
    let originalURL: URL
    let stagedURL: URL
    let fileName: String
    let contentType: UTType?
    var state: AttachmentState

    init(id: String = UUID().uuidString,
         originalURL: URL,
         stagedURL: URL,
         fileName: String? = nil,
         contentType: UTType? = nil,
         state: AttachmentState = .staged)
    {
        self.id = id
        self.originalURL = originalURL
        self.stagedURL = stagedURL
        self.fileName = fileName ?? originalURL.lastPathComponent
        self.contentType = contentType
        self.state = state
    }
    
    static func ==(lhs: OutgoingAttachment, rhs: OutgoingAttachment) -> Bool {
        return lhs.id == rhs.id
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
        hasher.combine(originalURL)
        hasher.combine(stagedURL)
        hasher.combine(fileName)
    }
}

final class AttachmentManager
{
    static let shared = AttachmentManager()

    private let fileManager = FileManager.default
    private let stagingRoot: URL

    private init() {
        let base = fileManager.temporaryDirectory.appendingPathComponent("kordophone-staging", isDirectory: true)
        try? fileManager.createDirectory(at: base, withIntermediateDirectories: true)
        self.stagingRoot = base
    }

    func stageIfImage(url: URL) -> OutgoingAttachment? {
        guard isImage(url: url) else { return nil }
        let staged = stage(url: url)
        let type = (try? url.resourceValues(forKeys: [.contentTypeKey]))?.contentType
            ?? UTType(filenameExtension: url.pathExtension)
        return OutgoingAttachment(originalURL: url, stagedURL: staged, fileName: url.lastPathComponent, contentType: type)
    }

    // MARK: - Helpers

    private func isImage(url: URL) -> Bool {
        if let type = (try? url.resourceValues(forKeys: [.contentTypeKey]))?.contentType {
            return type.conforms(to: .image)
        }
        return UTType(filenameExtension: url.pathExtension)?.conforms(to: .image) ?? false
    }

    private func stage(url: URL) -> URL {
        let ext = url.pathExtension
        let dest = stagingRoot.appendingPathComponent(UUID().uuidString).appendingPathExtension(ext)
        do {
            if fileManager.fileExists(atPath: dest.path) { try? fileManager.removeItem(at: dest) }
            try fileManager.copyItem(at: url, to: dest)
            return dest
        } catch {
            do {
                try fileManager.moveItem(at: url, to: dest)
                return dest
            } catch {
                return url
            }
        }
    }
}
