import { useState, useEffect } from 'react';
import { apiClient } from '../../../shared/api/client';
import { JSMpegPlayer } from '../components/JSMpegPlayer';
import { Plus, Settings, Trash2, X, Video } from 'lucide-react';
import { useAuth } from '../../../shared/auth/AuthContext';
import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, type DragEndEvent } from '@dnd-kit/core';
import { arrayMove, SortableContext, sortableKeyboardCoordinates, useSortable, rectSortingStrategy } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';

interface Camera {
    id: number;
    name: string;
    ip_address: string;
    port: number;
    username?: string;
    password?: string;
    stream_path?: string;
    transport_mode?: 'tcp' | 'udp' | 'auto';
    rtsp_encoding?: boolean;
    quality?: 'low' | 'medium' | 'original';
    display_order?: number;
    is_active?: boolean | number;
}

// Wrap Camera Card with Sortable
function SortableCamera({ camera, children, disabled }: { camera: Camera, children: React.ReactNode, disabled: boolean }) {
    const {
        attributes,
        listeners,
        setNodeRef,
        transform,
        transition,
    } = useSortable({ id: camera.id, disabled });

    const style = {
        transform: CSS.Transform.toString(transform),
        transition,
    };

    return (
        <div ref={setNodeRef} style={style} {...attributes} {...listeners} className="bg-white rounded-xl shadow-lg overflow-hidden border border-slate-200">
            {children}
        </div>
    );
}

export function MonitoringPage() {
    const { user } = useAuth();
    const [cameras, setCameras] = useState<Camera[]>([]);
    const [showForm, setShowForm] = useState(false);
    const [editingCamera, setEditingCamera] = useState<Camera | null>(null);
    const [formData, setFormData] = useState<Partial<Camera>>({
        name: '',
        ip_address: '',
        port: 554,
        username: '',
        password: '',
        stream_path: '/stream1',
        transport_mode: 'tcp',
        rtsp_encoding: false,
        quality: 'low'
    });
    const [loading, setLoading] = useState(false);

    const [streamVersions, setStreamVersions] = useState<{ [key: number]: number }>({});

    const sensors = useSensors(
        useSensor(PointerSensor),
        useSensor(KeyboardSensor, {
            coordinateGetter: sortableKeyboardCoordinates,
        })
    );

    useEffect(() => {
        fetchCameras();
    }, []);

    const fetchCameras = async () => {
        try {
            const res = await apiClient.get('/cameras');
            setCameras(res.data);
        } catch (err) {
            console.error('Failed to fetch cameras', err);
        }
    };

    const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const { name, value } = e.target;
        setFormData(prev => ({ ...prev, [name]: value }));
    };

    const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        setLoading(true);
        try {
            if (editingCamera) {
                await apiClient.put(`/cameras/${editingCamera.id}`, formData);
                // Force stream refresh for this camera
                setStreamVersions(prev => ({ ...prev, [editingCamera.id]: Date.now() }));
            } else {
                await apiClient.post('/cameras', formData);
            }
            setShowForm(false);
            setEditingCamera(null);
            setFormData({
                name: '',
                ip_address: '',
                port: 554,
                username: '',
                password: '',
                stream_path: '/stream1',
                transport_mode: 'tcp',
                rtsp_encoding: false,
                quality: 'low'
            });
            fetchCameras();
        } catch (err) {
            console.error('Failed to save camera', err);
            const errMsg = (err as any).response?.data?.error || (err as any).message || '카메라 저장 실패';
            alert(`오류 발생: ${errMsg}`);
        } finally {
            setLoading(false);
        }
    };

    const handleEdit = (camera: Camera) => {
        setEditingCamera(camera);
        setFormData(camera);
        setShowForm(true);
    };

    const handleDelete = async (id: number) => {
        if (!window.confirm('정말 삭제하시겠습니까?')) return;
        try {
            await apiClient.delete(`/cameras/${id}`);
            fetchCameras();
        } catch (err) {
            console.error('Failed to delete camera', err);
        }
    };

    const handleToggleStatus = async (camera: Camera) => {
        // Optimistic UI Update: Calculate new status
        const currentStatus = camera.is_active !== 0 && camera.is_active !== false;
        const newStatus = !currentStatus;

        // Immediately update UI state
        setCameras(prev => prev.map(c =>
            c.id === camera.id ? { ...c, is_active: newStatus ? 1 : 0 } : c
        ));

        try {
            // Send request to server
            await apiClient.patch(`/cameras/${camera.id}/status`, { is_active: newStatus });
            // Only silent fetch to sync eventually, no alert needed
            fetchCameras();
        } catch (err) {
            console.error('Failed to toggle status', err);
            // Revert UI on failure
            setCameras(prev => prev.map(c =>
                c.id === camera.id ? { ...c, is_active: currentStatus ? 1 : 0 } : c
            ));
            alert('상태 변경 실패 (되돌리기)');
        }
    };

    const handleDragEnd = async (event: DragEndEvent) => {
        const { active, over } = event;

        if (over && active.id !== over.id) {
            setCameras((items) => {
                const oldIndex = items.findIndex((item) => item.id === active.id);
                const newIndex = items.findIndex((item) => item.id === over.id);
                const newItems = arrayMove(items, oldIndex, newIndex);

                // Save new order
                apiClient.put('/cameras/reorder', { cameras: newItems.map(c => c.id) })
                    .catch(e => console.error('Failed to save order', e));

                return newItems;
            });
        }
    };

    const getStreamUrl = (cameraId: number) => {
        // Use current host (proxied or direct)
        const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
        const version = streamVersions[cameraId] || 0;
        const url = `${protocol}//${window.location.host}/api/stream?cameraId=${cameraId}&v=${version}`;
        console.log(`[CCTV] Connecting to: ${url}`);
        return url;
    };

    const handlePing = async (id: number) => {
        try {
            const res = await apiClient.get(`/cameras/${id}/ping`);

            // Critical check: If the server returns HTML (catch-all), it's old code
            if (typeof res.data === 'string' && res.data.includes('<html')) {
                alert('❌ Server Sync Error!\nThe production server is still running old code (received HTML instead of JSON).\nPlease re-upload the "server" folder and restart PM2.');
                return;
            }

            if (res.data.success) {
                alert(`✅ Ping Success!\nServer can reach Camera (${res.data.ip}).`);
            } else {
                alert(`❌ Ping Failed!\nServer cannot reach Camera (${res.data.ip || 'Unknown IP'}).\nCheck NAS network/firewall.`);
            }
        } catch (err: any) {
            if (err.response?.status === 404) {
                alert('❌ API Not Found (404)!\nThe server does not have the "ping" feature. Please update and restart the backend.');
            } else {
                alert('Ping API Error. Please check server logs.');
            }
        }
    };

    const checkServerVersion = async () => {
        try {
            const res = await apiClient.get('/health');
            console.log('[System] Server Version:', res.data);
        } catch (e) {
            console.warn('[System] Could not fetch server health - might be old version.');
        }
    };

    useEffect(() => {
        fetchCameras();
        checkServerVersion();
    }, []);

    return (
        <div className="p-6">
            <div className="flex justify-between items-center mb-6">
                <h1 className="text-2xl font-bold flex items-center gap-2">
                    <Video className="text-blue-600" />
                    CCTV <span className="text-xs text-slate-400 font-normal">({user?.role})</span>
                </h1>
                {(user?.role === 'admin' || user?.role === 'supervisor') && (
                    <button
                        onClick={() => {
                            setEditingCamera(null);
                            setFormData({
                                name: '',
                                ip_address: '',
                                port: 554,
                                username: '',
                                password: '',
                                stream_path: '/stream1'
                            });
                            setShowForm(true);
                        }}
                        className="bg-blue-600 text-white px-4 py-2 rounded-lg flex items-center gap-2 hover:bg-blue-700 transition"
                    >
                        <Plus size={18} />
                        카메라 추가
                    </button>
                )}
            </div>

            {/* Camera Grid with DnD */}
            <DndContext
                sensors={sensors}
                collisionDetection={closestCenter}
                onDragEnd={handleDragEnd}
            >
                <SortableContext
                    items={cameras.map(c => c.id)}
                    strategy={rectSortingStrategy}
                >
                    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-6">
                        {cameras.map(camera => (
                            <SortableCamera key={camera.id} camera={camera} disabled={user?.role !== 'admin' && user?.role !== 'supervisor'}>
                                <div className="relative aspect-video bg-black group">
                                    <JSMpegPlayer
                                        key={`${camera.id}-${streamVersions[camera.id] || 0}`}
                                        url={getStreamUrl(camera.id)}
                                        className="w-full h-full"
                                    />
                                    {/* Overlay Controls */}
                                    {(user?.role === 'admin' || user?.role === 'supervisor') && (
                                        <div className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity flex gap-2" onPointerDown={(e) => e.stopPropagation()}>
                                            <button
                                                onClick={() => handleToggleStatus(camera)}
                                                className={`${(camera.is_active !== 0 && camera.is_active !== false) ? 'bg-orange-500/80 hover:bg-orange-600' : 'bg-green-600/80 hover:bg-green-700'} text-white p-2 rounded-full`}
                                                title={(camera.is_active !== 0 && camera.is_active !== false) ? "스트리밍 중지 (Pause)" : "스트리밍 시작 (Play)"}
                                            >
                                                {(camera.is_active !== 0 && camera.is_active !== false) ? (
                                                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>
                                                ) : (
                                                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
                                                )}
                                            </button>
                                            <button
                                                onClick={() => handlePing(camera.id)}
                                                className="bg-green-600/80 text-white p-2 rounded-full hover:bg-green-700"
                                                title="연결 테스트 (Ping)"
                                            >
                                                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m21 2-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0 3 3L22 7l-3-3L15.5 7.5z" /></svg>
                                            </button>
                                            <button
                                                onClick={() => handleEdit(camera)}
                                                className="bg-black/50 text-white p-2 rounded-full hover:bg-black/70"
                                                title="설정"
                                            >
                                                <Settings size={16} />
                                            </button>
                                            <button
                                                onClick={() => handleDelete(camera.id)}
                                                className="bg-red-500/80 text-white p-2 rounded-full hover:bg-red-600"
                                                title="삭제"
                                            >
                                                <Trash2 size={16} />
                                            </button>
                                        </div>
                                    )}
                                    <div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/80 to-transparent p-4">
                                        <h3 className="text-white font-medium flex items-center gap-2">
                                            <span className={`w-2 h-2 rounded-full ${(camera.is_active !== 0 && camera.is_active !== false) ? 'bg-green-500 animate-pulse' : 'bg-red-500'}`}></span>
                                            {camera.name} {(camera.is_active === 0 || camera.is_active === false) && <span className="text-xs text-slate-400">(중지됨)</span>}
                                        </h3>
                                        {/* IP/Port Hidden as requested */}
                                    </div>
                                </div>
                            </SortableCamera>
                        ))}
                    </div>
                </SortableContext>
            </DndContext>

            {cameras.length === 0 && (
                <div className="text-center py-20 text-slate-500">
                    <Video size={48} className="mx-auto mb-4 opacity-50" />
                    <p>등록된 카메라가 없습니다. 카메라를 추가해주세요.</p>
                </div>
            )}

            {/* Add/Edit Modal */}
            {showForm && (
                <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
                    <div className="bg-white rounded-xl shadow-2xl w-full max-w-lg p-6 animate-in fade-in zoom-in duration-200">
                        <div className="flex justify-between items-center mb-6">
                            <h2 className="text-xl font-bold">
                                {editingCamera ? '카메라 설정 수정' : '새 카메라 추가'}
                            </h2>
                            <button onClick={() => setShowForm(false)} className="text-slate-400 hover:text-slate-600">
                                <X size={24} />
                            </button>
                        </div>

                        <form onSubmit={handleSubmit} className="space-y-4">
                            <div>
                                <label className="block text-sm font-medium text-slate-700 mb-1">카메라 이름</label>
                                <input type="text" name="name" value={formData.name} onChange={handleInputChange} required className="w-full border border-slate-300 rounded-lg px-3 py-2 outline-none focus:ring-2 focus:ring-blue-500" placeholder="예: 정문 CCTV" />
                            </div>
                            <div className="grid grid-cols-2 gap-4">
                                <div><label className="block text-sm font-medium text-slate-700 mb-1">IP 주소</label><input type="text" name="ip_address" value={formData.ip_address} onChange={handleInputChange} required className="w-full border border-slate-300 rounded-lg px-3 py-2 outline-none focus:ring-2 focus:ring-blue-500" placeholder="192.168.1.100" /></div>
                                <div><label className="block text-sm font-medium text-slate-700 mb-1">포트</label><input type="number" name="port" value={formData.port} onChange={handleInputChange} className="w-full border border-slate-300 rounded-lg px-3 py-2 outline-none focus:ring-2 focus:ring-blue-500" placeholder="554" /></div>
                            </div>
                            <div className="grid grid-cols-2 gap-4">
                                <div><label className="block text-sm font-medium text-slate-700 mb-1">RTSP 사용자명</label><input type="text" name="username" value={formData.username} onChange={handleInputChange} className="w-full border border-slate-300 rounded-lg px-3 py-2 outline-none focus:ring-2 focus:ring-blue-500" placeholder="admin" /></div>
                                <div><label className="block text-sm font-medium text-slate-700 mb-1">RTSP 비밀번호</label><input type="password" name="password" value={formData.password} onChange={handleInputChange} className="w-full border border-slate-300 rounded-lg px-3 py-2 outline-none focus:ring-2 focus:ring-blue-500" /></div>
                            </div>
                            <div>
                                <label className="block text-sm font-medium text-slate-700 mb-1">스트림 경로</label>
                                <input type="text" name="stream_path" value={formData.stream_path} onChange={handleInputChange} className="w-full border border-slate-300 rounded-lg px-3 py-2 outline-none focus:ring-2 focus:ring-blue-500" placeholder="/stream1" />
                            </div>

                            {/* Advanced Settings */}
                            <div className="bg-slate-50 p-4 rounded-lg border border-slate-200">
                                <h3 className="text-sm font-bold text-slate-700 mb-3 flex items-center gap-2">
                                    <Settings size={14} /> 고급 설정
                                </h3>
                                <div className="grid grid-cols-2 gap-4">
                                    <div>
                                        <label className="block text-xs font-medium text-slate-600 mb-1">전송 방식 (Transport)</label>
                                        <select name="transport_mode" value={formData.transport_mode || 'tcp'} onChange={(e) => setFormData(prev => ({ ...prev, transport_mode: e.target.value as any }))} className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm outline-none">
                                            <option value="tcp">TCP (권장 - 안정적)</option>
                                            <option value="udp">UDP (빠름 - 끊김가능)</option>
                                            <option value="auto">Auto</option>
                                        </select>
                                    </div>
                                    <div className="flex items-center">
                                        <label className="flex items-center gap-2 cursor-pointer">
                                            <input type="checkbox" name="rtsp_encoding" checked={!!formData.rtsp_encoding} onChange={(e) => setFormData(prev => ({ ...prev, rtsp_encoding: e.target.checked }))} className="w-4 h-4 text-blue-600 rounded focus:ring-blue-500" />
                                            <span className="text-sm text-slate-600">특수문자 인코딩 사용</span>
                                        </label>
                                    </div>
                                    <div className="col-span-2">
                                        <label className="block text-xs font-medium text-slate-600 mb-1">스트림 화질 (Quality)</label>
                                        <select name="quality" value={formData.quality || 'low'} onChange={(e) => setFormData(prev => ({ ...prev, quality: e.target.value as any }))} className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm outline-none">
                                            <option value="low">Low (640px) - 빠르고 안정적 (권장)</option>
                                            <option value="medium">Medium (1280px) - HD 화질</option>
                                            <option value="original">Original - 원본 화질 (네트워크 부하 큼)</option>
                                        </select>
                                    </div>
                                </div>
                            </div>

                            <div className="flex justify-end gap-3 mt-6">
                                <button type="button" onClick={() => setShowForm(false)} className="px-4 py-2 text-slate-600 hover:bg-slate-100 rounded-lg transition">취소</button>
                                <button type="submit" disabled={loading} className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition disabled:opacity-50">{loading ? '저장 중...' : '저장하기'}</button>
                            </div>
                        </form>
                    </div>
                </div>
            )}
        </div>
    );
}
