import {
    FolderIcon, FolderOpenIcon, DocumentIcon, DocumentTextIcon,
    PhotoIcon, VideoCameraIcon, MusicalNoteIcon, ArchiveBoxIcon,
    CodeBracketIcon, LinkIcon, LockClosedIcon, GlobeAltIcon,
    DocumentChartBarIcon, TableCellsIcon, PresentationChartBarIcon,
} from '@heroicons/vue/24/outline'

/**
 * File icon + colour mapping by extension/type.
 * Returns { component, colorClass } for any item.
 */
export function useFileIcon() {
    const iconFor = (item) => {
        if (item?.type === 'dir') {
            return { component: FolderIcon, colorClass: 'text-amber-500' }
        }
        if (item?.symlink) {
            return { component: LinkIcon, colorClass: 'text-cyan-500' }
        }
        const ext = (item?.name || '').split('.').pop()?.toLowerCase()
        return iconForExt(ext)
    }

    const iconForExt = (ext) => {
        const map = {
            // images
            jpg: [PhotoIcon, 'text-pink-500'],
            jpeg: [PhotoIcon, 'text-pink-500'],
            png: [PhotoIcon, 'text-pink-500'],
            gif: [PhotoIcon, 'text-pink-500'],
            webp: [PhotoIcon, 'text-pink-500'],
            svg: [PhotoIcon, 'text-pink-500'],
            ico: [PhotoIcon, 'text-pink-500'],
            bmp: [PhotoIcon, 'text-pink-500'],
            // video
            mp4: [VideoCameraIcon, 'text-purple-500'],
            webm: [VideoCameraIcon, 'text-purple-500'],
            ogg: [VideoCameraIcon, 'text-purple-500'],
            mov: [VideoCameraIcon, 'text-purple-500'],
            avi: [VideoCameraIcon, 'text-purple-500'],
            mkv: [VideoCameraIcon, 'text-purple-500'],
            // audio
            mp3: [MusicalNoteIcon, 'text-emerald-500'],
            wav: [MusicalNoteIcon, 'text-emerald-500'],
            flac: [MusicalNoteIcon, 'text-emerald-500'],
            aac: [MusicalNoteIcon, 'text-emerald-500'],
            m4a: [MusicalNoteIcon, 'text-emerald-500'],
            // archive
            zip: [ArchiveBoxIcon, 'text-amber-600'],
            tar: [ArchiveBoxIcon, 'text-amber-600'],
            gz: [ArchiveBoxIcon, 'text-amber-600'],
            tgz: [ArchiveBoxIcon, 'text-amber-600'],
            bz2: [ArchiveBoxIcon, 'text-amber-600'],
            rar: [ArchiveBoxIcon, 'text-amber-600'],
            '7z': [ArchiveBoxIcon, 'text-amber-600'],
            // code
            php: [CodeBracketIcon, 'text-indigo-500'],
            js: [CodeBracketIcon, 'text-yellow-500'],
            mjs: [CodeBracketIcon, 'text-yellow-500'],
            ts: [CodeBracketIcon, 'text-blue-500'],
            tsx: [CodeBracketIcon, 'text-blue-500'],
            jsx: [CodeBracketIcon, 'text-yellow-500'],
            vue: [CodeBracketIcon, 'text-emerald-500'],
            css: [CodeBracketIcon, 'text-sky-500'],
            scss: [CodeBracketIcon, 'text-sky-500'],
            less: [CodeBracketIcon, 'text-sky-500'],
            html: [GlobeAltIcon, 'text-orange-500'],
            htm: [GlobeAltIcon, 'text-orange-500'],
            json: [CodeBracketIcon, 'text-amber-500'],
            xml: [CodeBracketIcon, 'text-orange-500'],
            yml: [CodeBracketIcon, 'text-rose-500'],
            yaml: [CodeBracketIcon, 'text-rose-500'],
            py: [CodeBracketIcon, 'text-blue-600'],
            rb: [CodeBracketIcon, 'text-red-500'],
            go: [CodeBracketIcon, 'text-cyan-500'],
            rs: [CodeBracketIcon, 'text-orange-600'],
            java: [CodeBracketIcon, 'text-red-600'],
            c: [CodeBracketIcon, 'text-slate-600'],
            cpp: [CodeBracketIcon, 'text-slate-600'],
            cs: [CodeBracketIcon, 'text-purple-600'],
            sh: [CodeBracketIcon, 'text-slate-700'],
            bash: [CodeBracketIcon, 'text-slate-700'],
            sql: [CodeBracketIcon, 'text-blue-600'],
            // docs
            pdf: [DocumentChartBarIcon, 'text-red-500'],
            doc: [DocumentTextIcon, 'text-blue-500'],
            docx: [DocumentTextIcon, 'text-blue-500'],
            xls: [TableCellsIcon, 'text-emerald-600'],
            xlsx: [TableCellsIcon, 'text-emerald-600'],
            csv: [TableCellsIcon, 'text-emerald-600'],
            ppt: [PresentationChartBarIcon, 'text-orange-500'],
            pptx: [PresentationChartBarIcon, 'text-orange-500'],
            // plaintext
            txt: [DocumentTextIcon, 'text-slate-500'],
            md: [DocumentTextIcon, 'text-slate-700'],
            log: [DocumentTextIcon, 'text-slate-400'],
            env: [LockClosedIcon, 'text-amber-600'],
            htaccess: [LockClosedIcon, 'text-amber-600'],
            conf: [DocumentTextIcon, 'text-slate-500'],
            ini: [DocumentTextIcon, 'text-slate-500'],
            gitignore: [DocumentTextIcon, 'text-slate-500'],
        }
        const [component, colorClass] = map[ext] || [DocumentIcon, 'text-slate-400']
        return { component, colorClass }
    }

    const isImage = (name) => /\.(jpe?g|png|gif|webp|svg|bmp|ico)$/i.test(name || '')
    const isVideo = (name) => /\.(mp4|webm|ogg|mov|m4v)$/i.test(name || '')
    const isAudio = (name) => /\.(mp3|wav|flac|aac|m4a|ogg)$/i.test(name || '')
    const isArchive = (name) => /\.(zip|tar|tar\.gz|tgz|tar\.bz2|rar|7z)$/i.test(name || '')
    const isText = (name) => {
        const ext = (name || '').split('.').pop()?.toLowerCase()
        return [
            'txt', 'md', 'json', 'js', 'mjs', 'ts', 'tsx', 'vue', 'jsx', 'php', 'html',
            'htm', 'css', 'scss', 'less', 'yml', 'yaml', 'xml', 'sh', 'bash', 'conf',
            'ini', 'log', 'env', 'gitignore', 'htaccess', 'sql', 'py', 'rb', 'go',
            'rs', 'java', 'c', 'cpp', 'cs', 'svg', 'csv', 'tsv',
        ].includes(ext)
    }

    return { iconFor, iconForExt, isImage, isVideo, isAudio, isArchive, isText, FolderOpenIcon }
}

/**
 * Format byte count to human-readable string.
 */
export function formatBytes(bytes) {
    if (bytes === null || bytes === undefined) return '—'
    if (bytes < 1024) return `${bytes} B`
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
    if (bytes < 1024 * 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MB`
    return `${(bytes / 1024 / 1024 / 1024).toFixed(2)} GB`
}

/**
 * Format Unix timestamp (or ISO string) to localized date/time.
 * Returns '—' for invalid/missing input — never "Invalid Date".
 *
 * Backend stat() returns mtime as Unix seconds (int). Bazı endpoint'ler ISO 8601 string
 * dönebiliyor — her ikisini de tolere et.
 */
export function formatDate(ts) {
    if (ts === null || ts === undefined || ts === '' || ts === 'Invalid Date') return '—'
    let date
    if (typeof ts === 'number' && Number.isFinite(ts)) {
        // Unix seconds — JS Date wants milliseconds
        date = new Date(ts * 1000)
    } else if (typeof ts === 'string') {
        // Try numeric string (Unix seconds) first, then ISO/RFC
        const n = Number(ts)
        date = Number.isFinite(n) && ts.trim() !== '' && /^\d+(\.\d+)?$/.test(ts.trim())
            ? new Date(n * 1000)
            : new Date(ts)
    } else if (ts instanceof Date) {
        date = ts
    } else {
        return '—'
    }
    if (! date || Number.isNaN(date.getTime())) return '—'
    return date.toLocaleString('tr-TR', { dateStyle: 'short', timeStyle: 'short' })
}

/**
 * Compute "x gün önce" relative time. Invalid input → '—'.
 */
export function relativeTime(ts) {
    if (ts === null || ts === undefined || ts === '') return '—'
    const n = typeof ts === 'number' ? ts : Number(ts)
    if (! Number.isFinite(n)) return '—'
    const diffMs = Date.now() - n * 1000
    const days = Math.floor(diffMs / (24 * 3600 * 1000))
    if (days < 0) return 'gelecek'
    if (days === 0) return 'bugün'
    if (days === 1) return 'dün'
    if (days < 30) return `${days} gün önce`
    if (days < 365) return `${Math.floor(days / 30)} ay önce`
    return `${Math.floor(days / 365)} yıl önce`
}
