// ── Feedback Client ─────────────────────────────────────
// Submit user feedback with optional screenshot attachments.
// Part of ByteLystPlatformSDK for all iOS/watchOS/macOS apps.
//
// TODO-2: Full implementation for iOS feedback submission

import Foundation
import UIKit

/// Feedback types supported by the platform.
public enum BLFeedbackType: String, Codable, Sendable {
    case bug
    case feature
    case praise
    case other
}

/// Device context for debugging.
public struct BLDeviceContext: Codable, Sendable {
    public let osVersion: String
    public let appVersion: String
    public let deviceModel: String
    public let screenResolution: String
    public let locale: String
    
    public init(
        osVersion: String,
        appVersion: String,
        deviceModel: String,
        screenResolution: String,
        locale: String
    ) {
        self.osVersion = osVersion
        self.appVersion = appVersion
        self.deviceModel = deviceModel
        self.screenResolution = screenResolution
        self.locale = locale
    }
    
    /// Auto-detect current device context.
    public static func current() -> BLDeviceContext {
        let device = UIDevice.current
        let screen = UIScreen.main
        let bounds = screen.bounds
        let scale = screen.scale
        
        return BLDeviceContext(
            osVersion: device.systemVersion,
            appVersion: Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "unknown",
            deviceModel: device.model,
            screenResolution: "\(Int(bounds.width * scale))x\(Int(bounds.height * scale))",
            locale: Locale.current.identifier
        )
    }
}

/// Screenshot content types.
public enum BLScreenshotContentType: String, Codable, Sendable {
    case png = "image/png"
    case jpeg = "image/jpeg"
    case webp = "image/webp"
}

/// Response from feedback SAS endpoint.
public struct BLFeedbackSASResponse: Codable, Sendable {
    public let blobPath: String
    public let uploadUrl: String
    public let expiresIn: Int
    public let maxSizeBytes: Int
}

/// Response from feedback submission.
public struct BLFeedbackResponse: Codable, Sendable {
    public let id: String
    public let productId: String
    public let userId: String
    public let type: String
    public let title: String
    public let status: String
    public let createdAt: String
    public let screenshotBlobPath: String?
}

/// Parameters for submitting feedback.
public struct BLFeedbackParams: Sendable {
    public let type: BLFeedbackType
    public let title: String
    public let body: String?
    public let screen: String?
    public let rating: Int?
    public let screenshot: (data: Data, contentType: BLScreenshotContentType)?
    public let deviceContext: BLDeviceContext?
    
    public init(
        type: BLFeedbackType,
        title: String,
        body: String? = nil,
        screen: String? = nil,
        rating: Int? = nil,
        screenshot: (data: Data, contentType: BLScreenshotContentType)? = nil,
        deviceContext: BLDeviceContext? = nil
    ) {
        self.type = type
        self.title = title
        self.body = body
        self.screen = screen
        self.rating = rating
        self.screenshot = screenshot
        self.deviceContext = deviceContext
    }
}

/// Feedback client for submitting user feedback with screenshots.
/// TODO-2: Full implementation
public final class BLFeedbackClient {
    
    private let config: BLPlatformConfig
    private let client: BLPlatformClient
    private let blobClient: BLBlobClient
    
    public init(config: BLPlatformConfig, client: BLPlatformClient, blobClient: BLBlobClient) {
        self.config = config
        self.client = client
        self.blobClient = blobClient
    }
    
    // MARK: - Submit Feedback
    
    /// Submit feedback with optional screenshot.
    ///
    /// Flow:
    /// 1. If screenshot provided, upload to blob storage
    /// 2. Submit feedback with screenshot metadata
    ///
    /// TODO-2: Full implementation
    public func submitFeedback(_ params: BLFeedbackParams) async throws -> BLFeedbackResponse {
        var screenshotMeta: (blobPath: String, contentType: String, sizeBytes: Int)?
        
        // Step 1: Handle screenshot upload if provided
        if let screenshot = params.screenshot {
            // Get SAS URL for upload
            let sas = try await generateSASURL(contentType: screenshot.contentType)
            
            // Upload screenshot
            try await uploadScreenshot(data: screenshot.data, sasURL: sas.uploadUrl, contentType: screenshot.contentType.rawValue)
            
            screenshotMeta = (
                blobPath: sas.blobPath,
                contentType: screenshot.contentType.rawValue,
                sizeBytes: screenshot.data.count
            )
        }
        
        // Step 2: Submit feedback
        var body: [String: Any] = [
            "type": params.type.rawValue,
            "title": params.title,
        ]
        
        if let bodyText = params.body { body["body"] = bodyText }
        if let screen = params.screen { body["screen"] = screen }
        if let rating = params.rating { body["rating"] = rating }
        if let meta = screenshotMeta {
            body["screenshotBlobPath"] = meta.blobPath
            body["screenshotContentType"] = meta.contentType
            body["screenshotSizeBytes"] = meta.sizeBytes
        }
        if let context = params.deviceContext {
            body["deviceContext"] = [
                "osVersion": context.osVersion,
                "appVersion": context.appVersion,
                "deviceModel": context.deviceModel,
                "screenResolution": context.screenResolution,
                "locale": context.locale,
            ]
        }
        
        throw BLFeedbackError.notImplemented(
            "submitFeedback body encoding and API call not yet implemented. " +
            "Use client.request(path: \"/api/feedback\", method: \"POST\", body: body)"
        )
    }
    
    /// Capture screenshot and submit feedback in one operation.
    ///
    /// TODO-2: Implement using UIApplication.shared.windows or UIScreen
    public func captureAndSubmit(
        type: BLFeedbackType,
        title: String,
        body: String? = nil
    ) async throws -> BLFeedbackResponse {
        throw BLFeedbackError.notImplemented(
            "captureAndSubmit not yet implemented.\n\n" +
            "To implement:\n" +
            "1. Use UIGraphicsImageRenderer or UIScreen to capture\n" +
            "2. Convert UIImage to Data (PNG/JPEG)\n" +
            "3. Call submitFeedback with captured data\n\n" +
            "Example:\n" +
            "let window = UIApplication.shared.windows.first\n" +
            "UIGraphicsBeginImageContext(window.bounds.size)\n" +
            "window.drawHierarchy(in: window.bounds, afterScreenUpdates: true)\n" +
            "let image = UIGraphicsGetImageFromCurrentImageContext()\n" +
            "UIGraphicsEndImageContext()"
        )
    }
    
    // MARK: - Screenshot Capture
    
    /// Capture current screen as UIImage.
    ///
    /// TODO-2: Full implementation
    public func captureScreen() async throws -> UIImage {
        throw BLFeedbackError.notImplemented(
            "captureScreen not yet implemented. Use UIScreen or UIApplication.shared.windows"
        )
    }
    
    /// Capture specific UIView as UIImage.
    ///
    /// TODO-2: Full implementation
    public func captureView(_ view: UIView) async throws -> UIImage {
        throw BLFeedbackError.notImplemented(
            "captureView not yet implemented. Use UIGraphicsImageRenderer or drawHierarchy"
        )
    }
    
    // MARK: - Private
    
    private func generateSASURL(contentType: BLScreenshotContentType) async throws -> BLFeedbackSASResponse {
        let body = ["contentType": contentType.rawValue]
        return try await client.request(
            path: "/api/feedback/sas",
            method: "POST",
            body: body,
            responseType: BLFeedbackSASResponse.self
        )
    }
    
    private func uploadScreenshot(data: Data, sasURL: String, contentType: String) async throws {
        guard let url = URL(string: sasURL) else {
            throw BLNetworkError.invalidURL(sasURL)
        }
        
        var request = URLRequest(url: url)
        request.httpMethod = "PUT"
        request.setValue(contentType, forHTTPHeaderField: "Content-Type")
        request.setValue("BlockBlob", forHTTPHeaderField: "x-ms-blob-type")
        request.httpBody = data
        request.timeoutInterval = 60
        
        let (_, response) = try await URLSession.shared.data(for: request)
        
        guard let http = response as? HTTPURLResponse,
              (200...299).contains(http.statusCode) else {
            throw BLNetworkError.httpError(
                statusCode: (response as? HTTPURLResponse)?.statusCode ?? 0,
                message: "Screenshot upload failed"
            )
        }
    }
}

/// Errors specific to feedback operations.
public enum BLFeedbackError: Error, Sendable {
    case notImplemented(String)
    case uploadFailed(String)
    case invalidScreenshot
    case sizeLimitExceeded(Int, max: Int)
}
