const { useState, useEffect, useRef, useMemo } = React;

const UiIcon = ({ name, className = "w-6 h-6" }) => {
    const icons = {
        'camera': <svg className={className} fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"></path><path strokeLinecap="round" strokeLinejoin="round" d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>,
        'moon': <svg className={className} fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"></path></svg>,
        'sun': <svg className={className} fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path></svg>,
        'coffee': <svg className={className} fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M18 10h-1.26A8 8 0 109 20h9a1 1 0 001-1v-8a1 1 0 00-1-1z"></path></svg>,
        'clock': <svg className={className} fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>,
        'briefcase': <svg className={className} fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path></svg>,
        'users': <svg className={className} fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path></svg>,
        'bell': <svg className={className} fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"></path></svg>,
        'check-circle': <svg className={className} fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>,
        'log-out': <svg className={className} fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"></path></svg>,
        'settings': <svg className={className} fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path><path strokeLinecap="round" strokeLinejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>,
        'shield': <svg className={className} fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path></svg>,
        'x': <svg className={className} fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg>
    };
    return icons[name] || null;
};

window.UserDashboard = function({ profile, logs, reminders = [], vacations = [], settings, actions = [], onLogout, setView, allRoles = [], hasAdminAccess }) {
    const [status, setStatus] = useState('fuera');
    const [activeSubAction, setActiveSubAction] = useState(null);
    const [subActionStartTime, setSubActionStartTime] = useState(null);
    const [elapsedMinutes, setElapsedMinutes] = useState(0);

    const [showCam, setShowCam] = useState(false);
    const [purpose, setPurpose] = useState('');
    const [clientName, setClientName] = useState('');
    const [loadingMark, setLoadingMark] = useState(false);
    const [localLock, setLocalLock] = useState(false); 
    const [gpsPermissionGranted, setGpsPermissionGranted] = useState(false);
    
    const liveCoordsRef = useRef(null);

    const [showOffDayModal, setShowOffDayModal] = useState(false);
    const [pendingActionType, setPendingActionType] = useState('');
    const [tempJustification, setTempJustification] = useState('');
    const [activeJustification, setActiveJustification] = useState('');

    const [showClientModal, setShowClientModal] = useState(false);
    const [showNotifications, setShowNotifications] = useState(false);
    const [hasAutoOpenedNotices, setHasAutoOpenedNotices] = useState(false);

    const [showVacationModal, setShowVacationModal] = useState(false);
    const [vacReqType, setVacReqType] = useState('full');
    const [vacReqStart, setVacReqStart] = useState('');
    const [vacReqEnd, setVacReqEnd] = useState('');
    const [toastMsg, setToastMsg] = useState('');

    const videoRef = useRef(null);
    const canvasRef = useRef(null);
    const todayStr = window.getNICDate();
    
    const showToast = (msg) => { setToastMsg(msg); setTimeout(() => setToastMsg(''), 3000); };

    // Evaluación precisa de permisos de administración / supervisión
    const canAccessAdminPanel = useMemo(() => {
        if (hasAdminAccess !== undefined) return Boolean(hasAdminAccess);
        if (typeof window.checkHasAdminAccess === 'function') {
            return window.checkHasAdminAccess(profile);
        }
        const r = (profile?.role || profile?.role_name || '').toLowerCase().trim();
        const acc = (profile?.accessLevel || profile?.access_level || '').toLowerCase().trim();
        return r === 'admin' || r === 'propietario' || r === 'dueño' || acc === 'full' || acc === 'readonly' || acc === 'read_only' || Boolean(window.SHIFT_CONFIG?.isMaster);
    }, [hasAdminAccess, profile]);

    const isSupervisorOnly = useMemo(() => {
        const acc = (profile?.accessLevel || profile?.access_level || '').toLowerCase().trim();
        return acc === 'readonly' || acc === 'read_only';
    }, [profile]);

    const todayLogs = useMemo(() => {
        return (logs || []).filter(l => l.date === todayStr).sort((a,b) => b.timestamp - a.timestamp);
    }, [logs, todayStr]);

    const lunchLimitMinutes = Number(settings?.lunchLimitMinutes || settings?.lunch_limit_minutes || 60);
    const graceMinutes = Number(settings?.gracePeriodMinutes || settings?.grace_period_minutes || 5);

    const getActionLabel = (rawId) => {
        if (!rawId) return '';
        const cleanId = rawId.replace('_in', '').replace('_out', '').replace('vuelta_', '');
        const found = actions.find(a => a.id === cleanId || a.id === rawId);
        if (found) return found.label;
        if (cleanId === 'almuerzo') return 'Almuerzo';
        if (cleanId === 'break') return 'Break';
        if (cleanId === 'cirugia') return 'Cirugía';
        if (cleanId === 'reunion') return 'Reunión';
        return cleanId.toUpperCase();
    };

    const isTodayAnOffDay = useMemo(() => {
        return window.isUserOffDay(profile.scheduleDays, todayStr);
    }, [profile.scheduleDays, todayStr]);

    const isShiftCompleted = useMemo(() => {
        const hasSalida = todayLogs.some(l => l.type === 'salida');
        return Boolean(profile.manualLock) || ((hasSalida || localLock) && !profile.overrideCheckOut);
    }, [todayLogs, profile.overrideCheckOut, profile.manualLock, localLock]);

    useEffect(() => {
        if (todayLogs.length === 0) {
            setStatus('fuera');
            setActiveSubAction(null);
            setSubActionStartTime(null);
            return;
        }

        const newestLog = todayLogs[0];
        const lastType = newestLog.type;

        if (lastType === 'salida') {
            setStatus('salida');
            setActiveSubAction(null);
            setSubActionStartTime(null);
        } else if (lastType.endsWith('_in') && lastType !== 'entrada') {
            const baseAction = lastType.replace('_in', '');
            setStatus(lastType);
            setActiveSubAction(baseAction);
            setSubActionStartTime(newestLog.timestamp);
        } else {
            setStatus('activo');
            setActiveSubAction(null);
            setSubActionStartTime(null);
        }
    }, [todayLogs]);

    // RASTREO SATELITAL CONTINUO EN VIVO (GPS WATCH)
    useEffect(() => {
        if (!('geolocation' in navigator)) return;

        const geoOptions = {
            enableHighAccuracy: true,
            maximumAge: 0,
            timeout: 10000
        };

        const watchId = navigator.geolocation.watchPosition(
            (pos) => {
                const currentCoords = {
                    lat: pos.coords.latitude,
                    lng: pos.coords.longitude,
                    accuracy: pos.coords.accuracy,
                    timestamp: pos.timestamp
                };
                liveCoordsRef.current = currentCoords;
                setGpsPermissionGranted(true);

                if (Boolean(profile.gpsTrackingEnabled) && !isShiftCompleted && status !== 'fuera' && status !== 'salida') {
                    window.apiCall('ping_gps_tracker', {
                        userId: profile.id,
                        lat: currentCoords.lat,
                        lng: currentCoords.lng
                    });
                }
            },
            (err) => {
                console.warn("GPS Satelital en espera:", err.message);
            },
            geoOptions
        );

        return () => {
            if (watchId) navigator.geolocation.clearWatch(watchId);
        };
    }, [profile.gpsTrackingEnabled, isShiftCompleted, status]);

    const requestManualGpsPermission = () => {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(
                (pos) => {
                    setGpsPermissionGranted(true);
                    showToast("GPS Satelital Activado.");
                    if (Boolean(profile.gpsTrackingEnabled)) {
                        window.apiCall('ping_gps_tracker', {
                            userId: profile.id,
                            lat: pos.coords.latitude,
                            lng: pos.coords.longitude
                        });
                    }
                },
                (err) => {
                    showToast("Permiso de GPS denegado.");
                },
                { enableHighAccuracy: true, timeout: 5000 }
            );
        }
    };

    useEffect(() => {
        if (!subActionStartTime) {
            setElapsedMinutes(0);
            return;
        }
        const updateTimer = () => {
            const diffMs = Date.now() - subActionStartTime;
            setElapsedMinutes(Math.floor(diffMs / 60000));
        };
        updateTimer();
        const interval = setInterval(updateTimer, 15000);
        return () => clearInterval(interval);
    }, [subActionStartTime]);

    const activeVacationToday = useMemo(() => {
        return vacations.find(v => v.userId === profile.id && v.status === 'approved' && v.startDate <= todayStr && (v.endDate || v.startDate) >= todayStr && !(v.revokedDates||[]).includes(todayStr));
    }, [vacations, profile.id, todayStr]);

    const myNotifications = useMemo(() => {
        const now = Date.now();
        const activeAvisos = (reminders || []).filter(r => r.targetUsers?.includes(profile.id) && !(r.completedBy && r.completedBy[profile.id]) && (!r.expiresAt || r.expiresAt > now)).map(r => ({ ...r, notifType: 'aviso' }));
        const vacUpdates = (vacations || []).filter(v => v.userId === profile.id && (v.status === 'approved' || v.status === 'denied') && !v.seenByUser).map(v => ({
            id: v.id, title: `Vacaciones ${v.status === 'approved' ? 'Aprobadas' : 'Denegadas'}`,
            message: v.type === 'paid' ? `Se te ha pagado el equivalente a ${v.paidDays} día(s).` : `Tu solicitud del ${v.startDate} fue ${v.status === 'approved' ? 'aprobada' : 'denegada'}.`,
            notifType: 'vacation', status: v.status
        }));
        return [...activeAvisos, ...vacUpdates];
    }, [reminders, vacations, profile.id]);

    useEffect(() => {
        if (!hasAutoOpenedNotices && myNotifications.length > 0) {
            setShowNotifications(true);
            setHasAutoOpenedNotices(true);
        }
    }, [myNotifications, hasAutoOpenedNotices]);

    const markNotificationSeen = async (notif) => {
        try {
            await window.apiCall('mark_notification_seen', { id: notif.id, notifType: notif.notifType, userId: profile.id });
        } catch (e) { showToast("Error al confirmar."); }
    };

    const userRoleConfig = useMemo(() => {
        return allRoles.find(r => (r.name || '').toLowerCase() === (profile.role || '').toLowerCase());
    }, [allRoles, profile.role]);

    const permissions = useMemo(() => {
        if (userRoleConfig && userRoleConfig.permissions && userRoleConfig.permissions.length > 0) {
            return userRoleConfig.permissions;
        }
        return actions.map(a => a.id);
    }, [userRoleConfig, actions]);

    const evaluateEntryTardiness = () => {
        if (isTodayAnOffDay || !profile.scheduleStart) return null;
        
        const now = new Date();
        const currentMins = now.getHours() * 60 + now.getMinutes();
        const [schedH, schedM] = profile.scheduleStart.split(':').map(Number);
        const schedMins = schedH * 60 + schedM;

        const diffMins = currentMins - schedMins;
        if (diffMins > graceMinutes) {
            return `ALERTA: Llegada Tardía de ${diffMins} min (Horario oficial: ${profile.scheduleStart}, Tolerancia: ${graceMinutes} min)`;
        }
        return null;
    };

    const getFreshGPSLocation = async () => {
        return new Promise((resolve) => {
            if (!('geolocation' in navigator)) return resolve(null);
            if (liveCoordsRef.current) {
                return resolve({ lat: liveCoordsRef.current.lat, lng: liveCoordsRef.current.lng });
            }
            navigator.geolocation.getCurrentPosition(
                (pos) => resolve({ lat: pos.coords.latitude, lng: pos.coords.longitude }),
                () => resolve(null),
                { enableHighAccuracy: true, maximumAge: 0, timeout: 2500 }
            );
        });
    };

    const executeActionWithCheck = async (p, explicitJustification = '') => {
        const baseKey = p.replace('_in', '').replace('_out', '').replace('vuelta_', '');
        let requiresCam = false;
        
        if (userRoleConfig && userRoleConfig.cameraActions) {
            requiresCam = userRoleConfig.cameraActions.includes(baseKey) || userRoleConfig.cameraActions.includes(p);
        } else {
            requiresCam = p === 'entrada' || p === 'salida';
        }

        const justToSave = explicitJustification || activeJustification || null;

        if (requiresCam) {
            proceedWithCam(p);
        } else {
            setLoadingMark(true);
            const freshLoc = await getFreshGPSLocation();
            saveMark(p, null, freshLoc, justToSave);
        }
    };

    const startAction = async (p) => {
        if (isShiftCompleted || activeVacationToday) return;

        if (isTodayAnOffDay && todayLogs.length === 0 && !activeJustification) {
            setPendingActionType(p);
            const reasons = settings?.exceptionReasons || ['Horas extras autorizadas', 'Solicitud de gerencia', 'Cobertura de turno especial', 'Emergencia operativa'];
            setTempJustification(reasons[0] || 'Horas extras autorizadas');
            setShowOffDayModal(true);
            return;
        }

        if (p.includes('visita') && p.endsWith('_in') && !clientName) {
            setPurpose(p);
            setShowClientModal(true); 
            return;
        }
        executeActionWithCheck(p);
    };

    const handleConfirmOffDay = () => {
        const chosen = tempJustification || 'Horas extras autorizadas';
        setActiveJustification(chosen);
        setShowOffDayModal(false);
        const actionToExec = pendingActionType || 'entrada';
        setPendingActionType('');
        executeActionWithCheck(actionToExec, chosen);
    };

    const handleCancelOffDay = () => {
        setShowOffDayModal(false);
        setPendingActionType('');
        setTempJustification('');
        setActiveJustification('');
    };

    const proceedWithCam = async (p) => {
        setPurpose(p); 
        setShowClientModal(false);
        setShowCam(true);
        const useRear = p.includes('visita');
        const constraints = { video: { facingMode: useRear ? 'environment' : 'user', width: { ideal: 1280 }, height: { ideal: 720 } } };

        try {
            const s = await navigator.mediaDevices.getUserMedia(constraints);
            if (videoRef.current) {
                videoRef.current.srcObject = s;
                if (!useRear) videoRef.current.classList.add('mirror');
                else videoRef.current.classList.remove('mirror');
            }
        } catch (err) { showToast("Cámara requerida."); setShowCam(false); }
    };

    const capture = async () => {
        const canvas = canvasRef.current;
        const video = videoRef.current;
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        const ctx = canvas.getContext('2d');
        if (!purpose.includes('visita')) { ctx.translate(canvas.width, 0); ctx.scale(-1, 1); }
        ctx.drawImage(video, 0, 0);
        const photo = canvas.toDataURL('image/jpeg', 0.6);
        
        const freshLoc = await getFreshGPSLocation();
        saveMark(purpose, photo, freshLoc, activeJustification);
    };

    const saveMark = async (type, photo, loc, explicitJustification = null) => {
        setLoadingMark(true);

        let customJustification = explicitJustification || activeJustification || null;
        
        if (type === 'entrada' && !customJustification) {
            const tardyAlert = evaluateEntryTardiness();
            if (tardyAlert) customJustification = tardyAlert;
        }

        if (type === 'almuerzo_out' && subActionStartTime) {
            const durationMins = Math.floor((Date.now() - subActionStartTime) / 60000);
            if (durationMins > lunchLimitMinutes) {
                const overMins = durationMins - lunchLimitMinutes;
                customJustification = `ALERTA: Almuerzo excedido por ${overMins} min (Duró ${durationMins} min / Límite: ${lunchLimitMinutes} min)`;
            }
        }

        try {
            await window.apiCall('save_log', {
                userId: profile.id, 
                userName: profile.name, 
                type, 
                timestamp: Date.now(), 
                location: loc, 
                photo, 
                client: clientName || null, 
                date: todayStr, 
                role: profile.role,
                justification: customJustification,
                update_user_override: type === 'salida' ? true : false
            });

            if (type === 'salida') setLocalLock(true);

            if (videoRef.current?.srcObject) videoRef.current.srcObject.getTracks().forEach(t => t.stop());
            setShowCam(false); 
            setClientName('');
            setActiveJustification('');
            setTempJustification('');

            if (customJustification && customJustification.startsWith('ALERTA:')) {
                showToast(`⚠️ ${customJustification}`);
            } else {
                showToast("Marca registrada exitosamente.");
            }
        } catch (e) { 
            showToast("Error al guardar marca."); 
        } finally { 
            setLoadingMark(false); 
        }
    };

    const submitVacation = async () => {
        if (!vacReqStart || (vacReqType === 'range' && !vacReqEnd)) return showToast("Revisa las fechas.");
        const end = vacReqType === 'range' ? vacReqEnd : vacReqStart;
        if (vacReqType === 'range' && end < vacReqStart) return showToast("Fecha de fin inválida.");
        
        const daysReq = vacReqType === 'half' ? 0.5 : window.getDaysDiff(vacReqStart, end);
        const currentBal = window.calculateVacationBalance(profile, settings?.vacationRate||2.5, vacations);
        
        if (daysReq > currentBal) return showToast(`Saldo insuficiente. Pides ${daysReq} y tienes ${currentBal}`);
        
        try {
            await window.apiCall('add_vacation', {
                userId: profile.id, userName: profile.name, type: vacReqType,
                startDate: vacReqStart, endDate: end, status: 'pending',
                requestedAt: Date.now(), seenByUser: false
            });
            setShowVacationModal(false); setVacReqStart(''); setVacReqEnd(''); setVacReqType('full');
            showToast("Solicitud enviada a revisión.");
        } catch(e) { showToast("Error al solicitar."); }
    };

    const isInsideActivity = activeSubAction !== null;
    const isOverLunchTime = activeSubAction === 'almuerzo' && elapsedMinutes > lunchLimitMinutes;
    const activeLabelReadable = isInsideActivity ? getActionLabel(activeSubAction) : '';

    return (
        <div className="max-w-md mx-auto p-4 sm:p-6 space-y-5 pb-24 relative min-h-screen fade-in">
            {toastMsg && <div className="fixed top-4 left-1/2 -translate-x-1/2 bg-slate-900 text-white px-6 py-3 rounded-2xl font-black text-[10px] uppercase tracking-widest shadow-2xl z-[120] animate-bounce whitespace-nowrap">{toastMsg}</div>}

            {showOffDayModal && (
                <div className="fixed inset-0 bg-slate-900/80 z-[120] flex items-center justify-center p-6 fade-in" onClick={handleCancelOffDay}>
                    <div className="bg-white p-8 rounded-[3rem] w-full max-w-sm shadow-2xl space-y-5 border-t-[10px] border-orange-500" onClick={e=>e.stopPropagation()}>
                        <div className="text-center">
                            <div className="w-12 h-12 bg-orange-100 text-orange-600 rounded-2xl flex items-center justify-center mx-auto mb-3">
                                <UiIcon name="moon" className="w-6 h-6" />
                            </div>
                            <h3 className="font-black text-xl text-slate-900">Hoy es tu Día Libre</h3>
                            <p className="text-slate-500 text-xs font-bold mt-1">Debes indicar la autorización para registrar esta jornada extraordinaria:</p>
                        </div>
                        
                        <div>
                            <label className="text-[10px] font-black uppercase text-slate-400 ml-2 mb-1 block">Motivo de Excepción</label>
                            <select value={tempJustification} onChange={e=>setTempJustification(e.target.value)} className="w-full p-4 bg-slate-50 rounded-2xl font-bold text-xs outline-none border focus:ring-2 focus:ring-orange-200">
                                {(settings?.exceptionReasons || ['Horas extras autorizadas', 'Solicitud de gerencia', 'Cobertura de turno especial', 'Emergencia operativa']).map((r, i) => (
                                    <option key={i} value={r}>{r}</option>
                                ))}
                            </select>
                        </div>

                        <div className="flex gap-2 pt-2">
                            <button onClick={handleCancelOffDay} className="flex-1 py-4 bg-slate-100 text-slate-500 rounded-2xl font-black uppercase text-[10px]">
                                Cancelar
                            </button>
                            <button onClick={handleConfirmOffDay} className="flex-1 py-4 bg-orange-600 text-white font-black rounded-2xl uppercase tracking-widest text-[10px] shadow-lg active:scale-95 transition-all">
                                Confirmar y Marcar
                            </button>
                        </div>
                    </div>
                </div>
            )}

            {showNotifications && (
                <div className="fixed inset-0 bg-slate-900/60 z-[110] p-6 flex items-center justify-center fade-in" onClick={()=>setShowNotifications(false)}>
                    <div className="bg-white w-full max-w-sm rounded-[3rem] p-6 overflow-y-auto max-h-[80vh] space-y-4 shadow-2xl border-t-[10px] border-indigo-600" onClick={e=>e.stopPropagation()}>
                        <div className="flex justify-between items-center border-b pb-3">
                            <h3 className="font-black text-lg text-slate-900 flex items-center gap-2">
                                <UiIcon name="bell" className="text-indigo-600" /> Avisos y Alertas
                            </h3>
                            <button onClick={()=>setShowNotifications(false)} className="text-slate-400 p-1 hover:text-slate-600">
                                <UiIcon name="x" className="w-5 h-5" />
                            </button>
                        </div>

                        {myNotifications.length === 0 ? (
                            <p className="text-slate-400 text-xs font-bold text-center py-6">No tienes avisos pendientes.</p>
                        ) : (
                            myNotifications.map(n => (
                                <div key={n.id} className="p-5 rounded-2xl bg-indigo-50 border border-indigo-100 space-y-2">
                                    <h4 className="font-black text-indigo-950 uppercase text-xs">{n.title}</h4>
                                    <p className="text-slate-600 text-[11px] font-medium leading-relaxed">{n.message}</p>
                                    <button onClick={() => markNotificationSeen(n)} className="w-full py-2.5 bg-indigo-600 text-white rounded-xl font-black uppercase text-[9px] flex items-center justify-center gap-1.5 active:scale-95 transition-all shadow-sm">
                                        <UiIcon name="check-circle" className="w-3.5 h-3.5" /> Entendido / Leído
                                    </button>
                                </div>
                            ))
                        )}
                        <button onClick={()=>setShowNotifications(false)} className="w-full py-3.5 bg-slate-100 text-slate-600 font-black rounded-2xl uppercase text-[10px]">
                            Cerrar
                        </button>
                    </div>
                </div>
            )}

            {showVacationModal && (
                <div className="fixed inset-0 bg-slate-900/60 z-50 p-6 flex items-center justify-center fade-in" onClick={()=>setShowVacationModal(false)}>
                    <div className="bg-white w-full max-w-sm rounded-[3rem] p-8 space-y-6 shadow-2xl" onClick={e=>e.stopPropagation()}>
                        <div className="flex justify-between items-center">
                            <h3 className="font-black text-xl text-indigo-900 flex items-center gap-2"><UiIcon name="sun" /> Mis Vacaciones</h3>
                            <button onClick={()=>setShowVacationModal(false)} className="text-slate-400 bg-slate-100 p-2 rounded-full"><UiIcon name="x" className="w-4 h-4" /></button>
                        </div>
                        <div className="bg-indigo-50 border border-indigo-100 p-6 rounded-3xl text-center shadow-inner">
                            <p className="text-[10px] font-black uppercase tracking-widest text-indigo-400">Saldo Disponible</p>
                            <p className="text-4xl font-black text-indigo-600 mt-2">{window.calculateVacationBalance(profile, settings?.vacationRate||2.5, vacations)} <span className="text-lg">Días</span></p>
                        </div>
                        <div className="space-y-4">
                            <select value={vacReqType} onChange={e=>setVacReqType(e.target.value)} className="w-full p-4 bg-slate-50 rounded-2xl font-bold text-[10px] uppercase outline-none focus:ring-2 focus:ring-indigo-100">
                                <option value="full">Día Completo Libre (1)</option>
                                <option value="half">Medio Día Libre (0.5)</option>
                                <option value="range">Rango de Fechas</option>
                            </select>
                            <div className="grid grid-cols-2 gap-4">
                                <div className="col-span-2 md:col-span-1">
                                    <label className="text-[9px] font-black uppercase tracking-widest text-slate-400 ml-2">Desde / Día</label>
                                    <input type="date" value={vacReqStart} onChange={e=>setVacReqStart(e.target.value)} className="w-full p-4 bg-slate-50 rounded-2xl font-bold outline-none" min={todayStr} />
                                </div>
                                {vacReqType === 'range' && (
                                    <div className="col-span-2 md:col-span-1">
                                        <label className="text-[9px] font-black uppercase tracking-widest text-slate-400 ml-2">Hasta</label>
                                        <input type="date" value={vacReqEnd} onChange={e=>setVacReqEnd(e.target.value)} className="w-full p-4 bg-slate-50 rounded-2xl font-bold outline-none" min={vacReqStart || todayStr} />
                                    </div>
                                )}
                            </div>
                            <button onClick={submitVacation} className="w-full py-4 bg-indigo-600 text-white font-black rounded-2xl uppercase text-[10px] tracking-widest mt-2 active:scale-95 transition-all shadow-lg">Enviar a Revisión</button>
                        </div>
                    </div>
                </div>
            )}

            {/* HEADER CON FOTO DE PERFIL, ACCESO A SUPERVISIÓN Y BOTONES */}
            <header className="bg-white p-5 rounded-[2.5rem] shadow-sm border border-slate-100 flex items-center justify-between">
                <div className="flex items-center gap-3">
                    {profile.avatarUrl ? (
                        <img src={profile.avatarUrl} alt="Avatar" className="w-12 h-12 rounded-2xl object-cover border-2 border-indigo-100 shadow-md" />
                    ) : (
                        <div className="w-12 h-12 bg-indigo-600 rounded-2xl flex items-center justify-center text-white font-black text-xl shadow-lg">
                            {profile.name ? profile.name[0].toUpperCase() : 'U'}
                        </div>
                    )}
                    <div>
                        <h2 className="font-black text-slate-800 leading-none mb-1 text-sm sm:text-base">{profile.name}</h2>
                        <div className="flex items-center gap-1.5">
                            <span className="text-[9px] text-slate-400 font-black uppercase tracking-widest">{profile.role}</span>
                            {Boolean(profile.gpsTrackingEnabled) ? (
                                <span className="w-2 h-2 rounded-full bg-emerald-500 animate-ping" title="Rastreo en vivo activo"></span>
                            ) : null}
                        </div>
                    </div>
                </div>
                <div className="flex items-center gap-2">
                    {canAccessAdminPanel && (
                        <button 
                            onClick={() => setView('admin')} 
                            className="p-3 bg-indigo-50 hover:bg-indigo-100 text-indigo-700 border border-indigo-200 rounded-2xl active:scale-95 transition-all"
                            title={isSupervisorOnly ? "Ir a Panel de Supervisión" : "Ir a Panel de Administración"}
                        >
                            <UiIcon name={isSupervisorOnly ? "shield" : "settings"} className="w-5 h-5" />
                        </button>
                    )}
                    <button onClick={()=>setShowNotifications(true)} className="p-3 bg-slate-50 text-slate-400 rounded-2xl relative">
                        <UiIcon name="bell" />
                        {myNotifications.length > 0 ? <span className="absolute top-2 right-2 w-3 h-3 bg-red-500 rounded-full border-2 border-white animate-pulse"></span> : null}
                    </button>
                    <button onClick={onLogout} className="p-3 text-slate-300 hover:text-red-500 rounded-2xl"><UiIcon name="log-out" /></button>
                </div>
            </header>

            {/* BOTÓN INFORMATIVO DE ACTIVACIÓN TÁCTIL EN IPHONE */}
            {Boolean(profile.gpsTrackingEnabled) && !gpsPermissionGranted ? (
                <button onClick={requestManualGpsPermission} className="w-full p-3 bg-indigo-50 border border-indigo-200 text-indigo-700 rounded-2xl text-[10px] font-black uppercase flex items-center justify-center gap-2 active:scale-95 transition-all shadow-sm">
                    <UiIcon name="camera" className="w-4 h-4" /> Toca aquí para autorizar GPS de campo en iPhone
                </button>
            ) : null}

            {/* ACCIONES RÁPIDAS (VACACIONES Y ACCESO AL PANEL DE ADMINISTRACIÓN/SUPERVISIÓN) */}
            <div className="flex gap-2.5">
                <button 
                    onClick={() => setShowVacationModal(true)} 
                    className="flex-1 py-3.5 bg-emerald-50 hover:bg-emerald-100 text-emerald-700 rounded-2xl font-black uppercase text-[10px] tracking-widest flex items-center justify-center gap-1.5 border border-emerald-200 active:scale-95 transition-all shadow-sm"
                >
                    <UiIcon name="sun" className="w-4 h-4 text-emerald-600" /> Mis Vacaciones
                </button>
                {canAccessAdminPanel ? (
                    <button 
                        onClick={() => setView('admin')} 
                        className="flex-1 py-3.5 bg-gradient-to-r from-indigo-50 to-indigo-100/80 hover:from-indigo-100 hover:to-indigo-200 text-indigo-700 rounded-2xl font-black uppercase text-[10px] tracking-widest flex items-center justify-center gap-1.5 border border-indigo-200 active:scale-95 transition-all shadow-sm"
                    >
                        <UiIcon name={isSupervisorOnly ? "shield" : "settings"} className="w-4 h-4" />
                        {isSupervisorOnly ? 'Supervisión' : 'Panel Admin'}
                    </button>
                ) : null}
            </div>

            <div className="grid gap-4">
                {isShiftCompleted ? (
                    <div className="bg-slate-100 border-2 border-dashed border-slate-300 rounded-[3rem] p-8 text-center space-y-3">
                        <UiIcon name="moon" className="w-12 h-12 text-slate-400 mx-auto" />
                        <h3 className="text-lg font-black uppercase text-slate-700">Jornada Finalizada</h3>
                        <p className="text-[10px] font-bold text-slate-500 uppercase tracking-widest">
                            Has registrado tu salida del día.
                        </p>
                        <div className="p-3 bg-white rounded-2xl border border-slate-200 text-[10px] text-slate-600 font-medium">
                            ¿Reingreso extraordinario? Solicita el desbloqueo a tu Administrador.
                        </div>
                    </div>
                ) : (status === 'fuera') ? (
                    isTodayAnOffDay ? (
                        <div className="bg-orange-50 border-2 border-orange-200 rounded-[3rem] p-6 text-center space-y-4 shadow-sm">
                            <div className="w-14 h-14 bg-orange-500 text-white rounded-2xl flex items-center justify-center mx-auto shadow-md">
                                <UiIcon name="moon" className="w-8 h-8" />
                            </div>
                            <div>
                                <h3 className="font-black text-lg text-orange-950 uppercase tracking-tight">Hoy es tu Día de Descanso</h3>
                                <p className="text-[10px] font-bold text-orange-700 uppercase tracking-wider mt-1">
                                    No tienes turno programado para hoy ({window.getDayOfWeekCode(todayStr).toUpperCase()})
                                </p>
                            </div>
                            <button 
                                onClick={() => startAction('entrada')} 
                                className="w-full py-5 bg-orange-600 hover:bg-orange-700 text-white rounded-2xl font-black uppercase text-[10px] tracking-widest shadow-lg active:scale-95 transition-all flex items-center justify-center gap-2"
                            >
                                <UiIcon name="camera" className="w-4 h-4" /> Justificar y Marcar Entrada
                            </button>
                        </div>
                    ) : (
                        <button onClick={() => startAction('entrada')} className="h-64 sm:h-72 bg-emerald-500 rounded-[3rem] text-white flex flex-col items-center justify-center shadow-2xl active:scale-95 transition-all group relative overflow-hidden">
                            <div className="absolute inset-0 bg-emerald-400/20 group-hover:scale-150 rounded-full transition-transform duration-500"></div>
                            <UiIcon name="camera" className="w-12 h-12 mb-3 z-10" />
                            <span className="text-xl font-black uppercase z-10">Entrada Trabajo</span>
                        </button>
                    )
                ) : (
                    <div className="space-y-4">
                        <div className={`p-6 sm:p-8 rounded-[3rem] border-2 text-center shadow-sm relative transition-all ${isInsideActivity ? (isOverLunchTime ? 'bg-red-50 border-red-400' : 'bg-orange-50 border-orange-300') : 'bg-white border-emerald-500/20'}`}>
                            {isInsideActivity ? (
                                <div>
                                    <div className={`flex items-center justify-center gap-2 font-black text-base sm:text-lg tracking-widest uppercase ${isOverLunchTime ? 'text-red-600 animate-pulse' : 'text-orange-600'}`}>
                                        <span className="w-3 h-3 rounded-full bg-orange-500 animate-ping"></span>
                                        {activeLabelReadable.toUpperCase()} EN CURSO
                                    </div>
                                    <p className="text-3xl font-black text-slate-900 mt-2">
                                        {elapsedMinutes} <span className="text-sm font-bold text-slate-400">min transcurridos</span>
                                    </p>
                                    {activeSubAction === 'almuerzo' ? (
                                        <p className={`text-[10px] font-black uppercase tracking-widest mt-2 px-3 py-1 rounded-full inline-block ${isOverLunchTime ? 'bg-red-600 text-white' : 'bg-orange-200 text-orange-800'}`}>
                                            {isOverLunchTime ? `⚠️ LÍMITE EXCEDIDO (+${elapsedMinutes - lunchLimitMinutes} MIN)` : `Límite permitido: ${lunchLimitMinutes} min`}
                                        </p>
                                    ) : null}
                                </div>
                            ) : (
                                <div>
                                    <div className="flex items-center justify-center gap-2 text-emerald-600 mb-1 font-black text-xl tracking-widest">
                                        <span className="w-2.5 h-2.5 rounded-full bg-emerald-500"></span> ACTIVO
                                    </div>
                                    <p className="text-slate-400 text-[10px] font-bold uppercase tracking-widest">{window.formatNICTimeFull ? window.formatNICTimeFull(Date.now()).split(',')[0] : new Date().toLocaleDateString()}</p>
                                </div>
                            )}
                        </div>

                        <div className="grid grid-cols-2 gap-3 sm:gap-4">
                            {actions.map(a => {
                                if (!permissions.includes(a.id)) return null;

                                const isThisActionActive = activeSubAction === a.id;
                                const isBlockedByOtherAction = isInsideActivity && !isThisActionActive;

                                const actionTarget = isThisActionActive ? `${a.id}_out` : `${a.id}_in`;
                                const displayLabel = isThisActionActive ? `Regresar de ${a.label}` : a.label;

                                const iconMap = { 'almuerzo': 'coffee', 'break': 'clock', 'visita_in': 'briefcase', 'reunion': 'users' };
                                const iconName = iconMap[a.id] || 'check-circle';

                                return (
                                    <button 
                                        key={a.id} 
                                        onClick={() => !isBlockedByOtherAction && startAction(actionTarget)} 
                                        disabled={isBlockedByOtherAction}
                                        className={`h-28 sm:h-32 rounded-3xl shadow-sm flex flex-col items-center justify-center font-black uppercase text-[10px] tracking-wider transition-all p-3 text-center ${
                                            isThisActionActive 
                                                ? (isOverLunchTime ? 'bg-red-600 text-white shadow-xl ring-4 ring-red-200 animate-pulse' : 'bg-orange-500 text-white shadow-xl ring-4 ring-orange-200')
                                                : isBlockedByOtherAction 
                                                    ? 'bg-slate-100 text-slate-300 border border-slate-200 cursor-not-allowed opacity-40' 
                                                    : 'bg-white text-slate-700 border hover:border-indigo-200 active:scale-95'
                                        }`}
                                    >
                                        <UiIcon name={iconName} className="w-7 h-7 sm:w-8 sm:h-8 mb-2" /> 
                                        <span>{displayLabel}</span>
                                    </button>
                                );
                            })}
                        </div>

                        <button 
                            onClick={() => !isInsideActivity && startAction('salida')} 
                            disabled={isInsideActivity}
                            className={`w-full py-5 sm:py-6 rounded-[2.5rem] font-black uppercase text-xs tracking-widest transition-all ${
                                isInsideActivity 
                                    ? 'bg-slate-100 text-slate-300 cursor-not-allowed opacity-50' 
                                    : 'bg-red-50 text-red-600 hover:bg-red-100 active:scale-95 shadow-sm'
                            }`}
                        >
                            {isInsideActivity ? `Finaliza ${activeLabelReadable.toUpperCase()} antes de Cerrar Día` : 'Cerrar Día'}
                        </button>
                    </div>
                )}
            </div>

            {/* BITÁCORA DESCENDENTE */}
            <div className="bg-white p-5 sm:p-6 rounded-[2.5rem] border border-slate-100 shadow-sm">
                <h3 className="font-black text-[10px] uppercase tracking-widest text-slate-400 mb-4 flex items-center gap-2 border-b pb-3"><UiIcon name="file-text" className="w-4 h-4"/> Bitácora de Hoy (Recientes Primero)</h3>
                {todayLogs.length === 0 ? <p className="text-center py-6 text-[10px] font-black uppercase opacity-20">Sin registros aún</p> : (
                    <div className="space-y-3.5 max-h-[260px] overflow-y-auto pr-2 no-scrollbar">
                        {todayLogs.map(l => {
                            const rawActionId = l.type.replace('_in', '').replace('_out', '').replace('vuelta_', '');
                            const labelStr = getActionLabel(rawActionId);
                            
                            let displayType = l.type.replace('_', ' ');
                            if (l.type.endsWith('_in') && l.type !== 'entrada') displayType = `Inició ${labelStr}`;
                            else if (l.type.endsWith('_out') || l.type.startsWith('vuelta_')) displayType = `Regresó de ${labelStr}`;
                            else if (l.type === 'entrada') displayType = 'Entrada Trabajo';
                            else if (l.type === 'salida') displayType = 'Cierre de Día (Salida)';

                            const isAlert = l.justification && l.justification.startsWith('ALERTA:');

                            return (
                                <div key={l.id || l.timestamp} className="flex items-start gap-3.5">
                                    <div className={`w-3 h-3 rounded-full mt-1 flex-shrink-0 ${l.type.includes('entrada') ? 'bg-emerald-500' : l.type.includes('salida') ? 'bg-red-500' : isAlert ? 'bg-red-500 animate-ping' : 'bg-indigo-400'}`}></div>
                                    <div className="flex-1">
                                        <p className="text-[11px] font-black uppercase text-slate-800 leading-none">
                                            {displayType} {l.client ? <span className="text-indigo-600">- {l.client}</span> : null}
                                        </p>
                                        <p className="text-[9px] text-slate-400 font-bold mt-1 uppercase">
                                            {window.formatNICTimeFull ? window.formatNICTimeFull(l.timestamp).split(', ')[1] : new Date(l.timestamp).toLocaleTimeString()}
                                        </p>
                                        {l.justification ? (
                                            <p className={`text-[9px] font-bold mt-1 px-2 py-0.5 rounded-md inline-block ${isAlert ? 'bg-red-100 text-red-700' : 'bg-slate-100 text-slate-600'}`}>
                                                {l.justification}
                                            </p>
                                        ) : null}
                                    </div>
                                </div>
                            );
                        })}
                    </div>
                )}
            </div>

            {showCam && (
                <div className="fixed inset-0 bg-slate-950/95 z-[80] flex flex-col items-center justify-center p-6 text-white fade-in">
                    <div className="camera-container w-full max-w-sm shadow-2xl rounded-[3rem] overflow-hidden border-4 border-slate-800 relative bg-black aspect-[3/4]">
                        <video ref={videoRef} autoPlay playsInline muted className="w-full h-full object-cover" />
                        <canvas ref={canvasRef} className="hidden" />
                    </div>
                    <div className="mt-10 flex flex-col items-center gap-4 w-full max-w-sm">
                        <button onClick={capture} disabled={loadingMark} className="w-20 h-20 bg-white text-slate-950 rounded-full flex items-center justify-center shadow-2xl active:scale-90 transition-all focus:outline-none relative">
                            <span className={`absolute inset-0 flex items-center justify-center transition-opacity ${loadingMark ? 'opacity-100' : 'opacity-0'}`}>
                                <div className="w-7 h-7 border-4 border-indigo-600 border-t-transparent rounded-full animate-spin"></div>
                            </span>
                            <span className={`absolute inset-0 flex items-center justify-center transition-opacity ${!loadingMark ? 'opacity-100' : 'opacity-0'}`}>
                                <UiIcon name="camera" className="w-8 h-8" />
                            </span>
                        </button>
                        <button onClick={() => { if(videoRef.current?.srcObject) videoRef.current.srcObject.getTracks().forEach(t=>t.stop()); setShowCam(false); }} className="text-white/40 font-black uppercase text-[10px] tracking-widest underline p-2">Cancelar Marca</button>
                    </div>
                </div>
            )}
        </div>
    );
};