//
//  ParsedImage.swift
//
//
//  Created by Thibaut Schmitt on 24/01/2022.
//

import Foundation
import ToolCore

enum ImageExtension: String {

    case png
}

struct ParsedImage {

    // MARK: - Properties

    let name: String
    let tags: String
    let width: Int
    let height: Int
    let imageExtensions: [ImageExtension]

    init(
        name: String,
        tags: String,
        width: Int,
        height: Int,
        imageExtensions: [ImageExtension] = []
    ) {
        self.name = name
        self.tags = tags
        self.width = width
        self.height = height
        self.imageExtensions = imageExtensions
    }

    // MARK: - Convert

    var convertArguments: (x1: ConvertArgument, x2: ConvertArgument, x3: ConvertArgument) { // swiftlint:disable:this large_tuple
        var width1x = ""
        var height1x = ""
        var width2x = ""
        var height2x = ""
        var width3x = ""
        var height3x = ""

        if width != -1 {
            width1x = "\(width)"
            width2x = "\(width * 2)"
            width3x = "\(width * 3)"
        }

        if height != -1 {
            height1x = "\(height)"
            height2x = "\(height * 2)"
            height3x = "\(height * 3)"
        }

        return (x1: ConvertArgument(width: width1x, height: height1x),
                x2: ConvertArgument(width: width2x, height: height2x),
                x3: ConvertArgument(width: width3x, height: height3x))
    }

    // MARK: - Assets

    func generateContentJson(isVector: Bool) -> String? {
        let encoder = JSONEncoder()
        encoder.outputFormatting = [.prettyPrinted, .sortedKeys]

        let imageContent = generateImageContent(isVector: isVector)

        guard let data = try? encoder.encode(imageContent) else {
            let error = ImagesError.writeFile("Contents.json", "Error encoding json file")
            print(error.description)
            Images.exit(withError: error)
        }

        return String(decoding: data, as: UTF8.self)
    }

    func generateImageContent(isVector: Bool) -> AssetContent {
        if !imageExtensions.contains(.png) && isVector {
            // Generate svg
            return AssetContent(
                images: [
                    AssetImageDescription(
                        idiom: "universal",
                        filename: "\(name).\(OutputImageExtension.svg.rawValue)"
                    )
                ],
                info: AssetInfo(
                    version: 1,
                    author: "ResgenSwift-Imagium"
                ),
                properties: AssetProperties(
                    preservesVectorRepresentation: true,
                    templateRenderingIntent: .original
                )
            )
        } else {
            // Generate png
            return AssetContent(
                images: [
                    AssetImageDescription(
                        idiom: "universal",
                        scale: "1x",
                        filename: "\(name).\(OutputImageExtension.png.rawValue)"
                    ),
                    AssetImageDescription(
                        idiom: "universal",
                        scale: "2x",
                        filename: "\(name)@2x.\(OutputImageExtension.png.rawValue)"
                    ),
                    AssetImageDescription(
                        idiom: "universal",
                        scale: "3x",
                        filename: "\(name)@3x.\(OutputImageExtension.png.rawValue)"
                    )
                ],
                info: AssetInfo(
                    version: 1,
                    author: "ResgenSwift-Imagium"
                )
            )
        }
    }

    // MARK: - Extension property

    func getImageProperty(
        isStatic: Bool,
        isSwiftUI: Bool,
        visibility: ExtensionVisibility,
        assetBundle: AssetBundle
    ) -> String {
        if isSwiftUI {
            return """
                \(visibility) \(isStatic ? "static " : "")var \(name): Image {
                    Image("\(name)", bundle: Bundle.\(assetBundle))
                }
            """
        }
        return """
            \(visibility) \(isStatic ? "static " : "")var \(name): UIImage {
                UIImage(named: "\(name)", in: Bundle.\(assetBundle), with: nil)!
            }
        """
    }
}
