//
//  ExportView.swift
//  CheapRetouch
//
//  Export edited photos at full resolution.
//

import SwiftUI
import UIKit
import Photos

struct ExportView: View {
    let image: CGImage
    @Environment(\.dismiss) private var dismiss

    @State private var isExporting = false
    @State private var exportProgress: Double = 0
    @State private var showingShareSheet = false
    @State private var showingError = false
    @State private var errorMessage = ""
    @State private var showingSuccess = false
    @State private var selectedFormat: ExportFormat = .jpeg
    @State private var jpegQuality: Double = 0.9

    enum ExportFormat: String, CaseIterable, Identifiable {
        case jpeg = "JPEG"
        case png = "PNG"
        case heic = "HEIC"

        var id: String { rawValue }

        var utType: String {
            switch self {
            case .jpeg: return "public.jpeg"
            case .png: return "public.png"
            case .heic: return "public.heic"
            }
        }
    }

    var body: some View {
        NavigationStack {
            Form {
                Section {
                    // Preview
                    Image(decorative: image, scale: 1.0)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(maxHeight: 200)
                        .frame(maxWidth: .infinity)
                        .background(Color.black)
                        .clipShape(RoundedRectangle(cornerRadius: 8))
                }

                Section("Format") {
                    Picker("Format", selection: $selectedFormat) {
                        ForEach(ExportFormat.allCases) { format in
                            Text(format.rawValue).tag(format)
                        }
                    }
                    .pickerStyle(.segmented)

                    if selectedFormat == .jpeg {
                        VStack(alignment: .leading, spacing: 8) {
                            HStack {
                                Text("Quality")
                                Spacer()
                                Text("\(Int(jpegQuality * 100))%")
                                    .foregroundStyle(.secondary)
                            }
                            Slider(value: $jpegQuality, in: 0.5...1.0, step: 0.05)
                        }
                    }
                }

                Section("Image Info") {
                    LabeledContent("Dimensions", value: "\(image.width) × \(image.height)")
                    LabeledContent("Estimated Size", value: estimatedFileSize)
                }

                Section {
                    Button {
                        Task {
                            await saveToPhotoLibrary()
                        }
                    } label: {
                        Label("Save to Photos", systemImage: "photo.on.rectangle")
                    }
                    .disabled(isExporting)

                    Button {
                        showingShareSheet = true
                    } label: {
                        Label("Share", systemImage: "square.and.arrow.up")
                    }
                    .disabled(isExporting)
                }
            }
            .navigationTitle("Export")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") {
                        dismiss()
                    }
                }
            }
            .overlay {
                if isExporting {
                    exportingOverlay
                }
            }
            .alert("Export Failed", isPresented: $showingError) {
                Button("OK") {}
            } message: {
                Text(errorMessage)
            }
            .alert("Saved", isPresented: $showingSuccess) {
                Button("OK") {
                    dismiss()
                }
            } message: {
                Text("Photo saved to your library")
            }
            .sheet(isPresented: $showingShareSheet) {
                if let data = exportedImageData {
                    ShareSheet(items: [data])
                }
            }
        }
    }

    private var estimatedFileSize: String {
        let pixels = image.width * image.height
        let bytesPerPixel: Double

        switch selectedFormat {
        case .jpeg:
            bytesPerPixel = 0.5 * jpegQuality + 0.1
        case .png:
            bytesPerPixel = 1.5
        case .heic:
            bytesPerPixel = 0.3
        }

        let bytes = Double(pixels) * bytesPerPixel
        return ByteCountFormatter.string(fromByteCount: Int64(bytes), countStyle: .file)
    }

    private var exportedImageData: Data? {
        let uiImage = UIImage(cgImage: image)

        switch selectedFormat {
        case .jpeg:
            return uiImage.jpegData(compressionQuality: jpegQuality)
        case .png:
            return uiImage.pngData()
        case .heic:
            return uiImage.heicData()
        }
    }

    private var exportingOverlay: some View {
        VStack(spacing: 12) {
            ProgressView()
                .scaleEffect(1.2)
            Text("Exporting...")
                .font(.subheadline)
        }
        .padding(24)
        .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
    }

    private func saveToPhotoLibrary() async {
        isExporting = true

        do {
            // Request permission
            let status = await PHPhotoLibrary.requestAuthorization(for: .addOnly)
            guard status == .authorized || status == .limited else {
                throw ExportError.permissionDenied
            }

            guard let data = exportedImageData else {
                throw ExportError.encodingFailed
            }

            try await PHPhotoLibrary.shared().performChanges {
                let request = PHAssetCreationRequest.forAsset()
                request.addResource(with: .photo, data: data, options: nil)
            }

            showingSuccess = true
        } catch {
            errorMessage = error.localizedDescription
            showingError = true
        }

        isExporting = false
    }

    enum ExportError: LocalizedError {
        case permissionDenied
        case encodingFailed

        var errorDescription: String? {
            switch self {
            case .permissionDenied:
                return "Photo library access denied. Please enable it in Settings."
            case .encodingFailed:
                return "Failed to encode image"
            }
        }
    }
}

// MARK: - ShareSheet

struct ShareSheet: UIViewControllerRepresentable {
    let items: [Any]

    func makeUIViewController(context: Context) -> UIActivityViewController {
        UIActivityViewController(activityItems: items, applicationActivities: nil)
    }

    func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {}
}

// MARK: - UIImage HEIC Extension

extension UIImage {
    func heicData(compressionQuality: CGFloat = 0.9) -> Data? {
        guard let cgImage = self.cgImage else { return nil }

        let mutableData = NSMutableData()
        guard let destination = CGImageDestinationCreateWithData(
            mutableData,
            "public.heic" as CFString,
            1,
            nil
        ) else {
            return nil
        }

        let options: [CFString: Any] = [
            kCGImageDestinationLossyCompressionQuality: compressionQuality
        ]

        CGImageDestinationAddImage(destination, cgImage, options as CFDictionary)

        guard CGImageDestinationFinalize(destination) else {
            return nil
        }

        return mutableData as Data
    }
}

#Preview {
    if let image = UIImage(systemName: "photo")?.cgImage {
        ExportView(image: image)
    }
}
