import AVFoundation
import AVKit
import Utilities
import SwiftUI
import UIKit

private let log = Logger(category: "DebugFileViewerPanel")

struct DebugFileViewerPanel: View {
    let fileDataModel: OnDeviceFileDataModel

    var body: some View {
        ZStack {
            Color.black.opacity(0.5)
            switch fileDataModel.highLevelFileType {
            case .generic, .audio, .archive:
                VStack {
                    Image(systemName: fileDataModel.highLevelFileType.icon)
                        .font(.system(size: 24.0))
                        .foregroundStyle(.white.opacity(0.5))
                    Text(fileDataModel.lastComponent)
                        .font(.system(size: 24.0))
                        .foregroundStyle(.white.opacity(0.5))
                }

            case .movie:
                FitVideoPreviewView(player: .init(playerItem: .init(url: fileDataModel.url)))

            case .image:
                AsyncImage(
                    url: fileDataModel.url)
                { image in
                    image
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                } placeholder: {
                    ProgressView()
                        .progressViewStyle(.circular)
                }

            case .json:
                if let debugText = debugPrettyPrintJSON(from: fileDataModel.url) {
                    TextEditor(text: .constant(debugText))
                        .font(.system(size: 10.0))
                        .foregroundStyle(.white.opacity(0.8))
                        .textEditorStyle(.plain)
                }

            case .text:
                if let text = try? String(contentsOf: fileDataModel.url, encoding: .utf8) {
                    TextEditor(text: .constant(text))
                        .textEditorStyle(.plain)
                }

            case .directory:
                EmptyView()
            }
        }
    }
}

private func debugPrettyPrintJSON(from fileURL: URL) -> String? {
    do {
        let data = try Data(contentsOf: fileURL)
        // Print raw data for debugging
        if let rawString = String(data: data, encoding: .utf8) {
            log.debug("Raw JSON data:\n\(rawString)")
        }

        let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])
        let prettyData = try JSONSerialization.data(withJSONObject: jsonObject, options: [.prettyPrinted])
        let prettyPrintedString = String(data: prettyData, encoding: .utf8)
        return prettyPrintedString
    } catch {
        log.telemetry.error(error, message: "Error loading or parsing JSON.")
        return nil
    }
}

private struct FitVideoPreviewView: UIViewRepresentable {
    let player: AVPlayer?

    func makeUIView(context _: Context) -> FitPlayerView {
        return FitPlayerView(player: player)
    }

    func updateUIView(_ uiView: FitPlayerView, context _: Context) {
        uiView.player = player
    }

    init(player: AVPlayer?) {
        player?.play()
        self.player = player
    }
}

private class FitPlayerView: UIView {
    var player: AVPlayer? {
        get { playerLayer.player }
        set { playerLayer.player = newValue }
    }

    var playerLayer: AVPlayerLayer {
        return layer as! AVPlayerLayer
    }

    override static var layerClass: AnyClass {
        return AVPlayerLayer.self
    }

    init(player: AVPlayer?) {
        super.init(frame: .zero)
        self.player = player
        setupLayer()
    }

    @available(*, unavailable)
    required init?(coder _: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setupLayer() {
        playerLayer.videoGravity = .resizeAspect
        playerLayer.backgroundColor = UIColor.clear.cgColor
        playerLayer.masksToBounds = true
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        playerLayer.frame = bounds
    }
}
