import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogTrigger } from '@/components/ui/dialog';
import axios from 'axios';
import { useEffect, useState } from 'react';
import { MediaItem } from '../types';
import { MediaManager } from './MediaManager';

declare const route: (...args: any[]) => string;

interface MediaPickerProps {
    onSelect: (item: MediaItem) => void;
    trigger?: React.ReactNode;
    open?: boolean;
    onOpenChange?: (open: boolean) => void;
    enableMultiSelect?: boolean;
    onMultiSelect?: (items: MediaItem[]) => void;
    defaultValue?: MediaItem | MediaItem[];
    appName?: string;
    appModule?: string;
}

export function MediaPicker({
    onSelect,
    trigger,
    open: controlledOpen,
    onOpenChange: controlledOpenChange,
    enableMultiSelect = false,
    onMultiSelect,
    defaultValue,
    appName = 'platform',
    appModule = 'media',
}: MediaPickerProps) {
    const [internalOpen, setInternalOpen] = useState(false);
    const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;
    const setIsOpen = controlledOpenChange || setInternalOpen;

    const [items, setItems] = useState<MediaItem[]>([]);
    const [loading, setLoading] = useState(false);
    const [selectedItems, setSelectedItems] = useState<MediaItem[]>([]);

    useEffect(() => {
        if (isOpen && defaultValue) {
            const defaults = Array.isArray(defaultValue) ? defaultValue : [defaultValue];
            setSelectedItems(defaults);
        }
    }, [isOpen, defaultValue]);

    const fetchData = async (search = '') => {
        setLoading(true);
        try {
            const response = await axios.get(route('media.index'), {
                params: { search, format: 'json' },
                headers: { Accept: 'application/json' },
            });
            setItems(response.data.data);
        } catch (error) {
            console.error('Failed to fetch media', error);
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        if (isOpen && items.length === 0) {
            fetchData();
        }
    }, [isOpen]);

    const handleUpload = async (files: File[]) => {
        setLoading(true);
        const formData = new FormData();
        files.forEach((file) => formData.append('file', file));
        formData.append('app_name', appName);
        formData.append('app_module', appModule);

        try {
            await axios.post(route('media.store'), formData, {
                headers: { 'Content-Type': 'multipart/form-data' },
            });
            fetchData();
        } catch (error) {
            console.error('Upload failed', error);
        }
        setLoading(false);
    };

    const handleDelete = async (id: number) => {
        if (!confirm('Are you sure you want to delete this file?')) return;
        try {
            await axios.delete(route('media.destroy', id));
            setItems((prev) => prev.filter((i) => i.id !== id));
        } catch (error) {
            console.error('Delete failed', error);
        }
    };

    const handleUpdate = async (item: MediaItem) => {
        setItems((prev) => prev.map((i) => (i.id === item.id ? item : i)));
    };

    const handleConfirm = () => {
        if (enableMultiSelect) {
            onMultiSelect?.(selectedItems);
        } else if (selectedItems.length > 0) {
            onSelect(selectedItems[0]);
        }
        setIsOpen(false);
    };

    return (
        <Dialog open={isOpen} onOpenChange={setIsOpen}>
            {trigger && <DialogTrigger asChild>{trigger}</DialogTrigger>}
            <DialogContent className="flex h-[85vh] max-w-6xl flex-col gap-0 overflow-hidden p-0">
                {/* WordPress-style header */}
                <div className="flex items-center justify-between border-b border-[#c3c4c7] bg-white px-4 py-3 dark:border-zinc-700 dark:bg-zinc-800">
                    <h2 className="text-lg font-semibold text-[#1d2327] dark:text-zinc-200">
                        {enableMultiSelect ? 'Select Images' : 'Select Image'}
                    </h2>
                </div>

                {/* Media Manager */}
                <div className="flex-1 overflow-hidden">
                    <MediaManager
                        items={items}
                        onSearch={(query) => fetchData(query)}
                        onUpload={handleUpload}
                        onDelete={handleDelete}
                        onUpdate={handleUpdate}
                        isLoading={loading}
                        enableMultiSelect={enableMultiSelect}
                        onSelectionChange={setSelectedItems}
                    />
                </div>

                {/* Footer */}
                <div className="flex items-center justify-between border-t border-[#c3c4c7] bg-[#f6f7f7] px-4 py-3 dark:border-zinc-700 dark:bg-zinc-800">
                    <div className="text-sm text-[#50575e] dark:text-zinc-400">
                        {selectedItems.length > 0 && (
                            <span>
                                {selectedItems.length} {selectedItems.length === 1 ? 'item' : 'items'} selected
                            </span>
                        )}
                    </div>
                    <div className="flex gap-2">
                        <Button variant="outline" onClick={() => setIsOpen(false)} className="border-[#8c8f94] dark:border-zinc-600">
                            Cancel
                        </Button>
                        <Button onClick={handleConfirm} disabled={selectedItems.length === 0} className="bg-[#2271b1] text-white hover:bg-[#135e96]">
                            {enableMultiSelect ? `Insert ${selectedItems.length > 0 ? `(${selectedItems.length})` : ''}` : 'Select'}
                        </Button>
                    </div>
                </div>
            </DialogContent>
        </Dialog>
    );
}
