import { useCallback, useRef, useEffect, useState } from 'react';
import {
  Avatar,
  Box,
  Drawer,
  Typography,
  IconButton,
  Alert,
  AlertTitle,
  useMediaQuery,
  useTheme,
  CircularProgress,
} from '@mui/material';
import MenuIcon from '@mui/icons-material/Menu';
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
import DarkModeOutlinedIcon from '@mui/icons-material/DarkModeOutlined';
import LightModeOutlinedIcon from '@mui/icons-material/LightModeOutlined';
import { logger } from '@/utils/logger';

import { useSessionStore } from '@/store/sessionStore';
import { useAgentStore } from '@/store/agentStore';
import { useLayoutStore } from '@/store/layoutStore';
import { useAgentWebSocket } from '@/hooks/useAgentWebSocket';
import SessionSidebar from '@/components/SessionSidebar/SessionSidebar';
import CodePanel from '@/components/CodePanel/CodePanel';
import ChatInput from '@/components/Chat/ChatInput';
import MessageList from '@/components/Chat/MessageList';
import WelcomeScreen from '@/components/WelcomeScreen/WelcomeScreen';
import { apiFetch } from '@/utils/api';
import type { Message } from '@/types/agent';
import { triggerLogin } from '@/hooks/useAuth';

const DRAWER_WIDTH = 260;

export default function AppLayout() {
  const { sessions, activeSessionId, createSession, deleteSession, updateSessionTitle } = useSessionStore();
  const { isConnected, isProcessing, getMessages, addMessage, setProcessing, llmHealthError, setLlmHealthError, user, setPlan, setPanelContent } = useAgentStore();
  const { 
    isLeftSidebarOpen, 
    isRightPanelOpen, 
    rightPanelWidth,
    themeMode,
    setRightPanelWidth,
    setLeftSidebarOpen,
    toggleLeftSidebar, 
    toggleTheme,
  } = useLayoutStore();

  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('md'));

  const isResizing = useRef(false);
  const [isAutoCreating, setIsAutoCreating] = useState(false);
  const [autoCreateError, setAutoCreateError] = useState<string | null>(null);

  const handleMouseMove = useCallback((e: MouseEvent) => {
    if (!isResizing.current) return;
    const newWidth = window.innerWidth - e.clientX;
    const maxWidth = window.innerWidth * 0.6;
    const minWidth = 300;
    if (newWidth > minWidth && newWidth < maxWidth) {
      setRightPanelWidth(newWidth);
    }
  }, [setRightPanelWidth]);

  const stopResizing = useCallback(() => {
    isResizing.current = false;
    document.removeEventListener('mousemove', handleMouseMove);
    document.removeEventListener('mouseup', stopResizing);
    document.body.style.cursor = 'default';
  }, [handleMouseMove]);

  const startResizing = useCallback((e: React.MouseEvent) => {
    e.preventDefault();
    isResizing.current = true;
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', stopResizing);
    document.body.style.cursor = 'col-resize';
  }, [handleMouseMove, stopResizing]);

  useEffect(() => {
    return () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', stopResizing);
    };
  }, [handleMouseMove, stopResizing]);

  // ── Auto-create session if none exist ───────────────────────────
  useEffect(() => {
    const hasAnySessions = sessions.length > 0;
    const isAuthenticated = user?.authenticated;
    const isDevUser = user?.username === 'dev';

    if (!hasAnySessions && (isAuthenticated || isDevUser) && !isAutoCreating) {
      (async () => {
        setIsAutoCreating(true);
        setAutoCreateError(null);
        try {
          const response = await apiFetch('/api/session', { method: 'POST' });
          if (response.status === 503) {
            const data = await response.json();
            setAutoCreateError(data.detail || 'Server is at capacity. Please try again later.');
            return;
          }
          if (response.status === 401) {
            triggerLogin();
            return;
          }
          if (!response.ok) {
            setAutoCreateError('Failed to create session. Please try again.');
            return;
          }
          const data = await response.json();
          createSession(data.session_id);
          setPlan([]);
          setPanelContent(null);
        } catch (e) {
          logger.error('Auto-create session failed:', e);
          setAutoCreateError('Failed to auto-create session.');
        } finally {
          setIsAutoCreating(false);
        }
      })();
    }
  }, [sessions.length, user, createSession, setPlan, setPanelContent, isAutoCreating]);

  // ── LLM health check on mount ───────────────────────────────────
  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const res = await apiFetch('/api/health/llm');
        const data = await res.json();
        if (!cancelled && data.status === 'error') {
          setLlmHealthError({
            error: data.error || 'Unknown LLM error',
            errorType: data.error_type || 'unknown',
            model: data.model,
          });
        } else if (!cancelled) {
          setLlmHealthError(null);
        }
      } catch {
        // Backend unreachable — not an LLM issue, ignore
      }
    })();
    return () => { cancelled = true; };
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  const messages = activeSessionId ? getMessages(activeSessionId) : [];
  const hasAnySessions = sessions.length > 0;

  useAgentWebSocket({
    sessionId: activeSessionId,
    onReady: () => logger.log('Agent ready'),
    onError: (error) => logger.error('Agent error:', error),
    onSessionDead: (deadSessionId) => {
      logger.log('Removing dead session:', deadSessionId);
      deleteSession(deadSessionId);
    },
  });

  const handleSendMessage = useCallback(
    async (text: string) => {
      if (!activeSessionId || !text.trim() || isProcessing) return;
      
      // Lock input immediately to prevent double-sends
      setProcessing(true);

      const userMsg: Message = {
        id: `user_${Date.now()}`,
        role: 'user',
        content: text.trim(),
        timestamp: new Date().toISOString(),
      };
      addMessage(activeSessionId, userMsg);

      // Auto-title the session from the first user message (async, non-blocking)
      const currentMessages = getMessages(activeSessionId);
      const isFirstMessage = currentMessages.filter((m) => m.role === 'user').length <= 1;
      if (isFirstMessage) {
        const sessionId = activeSessionId;
        apiFetch('/api/title', {
          method: 'POST',
          body: JSON.stringify({ session_id: sessionId, text: text.trim() }),
        })
          .then((res) => res.json())
          .then((data) => {
            if (data.title) updateSessionTitle(sessionId, data.title);
          })
          .catch(() => {
            const raw = text.trim();
            updateSessionTitle(sessionId, raw.length > 40 ? raw.slice(0, 40) + '…' : raw);
          });
      }

      try {
        await apiFetch('/api/submit', {
          method: 'POST',
          body: JSON.stringify({
            session_id: activeSessionId,
            text: text.trim(),
          }),
        });
      } catch (e) {
        logger.error('Send failed:', e);
      }
    },
    [activeSessionId, addMessage, getMessages, updateSessionTitle, isProcessing, setProcessing]
  );

  // Close sidebar on mobile after selecting a session
  const handleSidebarClose = useCallback(() => {
    if (isMobile) setLeftSidebarOpen(false);
  }, [isMobile, setLeftSidebarOpen]);

  // ── LLM error banner (shared) ─────────────────────────────────────
  const llmBanner = llmHealthError && (
    <Alert
      severity="error"
      variant="filled"
      onClose={() => setLlmHealthError(null)}
      sx={{ borderRadius: 0, flexShrink: 0, '& .MuiAlert-message': { flex: 1 } }}
    >
      <AlertTitle sx={{ fontWeight: 700, fontSize: '0.85rem' }}>
        {llmHealthError.errorType === 'credits'
          ? 'API Credits Exhausted'
          : llmHealthError.errorType === 'auth'
          ? 'Invalid API Key'
          : llmHealthError.errorType === 'rate_limit'
          ? 'Rate Limited'
          : llmHealthError.errorType === 'network'
          ? 'LLM Provider Unreachable'
          : 'LLM Error'}
      </AlertTitle>
      <Typography variant="body2" sx={{ fontSize: '0.8rem', opacity: 0.9 }}>
        Model: <strong>{llmHealthError.model}</strong> — {llmHealthError.error.slice(0, 200)}
      </Typography>
    </Alert>
  );

  // ── Welcome screen: no sessions at all ────────────────────────────
  if (!hasAnySessions) {
    return (
      <Box sx={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column' }}>
        {llmBanner}
        {isAutoCreating ? (
          <Box sx={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--body-gradient)' }}>
            <CircularProgress color="primary" />
          </Box>
        ) : autoCreateError ? (
          <Box sx={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--body-gradient)', p: 3 }}>
            <Alert severity="error" variant="outlined" sx={{ maxWidth: 400 }}>
              <AlertTitle>Auto-initialization Failed</AlertTitle>
              {autoCreateError}
              <Box sx={{ mt: 2 }}>
                <WelcomeScreen />
              </Box>
            </Alert>
          </Box>
        ) : (
          <WelcomeScreen />
        )}
      </Box>
    );
  }

  // ── Sidebar drawer ────────────────────────────────────────────────
  const sidebarDrawer = (
    <Drawer
      variant={isMobile ? 'temporary' : 'persistent'}
      anchor="left"
      open={isLeftSidebarOpen}
      onClose={() => setLeftSidebarOpen(false)}
      ModalProps={{ keepMounted: true }} // Better mobile perf
      sx={{
        '& .MuiDrawer-paper': {
          boxSizing: 'border-box',
          width: DRAWER_WIDTH,
          borderRight: '1px solid',
          borderColor: 'divider',
          top: 0,
          height: '100%',
          bgcolor: 'var(--panel)',
        },
      }}
    >
      <SessionSidebar onClose={handleSidebarClose} />
    </Drawer>
  );

  // ── Main chat interface ───────────────────────────────────────────
  return (
    <Box sx={{ display: 'flex', width: '100%', height: '100%' }}>
      {/* ── Left Sidebar ─────────────────────────────────────────── */}
      {isMobile ? (
        // Mobile: temporary overlay drawer (no reserved width)
        sidebarDrawer
      ) : (
        // Desktop: persistent drawer with reserved width
        <Box
          component="nav"
          sx={{
            width: isLeftSidebarOpen ? DRAWER_WIDTH : 0,
            flexShrink: 0,
            transition: isResizing.current ? 'none' : 'width 0.2s',
            overflow: 'hidden',
          }}
        >
          {sidebarDrawer}
        </Box>
      )}

      {/* ── Main Content (header + chat + code panel) ────────────── */}
      <Box
        sx={{
          flexGrow: 1,
          height: '100%',
          display: 'flex',
          flexDirection: 'column',
          transition: isResizing.current ? 'none' : 'width 0.2s',
          overflow: 'hidden',
          minWidth: 0,
        }}
      >
        {/* ── Top Header Bar ─────────────────────────────────────── */}
        <Box sx={{ 
          height: { xs: 52, md: 60 },
          px: { xs: 1, md: 2 }, 
          display: 'flex', 
          alignItems: 'center', 
          borderBottom: 1, 
          borderColor: 'divider',
          bgcolor: 'background.default',
          zIndex: 1200,
          flexShrink: 0,
        }}>
          <IconButton onClick={toggleLeftSidebar} size="small">
            {isLeftSidebarOpen && !isMobile ? <ChevronLeftIcon /> : <MenuIcon />}
          </IconButton>
          
          <Box sx={{ flex: 1, display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 0.75 }}>
            <Box
              component="img"
              src="https://huggingface.co/front/assets/huggingface_logo-noborder.svg"
              alt="HF"
              sx={{ width: { xs: 20, md: 22 }, height: { xs: 20, md: 22 } }}
            />
            <Typography
              variant="subtitle1"
              sx={{
                fontWeight: 700,
                color: 'var(--text)',
                letterSpacing: '-0.01em',
                fontSize: { xs: '0.88rem', md: '0.95rem' },
              }}
            >
              ML Agent
            </Typography>
          </Box>

          <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
            <IconButton
              onClick={toggleTheme}
              size="small"
              sx={{ color: 'var(--muted-text)' }}
            >
              {themeMode === 'dark' ? <LightModeOutlinedIcon fontSize="small" /> : <DarkModeOutlinedIcon fontSize="small" />}
            </IconButton>

            <Box sx={{ display: 'flex', alignItems: 'center', ml: 1, gap: 1 }}>
              {user?.username && (
                <Typography variant="caption" sx={{ color: 'var(--muted-text)', display: { xs: 'none', sm: 'block' } }}>
                  {user.username}
                </Typography>
              )}
              <Avatar
                src={user?.picture}
                sx={{
                  width: 28,
                  height: 28,
                  border: '1px solid',
                  borderColor: 'divider',
                }}
              />
            </Box>
          </Box>
        </Box>

        {/* ── Chat + Code Panel ──────────────────────────────────── */}
        <Box sx={{ 
          flexGrow: 1, 
          display: 'flex', 
          overflow: 'hidden', 
          position: 'relative',
          bgcolor: 'background.default'
        }}>
          {/* Chat Column */}
          <Box sx={{ 
            flexGrow: 1, 
            display: 'flex', 
            flexDirection: 'column',
            minWidth: 0,
            height: '100%',
            position: 'relative',
          }}>
            <Box sx={{ flexGrow: 1, overflow: 'visible' }}>
              <MessageList messages={messages} isProcessing={isProcessing} />
            </Box>
            <Box sx={{ p: { xs: 1.5, md: 2.5 }, pt: 0 }}>
              <ChatInput 
                onSend={handleSendMessage} 
                disabled={!isConnected || isProcessing}
              />
            </Box>
          </Box>

          {/* Resizable Code Panel (Desktop only) */}
          {!isMobile && isRightPanelOpen && (
            <>
              {/* Resize Handle */}
              <Box
                onMouseDown={startResizing}
                sx={{
                  width: '4px',
                  cursor: 'col-resize',
                  bgcolor: 'transparent',
                  '&:hover': { bgcolor: 'primary.main', opacity: 0.5 },
                  zIndex: 10,
                  position: 'relative',
                  '&::after': {
                    content: '""',
                    position: 'absolute',
                    left: '50%',
                    top: '50%',
                    transform: 'translate(-50%, -50%)',
                    height: '24px',
                    width: '1px',
                    bgcolor: 'divider',
                  }
                }}
              />
              <Box sx={{ 
                width: rightPanelWidth,
                flexShrink: 0,
                height: '100%',
                bgcolor: 'var(--panel)',
                borderLeft: '1px solid',
                borderColor: 'divider',
                display: 'flex',
                flexDirection: 'column',
                overflow: 'hidden',
              }}>
                <CodePanel />
              </Box>
            </>
          )}

          {/* Mobile Code Panel Overlay */}
          {isMobile && isRightPanelOpen && (
            <Box sx={{
              position: 'absolute',
              top: 0,
              left: 0,
              right: 0,
              bottom: 0,
              zIndex: 1300,
              bgcolor: 'background.default',
              display: 'flex',
              flexDirection: 'column',
            }}>
              <CodePanel />
            </Box>
          )}
        </Box>
      </Box>
    </Box>
  );
}
