import React, { useEffect, useState, useMemo } from 'react';
import { Box, List, ListItem, ListItemButton, ListItemIcon, ListItemText, Typography, Divider, CircularProgress, Stack, TextField, InputAdornment, IconButton, Tooltip, Dialog, DialogTitle, DialogContent, DialogActions, Button, Alert, Snackbar, AlertTitle } from '@mui/material';
import { Storage, Search, FilterList, ChevronRight, ExpandMore, TableChart, Folder, Add } from '@mui/icons-material';
import { useAppStore } from '../store/useAppStore';
import { SchemaService } from '../services/api';
import type { MainNotification } from '../types/database';

const Sidebar: React.FC = () => {
  const { activeDatabase, setActiveDatabase, setActiveTable, activeTable } = useAppStore();
  const [databases, setDatabases] = useState<string[]>([]);
  const [tables, setTables] = useState<string[]>([]);
  const [loading, setLoading] = useState(true);
  const [expandedDbs, setExpandedDbs] = useState<string[]>([]);
  
  const [dbSearch, setDbSearch] = useState('');
  const [tableSearch, setTableSearch] = useState('');

  const [tablesLoading, setTablesLoading] = useState(false);
  
  const [openNewDbDialog, setOpenNewDbDialog] = useState(false);
  const [newDbName, setNewDbName] = useState('');
  const [isCreatingDb, setIsCreatingDb] = useState(false);
  const [notification, setNotification] = useState<MainNotification>({
    open: false,
    message: '',
    title: '',
    severity: 'success'
  });

  const fetchDatabases = async () => {
    setLoading(true);
    try {
      const response = await SchemaService.getDatabases();
      setDatabases(response.data);
    } catch (error) {
      console.error('Failed to fetch databases', error);
    } finally {
      setLoading(false);
    }
  };
  
  // Fetch databases on mount
  useEffect(() => {
    fetchDatabases();
  }, []);

  // Fetch tables when activeDatabase changes
  useEffect(() => {
    const fetchTables = async () => {
      if (!activeDatabase) {
        setTables([]);
        return;
      }
      
      setTablesLoading(true);
      try {
        const response = await SchemaService.getTables(activeDatabase);
        setTables(response.data);
      } catch (error) {
        console.error('Failed to fetch tables', error);
        setTables([]);
      } finally {
        setTablesLoading(false);
      }
    };
    fetchTables();
  }, [activeDatabase]);

  // Auto-expand when a database is active
  useEffect(() => {
    if (activeDatabase && !expandedDbs.includes(activeDatabase)) {
      setExpandedDbs(prev => [...prev, activeDatabase]);
    }
  }, [activeDatabase]);

  const toggleExpansion = (e: React.MouseEvent, db: string) => {
    e.stopPropagation();
    setExpandedDbs(prev => 
      prev.includes(db) ? prev.filter(d => d !== db) : [...prev, db]
    );
  };

  const handleDatabaseClick = (db: string) => {
    setActiveDatabase(db);
    setActiveTable(null);
    setTableSearch('');
    
    // Also ensure it's expanded
    if (!expandedDbs.includes(db)) {
      setExpandedDbs(prev => [...prev, db]);
    }
  };

  const filteredDatabases = useMemo(() => {
    return databases.filter(db => db.toLowerCase().includes(dbSearch.toLowerCase()));
  }, [databases, dbSearch]);

  const filteredTables = useMemo(() => {
    return tables.filter(table => table.toLowerCase().includes(tableSearch.toLowerCase()));
  }, [tables, tableSearch]);

  const handleCreateDatabase = async () => {
    if (!newDbName.trim()) return;
    
    setIsCreatingDb(true);
    try {
      await SchemaService.createDatabase(newDbName);
      setNotification({
        open: true,
        title: 'Success',
        message: `Database '${newDbName}' created successfully.`,
        severity: 'success'
      });
      setOpenNewDbDialog(false);
      setNewDbName('');
      fetchDatabases();
    } catch (error: any) {
      setNotification({
        open: true,
        title: 'Error',
        message: error.response?.data?.error || error.message,
        severity: 'error'
      });
    } finally {
      setIsCreatingDb(false);
    }
  };

  return (
    <Box sx={{ width: 280, borderRight: 1, borderColor: 'divider', display: 'flex', flexDirection: 'column', bgcolor: 'background.paper', zIndex: 10 }}>
      <Box sx={{ p: 2, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>
          <Storage color="primary" sx={{ fontSize: 24 }} />
          <Typography variant="h6" sx={{ fontWeight: 800, fontSize: '1.1rem' }}>Explorer</Typography>
        </Box>
        <Tooltip title="New Database">
          <IconButton size="small" onClick={() => setOpenNewDbDialog(true)} sx={{ color: 'primary.main' }}>
            <Add fontSize="small" />
          </IconButton>
        </Tooltip>
      </Box>
      
      <Box sx={{ px: 2, pb: 1 }}>
        <TextField
          placeholder="Search Databases..."
          size="small"
          fullWidth
          value={dbSearch}
          onChange={(e) => setDbSearch(e.target.value)}
          sx={{ 
            '& .MuiOutlinedInput-root': {
              borderRadius: 2,
              bgcolor: 'rgba(0,0,0,0.03)',
              fontSize: '0.8rem'
            }
          }}
          slotProps={{
            input: {
              startAdornment: <InputAdornment position="start"><Search sx={{ fontSize: 18, color: 'text.secondary' }} /></InputAdornment>,
            }
          }}
        />
      </Box>
      
      <Divider />
      
      <Box sx={{ flexGrow: 1, overflowY: 'auto' }}>
        {loading ? (
          <Box sx={{ display: 'flex', justifyContent: 'center', p: 4 }}><CircularProgress size={24} /></Box>
        ) : (
          <List dense sx={{ p: 0 }}>
            {filteredDatabases.map((db) => (
              <React.Fragment key={db}>
                <ListItem disablePadding>
                  <ListItemButton 
                    onClick={() => handleDatabaseClick(db)}
                    selected={activeDatabase === db}
                    sx={{ py: 0.5, px: 1 }}
                  >
                    <ListItemIcon sx={{ minWidth: 24, cursor: 'pointer' }} onClick={(e) => toggleExpansion(e, db)}>
                      {expandedDbs.includes(db) ? <ExpandMore fontSize="small" /> : <ChevronRight fontSize="small" />}
                    </ListItemIcon>
                    <ListItemIcon sx={{ minWidth: 32 }}>
                      <Folder fontSize="small" sx={{ color: activeDatabase === db ? 'primary.main' : 'text.secondary' }} />
                    </ListItemIcon>
                    <ListItemText 
                      primary={<Typography variant="body2" sx={{ fontWeight: activeDatabase === db ? 600 : 400, fontSize: '0.85rem' }}>{db}</Typography>} 
                    />
                  </ListItemButton>
                </ListItem>
                
                {expandedDbs.includes(db) && (
                  <Box sx={{ 
                    position: 'relative',
                    ml: 2.5,
                    borderLeft: '1px solid rgba(255,255,255,0.05)',
                    bgcolor: 'rgba(0,0,0,0.02)', 
                    pb: 1 
                  }}>
                    <Box sx={{ px: 2, py: 1 }}>
                      <TextField
                        placeholder="Filter Tables..."
                        size="small"
                        fullWidth
                        autoFocus
                        value={tableSearch}
                        onChange={(e) => setTableSearch(e.target.value)}
                        sx={{
                          '& .MuiOutlinedInput-root': {
                            borderRadius: 1,
                            bgcolor: 'background.paper',
                            fontSize: '0.7rem',
                            height: 28
                          }
                        }}
                        slotProps={{
                          input: {
                            startAdornment: <InputAdornment position="start"><FilterList sx={{ fontSize: 14, color: 'text.secondary' }} /></InputAdornment>,
                          }
                        }}
                      />
                    </Box>
                    <List dense sx={{ p: 0 }}>
                      {tablesLoading ? (
                        <ListItem sx={{ pl: 4 }}><CircularProgress size={14} /></ListItem>
                      ) : filteredTables.length === 0 ? (
                        <ListItem sx={{ pl: 4 }}><Typography variant="caption" sx={{ color: 'text.secondary', fontStyle: 'italic' }}>No tables found</Typography></ListItem>
                      ) : filteredTables.map((table) => (
                        <ListItem key={table} disablePadding>
                          <ListItemButton 
                            selected={activeTable === table}
                            onClick={() => setActiveTable(table)}
                            sx={{ 
                              py: 0.4,
                              px: 2,
                              borderRadius: '4px',
                              mx: 0.5,
                              mb: 0.1,
                              '&.Mui-selected': {
                                bgcolor: 'primary.main',
                                color: 'white',
                                '&:hover': { bgcolor: 'primary.dark' }
                              }
                            }}
                          >
                            <ListItemIcon sx={{ minWidth: 28 }}>
                              <TableChart sx={{ fontSize: 16, opacity: 0.7 }} />
                            </ListItemIcon>
                            <ListItemText 
                              primary={
                                <Typography variant="body2" sx={{ 
                                  fontWeight: activeTable === table ? 600 : 400,
                                  fontSize: '0.8rem' 
                                }}>
                                  {table}
                                </Typography>
                              } 
                            />
                          </ListItemButton>
                        </ListItem>
                      ))}
                    </List>
                  </Box>
                )}
              </React.Fragment>
            ))}
          </List>
        )}
      </Box>
      <Divider />
      <Box sx={{ p: 1.5, bgcolor: 'rgba(0,0,0,0.03)' }}>
        <Stack direction="row" spacing={1} sx={{ alignItems: 'center' }}>
          <Box sx={{ width: 8, height: 8, borderRadius: '50%', bgcolor: 'success.main' }} />
          <Typography variant="caption" sx={{ color: 'text.secondary', fontWeight: 600, fontSize: '0.7rem' }}>
            Connected: 127.0.0.1
          </Typography>
        </Stack>
      </Box>

      {/* New Database Dialog */}
      <Dialog open={openNewDbDialog} onClose={() => setOpenNewDbDialog(false)} maxWidth="xs" fullWidth>
        <DialogTitle sx={{ fontWeight: 800 }}>Create New Database</DialogTitle>
        <DialogContent>
          <TextField
            autoFocus
            margin="dense"
            label="Database Name"
            type="text"
            fullWidth
            variant="outlined"
            value={newDbName}
            onChange={(e) => setNewDbName(e.target.value)}
            disabled={isCreatingDb}
            onKeyDown={(e) => {
              if (e.key === 'Enter') handleCreateDatabase();
            }}
          />
        </DialogContent>
        <DialogActions sx={{ p: 2, pt: 0 }}>
          <Button onClick={() => setOpenNewDbDialog(false)} disabled={isCreatingDb}>Cancel</Button>
          <Button 
            onClick={handleCreateDatabase} 
            variant="contained" 
            disabled={isCreatingDb || !newDbName.trim()}
          >
            {isCreatingDb ? <CircularProgress size={24} /> : 'Create'}
          </Button>
        </DialogActions>
      </Dialog>

      {/* Local Notification */}
      <Snackbar 
        open={notification.open} 
        autoHideDuration={4000} 
        onClose={() => setNotification({ ...notification, open: false })}
        anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
      >
        <Alert 
          severity={notification.severity} 
          variant="filled" 
          onClose={() => setNotification({ ...notification, open: false })}
          sx={{ width: '100%', borderRadius: 2 }}
        >
          <AlertTitle sx={{ fontWeight: 700 }}>{notification.title}</AlertTitle>
          {notification.message}
        </Alert>
      </Snackbar>
    </Box>
  );
};

export default Sidebar;
