import { useState } from 'react';
import { FileField } from '@/Components/ui/FileField';
import { SosmedChecklist } from '@/Components/Kegiatan/SosmedChecklist';
import type { SosmedItem } from '@/Components/Kegiatan/SosmedChecklist';

export type DokKey =
    | 'mentah'
    | 'timestamp'
    | 'matang'
    | 'video_mentah'
    | 'video_jadi'
    | 'daftar_hadir_berkas'
    | 'daftar_hadir_xlsx'
    | 'draf_berita';

export type Dokumentasi = Record<DokKey, string[]>;

export const emptyDokumentasi = (): Dokumentasi => ({
    mentah: [],
    timestamp: [],
    matang: [],
    video_mentah: [],
    video_jadi: [],
    daftar_hadir_berkas: [],
    daftar_hadir_xlsx: [],
    draf_berita: [],
});

export function toDokumentasi(raw?: Partial<Dokumentasi> | null): Dokumentasi {
    return {
        mentah: raw?.mentah ?? [],
        timestamp: raw?.timestamp ?? [],
        matang: raw?.matang ?? [],
        video_mentah: raw?.video_mentah ?? [],
        video_jadi: raw?.video_jadi ?? [],
        daftar_hadir_berkas: raw?.daftar_hadir_berkas ?? [],
        daftar_hadir_xlsx: raw?.daftar_hadir_xlsx ?? [],
        draf_berita: raw?.draf_berita ?? [],
    };
}

const GROUPS: { group: string; items: { key: DokKey; label: string }[] }[] = [
    {
        group: 'Dokumentasi',
        items: [
            { key: 'mentah', label: 'Foto Mentah' },
            { key: 'timestamp', label: 'Foto Timestamps' },
            { key: 'matang', label: 'Foto Carousel' },
        ],
    },
    {
        group: 'Video',
        items: [
            { key: 'video_mentah', label: 'Video Mentah' },
            { key: 'video_jadi', label: 'Video Jadi' },
        ],
    },
    {
        group: 'Daftar Hadir',
        items: [
            { key: 'daftar_hadir_berkas', label: 'Daftar Hadir (Berkas)' },
            { key: 'daftar_hadir_xlsx', label: 'Daftar Hadir (XLSX)' },
        ],
    },
    {
        group: 'Berita',
        items: [{ key: 'draf_berita', label: 'Draf Berita' }],
    },
];

const LABEL: Record<DokKey, string> = {
    mentah: 'Foto Mentah',
    timestamp: 'Foto Timestamps',
    matang: 'Foto Carousel',
    video_mentah: 'Video Mentah',
    video_jadi: 'Video Jadi',
    daftar_hadir_berkas: 'Daftar Hadir (Berkas)',
    daftar_hadir_xlsx: 'Daftar Hadir (XLSX)',
    draf_berita: 'Draf Berita',
};

const FOLDER: Record<DokKey, string> = {
    mentah: 'kegiatan/dokumentasi/mentah',
    timestamp: 'kegiatan/dokumentasi/timestamp',
    matang: 'kegiatan/dokumentasi/matang',
    video_mentah: 'kegiatan/video/mentah',
    video_jadi: 'kegiatan/video/jadi',
    daftar_hadir_berkas: 'kegiatan/daftar-hadir/berkas',
    daftar_hadir_xlsx: 'kegiatan/daftar-hadir/xlsx',
    draf_berita: 'kegiatan/draf-berita',
};

const ACCEPT: Partial<Record<DokKey, string>> = {
    video_mentah: 'video/*',
    video_jadi: 'video/*',
    daftar_hadir_xlsx: '.xlsx,.xls,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel',
};

const HINT: Partial<Record<DokKey, string>> = {
    video_mentah: 'Video, bisa lebih dari satu',
    video_jadi: 'Video, bisa lebih dari satu',
    daftar_hadir_xlsx: 'Berkas XLSX, bisa lebih dari satu',
};

const isImage = (url: string) => /\.(png|jpe?g|gif|webp|svg)(\?.*)?$/i.test(url);

type OpenKey = DokKey | 'sosmed';

interface Props {
    value: Dokumentasi;
    onChange: (next: Dokumentasi) => void;
    sosmed?: SosmedItem[];
    onSosmedChange?: (next: SosmedItem[]) => void;
    readOnly?: boolean;
    fileDetails?: Record<string, { file_size?: number; uploader?: string; uploaded_at?: string }>;
}

const formatBytes = (bytes?: number) => {
    if (!bytes || bytes === 0) return '';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
};

const fileName = (url: string) => {
    try {
        return decodeURIComponent(url.split('?')[0].split('/').pop() ?? '');
    } catch {
        return url.split('/').pop() ?? '';
    }
};

const getThumbUrl = (url: string) => {
    if (!url || !isImage(url)) return url;
    const parts = url.split('/');
    const last = parts.pop() ?? '';
    if (last.startsWith('thumb_')) return url;
    return [...parts, `thumb_${last}`].join('/');
};

export function DokumentasiPanel({ value, onChange, sosmed, onSosmedChange, readOnly, fileDetails = {} }: Props) {
    const dok = toDokumentasi(value);
    const [open, setOpen] = useState<OpenKey>('mentah');

    const handleDokChange = (key: DokKey, urls: string[]) => {
        const nextDok = { ...toDokumentasi(value), [key]: urls };
        onChange(nextDok);
    };

    return (
        <div className="flex flex-col sm:flex-row gap-4 sm:gap-6">
            <aside className="sm:w-56 shrink-0 flex flex-col gap-4">
                {GROUPS.map((g) => (
                    <div key={g.group}>
                        <p className="px-2 mb-1 text-xs font-bold uppercase tracking-wide text-gray-400">{g.group}</p>
                        <div className="flex flex-col gap-0.5">
                            {g.items.map((it) => {
                                const active = open === it.key;
                                return (
                                    <button
                                        key={it.key}
                                        type="button"
                                        onClick={() => setOpen(it.key)}
                                        className={`flex items-center justify-between gap-2 rounded-lg px-2.5 py-2 text-sm text-left transition-colors ${
                                            active ? 'bg-sky-600 text-white font-bold' : 'text-gray-600 hover:bg-gray-100'
                                        }`}
                                    >
                                        <span className="truncate">{it.label}</span>
                                        <span className={`shrink-0 text-xs ${active ? 'text-white/80' : 'text-gray-400'}`}>{dok[it.key].length}</span>
                                    </button>
                                );
                            })}
                        </div>
                    </div>
                ))}

                {onSosmedChange && (
                    <div>
                        <p className="px-2 mb-1 text-xs font-bold uppercase tracking-wide text-gray-400">Sosmed</p>
                        <div className="flex flex-col gap-0.5">
                            <button
                                type="button"
                                onClick={() => setOpen('sosmed')}
                                className={`flex items-center justify-between gap-2 rounded-lg px-2.5 py-2 text-sm text-left transition-colors ${
                                    open === 'sosmed' ? 'bg-sky-600 text-white font-bold' : 'text-gray-600 hover:bg-gray-100'
                                }`}
                            >
                                <span className="truncate">Checklist Sosmed</span>
                                <span className={`shrink-0 text-xs ${open === 'sosmed' ? 'text-white/80' : 'text-gray-400'}`}>{(sosmed ?? []).length}</span>
                            </button>
                        </div>
                    </div>
                )}
            </aside>

            <div className="flex-1 min-w-0 sm:border-l sm:border-gray-200 sm:pl-6 min-h-[20rem] max-h-[30rem] sm:h-[26rem] overflow-y-auto pr-1">
                {open === 'sosmed' ? (
                    <SosmedChecklist value={sosmed ?? []} onChange={onSosmedChange ?? (() => {})} readOnly={readOnly} />
                ) : !readOnly ? (
                    <FileField
                        key={open}
                        label={LABEL[open]}
                        folder={FOLDER[open]}
                        accept={ACCEPT[open]}
                        hint={HINT[open]}
                        value={dok[open]}
                        onChange={(urls) => handleDokChange(open as DokKey, urls)}
                        fileDetails={fileDetails}
                    />
                ) : dok[open].length > 0 ? (
                    <>
                        <p className="mb-3 text-sm font-semibold text-gray-700">{LABEL[open]}</p>
                        <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3">
                            {dok[open].map((url, i) => (
                                <div key={url + i} className="bg-white rounded-xl border border-gray-200 overflow-hidden shadow-2xs flex flex-col justify-between">
                                    <a href={url} target="_blank" rel="noreferrer" className="aspect-video block bg-gray-100 relative group overflow-hidden">
                                        {isImage(url) ? (
                                            <img
                                                src={getThumbUrl(url)}
                                                onError={(e) => {
                                                    const target = e.currentTarget;
                                                    if (target.src !== url) {
                                                        target.src = url;
                                                    }
                                                }}
                                                alt={LABEL[open]}
                                                loading="lazy"
                                                decoding="async"
                                                className="w-full h-full object-cover group-hover:scale-105 transition-transform"
                                            />
                                        ) : (
                                            <span className="flex w-full h-full items-center justify-center bg-gray-50 text-sky-600 text-xs font-medium text-center p-2">
                                                Buka Berkas
                                            </span>
                                        )}
                                    </a>
                                    <div className="p-2 flex flex-col gap-0.5">
                                        <p className="text-xs font-medium text-gray-800 truncate" title={fileName(url)}>
                                            {fileName(url)}
                                        </p>
                                        <div className="flex items-center justify-between text-[10px] text-gray-400">
                                            <span>{formatBytes(fileDetails[url]?.file_size)}</span>
                                            {fileDetails[url]?.uploader && (
                                                <span className="truncate max-w-[100px]" title={`Pengunggah: ${fileDetails[url]?.uploader}`}>
                                                    Oleh: <strong className="text-gray-600">{fileDetails[url]?.uploader}</strong>
                                                </span>
                                            )}
                                        </div>
                                        {fileDetails[url]?.uploaded_at && (
                                            <div className="text-[9px] text-gray-400">
                                                {fileDetails[url]?.uploaded_at}
                                            </div>
                                        )}
                                    </div>
                                </div>
                            ))}
                        </div>
                    </>
                ) : (
                    <span className="text-sm text-gray-400">Belum ada berkas di {LABEL[open]}.</span>
                )}
            </div>
        </div>
    );
}
