import Foundation

enum FileTypeCategory: String, CaseIterable {
    case image
    case code
    case model
    case text
    case video
    case resource
    case asset
    case audio

    var text: String {
        switch self {
        case .image: return "Images"
        case .code: return "Code"
        case .model: return "Models"
        case .text: return "Text"
        case .video: return "Videos"
        case .asset: return "Assets"
        case .resource: return "Other"
        case .audio: return "Audio"
        }
    }
}

extension FileTypeCategory: Hashable {
    
}

extension FileTypeCategory: Identifiable {

    var id: String {
        rawValue
    }
}

enum FileType: String {

    // MARK: Images

    case jpg

    case png

    case avif

    case webp

    case gif

    case svg

    case tiff

    // MARK: Code

    case html

    case cpp

    case swift

    // MARK: Assets

    case css

    case js

    case ttf

    // MARK: Text

    case json

    case conf

    case yaml

    // MARK: Model

    case stl

    case f3d

    case step

    case glb

    case f3z

    // MARK: Video

    case mp4

    case m4v

    case webm

    // MARK: Audio

    case mp3

    case aac

    case m4b

    case m4a

    // MARK: Other

    case noExtension

    case zip

    case cddx

    case pdf

    case key

    case psd

    // MARK: Unknown

    case unknown

    init(fileExtension: String?) {
        guard let lower = fileExtension?.lowercased() else {
            self = .noExtension
            return
        }
        if lower == "jpeg" {
            self = .jpg
            return
        }
        guard let type = FileType(rawValue: lower) else {
            self = .unknown
            return
        }
        self = type
    }

    var category: FileTypeCategory {
        switch self {
        case .jpg, .png, .avif, .webp, .gif, .svg, .tiff:
            return .image
        case .mp4, .m4v, .webm:
            return .video
        case .mp3, .aac, .m4b, .m4a:
            return .audio
        case .js, .css, .ttf:
            return .asset
        case .json, .conf, .yaml:
            return .text
        case .html, .cpp, .swift:
            return .code
        case .stl, .f3d, .step, .glb, .f3z:
            return .model
        case .zip, .cddx, .pdf, .key, .psd:
            return .resource
        case .noExtension, .unknown:
            return .resource
        }
    }

    var fileExtension: String? {
        switch self {
        case .noExtension, .unknown: return nil
        default:
            return rawValue
        }
    }

    var isImage: Bool {
        category == .image
    }

    var isVideo: Bool {
        category == .video
    }

    var isAudio: Bool {
        category == .audio
    }

    var isAsset: Bool {
        category == .asset
    }

    var isTextFile: Bool {
        switch category {
        case .text, .code: return true
        default: break
        }
        switch self {
        case .css, .js: return true
        default: return false
        }
    }

    var htmlType: String? {
        switch self {
        case .mp4, .m4v:
            return "video/mp4"
        case .webm:
            return "video/webm"
        default:
            return nil
        }
    }

    var isSvg: Bool {
        guard case .svg = self else {
            return false
        }
        return true
    }
}
