import React, { useEffect, useState, useCallback } from 'react';
import { 
  Box, 
  Paper, 
  Typography, 
  CircularProgress, 
  Button, 
  Divider, 
  IconButton, 
  Tooltip, 
  Snackbar, 
  Alert,
  AlertTitle,
  Tabs,
  Tab,
  Stack,
  Checkbox
} from '@mui/material';
import { 
  PlayArrow, 
  History, 
  Save, 
  CleaningServices, 
  Close,
  TableChart,
  Terminal,
  CloudDownload,
  CloudUpload,
  Info
} from '@mui/icons-material';
import { DataGrid } from '@mui/x-data-grid';
import type { GridColDef, GridPaginationModel } from '@mui/x-data-grid';
import Editor from '@monaco-editor/react';
import { useAppStore } from '../store/useAppStore';
import { SchemaService } from '../services/api';
import TransferContent from './TransferContent';
import ConfirmDialog from './ConfirmDialog';

interface MainNotification {
  open: boolean;
  message: string;
  title: string;
  severity: 'success' | 'error' | 'info' | 'warning';
}

const DatabaseTablesGrid = ({ database, setNotification }: { database: string, setNotification: (n: MainNotification) => void }) => {
  const [tableRows, setTableRows] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [selectionModel, setSelectionModel] = useState<string[]>([]);
  const { setActiveTable } = useAppStore();

  const fetchTablesMeta = useCallback(async () => {
    setLoading(true);
    try {
      const res = await SchemaService.getTablesMetadata(database);
      setTableRows(res.data);
    } catch (e) {
      console.error(e);
    } finally {
      setLoading(false);
    }
  }, [database]);

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

  const handleBulkAction = async (action: 'truncate' | 'drop' | 'optimize') => {
    if (selectionModel.length === 0) return;
    
    const confirmMsg = `Are you sure you want to ${action} ${selectionModel.length} selected tables? This action is irreversible!`;
    if (!window.confirm(confirmMsg)) return;

    setLoading(true);
    try {
      await SchemaService.bulkAction({
        tables: selectionModel,
        action,
        database
      });
      setNotification({
        open: true,
        title: 'Bulk Action Success',
        message: `Successfully performed ${action} on ${selectionModel.length} tables.`,
        severity: 'success'
      });
      fetchTablesMeta();
      setSelectionModel([]);
    } catch (error: any) {
      setNotification({
        open: true,
        title: 'Bulk Action Error',
        message: error.response?.data?.error || error.message,
        severity: 'error'
      });
    } finally {
      setLoading(false);
    }
  };

  const toggleRow = (name: string) => {
    setSelectionModel(prev => 
      prev.includes(name) ? prev.filter(n => n !== name) : [...prev, name]
    );
  };

  const toggleAll = () => {
    if (selectionModel.length === tableRows.length) {
      setSelectionModel([]);
    } else {
      setSelectionModel(tableRows.map(r => r.name));
    }
  };

  const columns: GridColDef[] = [
    {
      field: '__check__',
      headerName: '',
      width: 50,
      sortable: false,
      filterable: false,
      renderHeader: () => (
        <Checkbox 
          size="small" 
          indeterminate={selectionModel.length > 0 && selectionModel.length < tableRows.length}
          checked={tableRows.length > 0 && selectionModel.length === tableRows.length}
          onChange={toggleAll}
        />
      ),
      renderCell: (params) => (
        <Checkbox 
          size="small" 
          checked={selectionModel.includes(params.row.name)}
          onChange={(e) => {
            e.stopPropagation();
            toggleRow(params.row.name);
          }}
        />
      )
    },
    { 
      field: 'name', 
      headerName: 'Table Name', 
      flex: 1, 
      minWidth: 200,
      renderCell: (params) => (
        <Button 
          size="small" 
          startIcon={<TableChart fontSize="small" />}
          onClick={() => setActiveTable(params.value)}
          sx={{ textTransform: 'none', fontWeight: 600, color: '#ffc107', '&:hover': { color: '#ffca28' } }}
        >
          {params.value}
        </Button>
      )
    },
    { field: 'engine', headerName: 'Engine', width: 120 },
    { field: 'rows', headerName: 'Rows', type: 'number', width: 120 },
    { 
      field: 'data_length', 
      headerName: 'Data Size', 
      width: 130,
      valueFormatter: (value) => `${(Number(value) / 1024 / 1024).toFixed(2)} MB`
    },
    { 
      field: 'index_length', 
      headerName: 'Index Size', 
      width: 130,
      valueFormatter: (value) => `${(Number(value) / 1024 / 1024).toFixed(2)} MB`
    },
    { field: 'collation', headerName: 'Collation', width: 180 },
    { field: 'comment', headerName: 'Comment', flex: 1, minWidth: 150 },
  ];

  return (
    <Box sx={{ flexGrow: 1, display: 'flex', flexDirection: 'column', gap: 2 }}>
      {selectionModel.length > 0 && (
        <Paper sx={{ p: 1.5, borderRadius: 2, display: 'flex', alignItems: 'center', gap: 2, bgcolor: 'rgba(255, 193, 7, 0.05)', border: '1px dashed #ffc107' }}>
          <Typography variant="body2" sx={{ fontWeight: 700, color: '#ffc107' }}>
            {selectionModel.length} tables selected:
          </Typography>
          <Stack direction="row" spacing={1}>
            <Button size="small" color="warning" variant="outlined" startIcon={<CleaningServices />} onClick={() => handleBulkAction('truncate')}>Truncate</Button>
            <Button size="small" color="error" variant="outlined" startIcon={<Close />} onClick={() => handleBulkAction('drop')}>Drop</Button>
            <Button size="small" color="info" variant="outlined" startIcon={<Save />} onClick={() => handleBulkAction('optimize')}>Optimize</Button>
          </Stack>
          <Box sx={{ flexGrow: 1 }} />
          <Button size="small" onClick={() => setSelectionModel([])}>Clear Selection</Button>
        </Paper>
      )}
      <Paper sx={{ 
        flexGrow: 1, 
        borderRadius: 3, 
        overflow: 'hidden', 
        display: 'flex', 
        flexDirection: 'column', 
        border: 1, 
        borderColor: 'divider',
        boxShadow: '0 4px 12px rgba(0,0,0,0.05)'
      }}>
        <DataGrid
          rows={tableRows}
          columns={columns}
          loading={loading}
          getRowId={(row: any) => row.name}
          density="comfortable"
          sx={{ border: 'none' }}
        />
      </Paper>
    </Box>
  );
};

const TechnicalOverview = ({ database, table, setNotification }: { database: string, table: string | null, setNotification: (n: MainNotification) => void }) => {
  const [meta, setMeta] = useState<any>(null);
  const [loadingMeta, setLoadingMeta] = useState(true);
  const [truncating, setTruncating] = useState(false);
  const [showConfirm, setShowConfirm] = useState(false);

  const fetchMeta = useCallback(async () => {
    setLoadingMeta(true);
    try {
      const res = table 
        ? await SchemaService.getTableMetadata(database, table)
        : await SchemaService.getDatabaseMetadata(database);
      setMeta(res.data);
    } catch (e) {
      console.error(e);
    } finally {
      setLoadingMeta(false);
    }
  }, [database, table]);

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

  const handleTruncate = async () => {
    setTruncating(true);
    setShowConfirm(false);
    try {
      await SchemaService.truncateTable(table!);
      setNotification({
        open: true,
        title: 'Success',
        message: `Table "${table}" has been truncated.`,
        severity: 'success'
      });
      fetchMeta();
    } catch (error: any) {
      setNotification({
        open: true,
        title: 'Truncate Error',
        message: error.response?.data?.error || error.message,
        severity: 'error'
      });
    } finally {
      setTruncating(false);
    }
  };

  if (loadingMeta) return <Box sx={{ display: 'flex', justifyContent: 'center', p: 8 }}><CircularProgress /></Box>;
  if (!meta) return <Alert severity="error">Could not load metadata</Alert>;

  const stats = table ? [
    { label: 'Engine', value: meta.engine, icon: <Terminal /> },
    { label: 'Rows', value: meta.rows, icon: <TableChart /> },
    { label: 'Collation', value: meta.collation, icon: <CleaningServices /> },
    { label: 'Data Size', value: `${(meta.data_length / 1024 / 1024).toFixed(2)} MB`, icon: <Save /> },
    { label: 'Index Size', value: `${(meta.index_length / 1024 / 1024).toFixed(2)} MB`, icon: <History /> },
    { label: 'Created', value: meta.create_time, icon: <Info /> },
  ] : [
    { label: 'Character Set', value: meta.charset, icon: <History /> },
    { label: 'Collation', value: meta.collation, icon: <CleaningServices /> },
    { label: 'Tables', value: meta.table_count, icon: <TableChart /> },
    { label: 'Views', value: meta.view_count, icon: <History /> },
    { label: 'Total Size', value: `${(meta.size_bytes / 1024 / 1024).toFixed(2)} MB`, icon: <Save /> },
  ];

  return (
    <Box sx={{ p: 1 }}>
      <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 4 }}>
        <Typography variant="h5" sx={{ fontWeight: 800, letterSpacing: -0.5 }}>
          Technical Specifications: {table ? `${database}.${table}` : database}
        </Typography>
        {table && (
          <Button 
            variant="outlined" 
            color="error" 
            startIcon={truncating ? <CircularProgress size={16} color="inherit" /> : <CleaningServices />}
            onClick={() => setShowConfirm(true)}
            disabled={truncating}
            sx={{ borderRadius: 2, textTransform: 'none', fontWeight: 700 }}
          >
            Truncate Table
          </Button>
        )}
      </Box>

      <ConfirmDialog 
        open={showConfirm}
        onClose={() => setShowConfirm(false)}
        onConfirm={handleTruncate}
        title="Truncate Table"
        message={`Are you sure you want to truncate table "${table}"? This action will permanently delete all ${meta?.rows || ''} records. This cannot be undone.`}
        confirmLabel="Truncate Now"
        loading={truncating}
      />
      <Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(240px, 1fr))', gap: 3 }}>
        {stats.map((stat, i) => (
          <Paper key={i} sx={{ 
            p: 3, 
            borderRadius: 4, 
            border: 1, 
            borderColor: 'divider',
            display: 'flex',
            flexDirection: 'column',
            gap: 1,
            bgcolor: (theme) => theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.02)' : 'rgba(0,0,0,0.01)',
            transition: 'all 0.2s',
            '&:hover': { borderColor: 'primary.main', transform: 'translateY(-2px)' }
          }}>
            <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
              <Typography variant="caption" sx={{ fontWeight: 700, color: 'text.secondary', textTransform: 'uppercase', letterSpacing: 1 }}>{stat.label}</Typography>
              <Box sx={{ color: 'primary.main', opacity: 0.5 }}>{stat.icon}</Box>
            </Box>
            <Typography variant="h5" sx={{ fontWeight: 800 }}>{stat.value || 'N/A'}</Typography>
          </Paper>
        ))}
      </Box>
    </Box>
  );
};

const MainContent: React.FC = () => {
  const { activeTable, activeDatabase, darkMode, dbTab, setDbTab } = useAppStore();
  const [columns, setColumns] = useState<GridColDef[]>([]);
  const [rows, setRows] = useState<any[]>([]);
  const [rowCount, setRowCount] = useState(0);
  const [loadingSchema, setLoadingSchema] = useState(false);
  const [loadingData, setLoadingData] = useState(false);
  const [sqlQuery, setSqlQuery] = useState('');
  const [isCustomQuery, setIsCustomQuery] = useState(false);
  const [paginationModel, setPaginationModel] = useState<GridPaginationModel>({
    page: 0,
    pageSize: 100,
  });

  // Custom Notification State
  const [notification, setNotification] = useState<MainNotification>({
    open: false,
    message: '',
    title: '',
    severity: 'error'
  });

  const handleCloseNotification = () => setNotification({ ...notification, open: false });

  // Helper to map SQL types to MUI X Data Grid types
  const mapSqlTypeToMuiType = (sqlType: string): 'string' | 'number' | 'date' | 'dateTime' | 'boolean' => {
    sqlType = sqlType.toLowerCase();
    if (sqlType.includes('int') || sqlType.includes('decimal') || sqlType.includes('float') || sqlType.includes('double')) return 'number';
    if (sqlType.includes('datetime') || sqlType.includes('timestamp')) return 'dateTime';
    if (sqlType.includes('date')) return 'date';
    if (sqlType.includes('bool') || sqlType.includes('tinyint(1)')) return 'boolean';
    return 'string';
  };

  // Set initial SQL query when table changes
  useEffect(() => {
    if (activeTable && activeDatabase) {
      setSqlQuery(`SELECT * FROM ${activeDatabase}.${activeTable} LIMIT 1000;`);
      setIsCustomQuery(false);
    }
  }, [activeTable, activeDatabase]);

  // Fetch Schema
  useEffect(() => {
    const fetchSchema = async () => {
      if (!activeTable || !activeDatabase || isCustomQuery) return;
      
      setLoadingSchema(true);
      try {
        const schemaRes = await SchemaService.getTableSchema(activeTable, activeDatabase);
        const cols: GridColDef[] = schemaRes.data.map((col: any) => {
          const type = mapSqlTypeToMuiType(col.Type);
          return {
            field: col.Field,
            headerName: col.Field,
            type: type,
            width: 200,
            minWidth: 100,
            valueGetter: (value: any) => {
              if ((type === 'date' || type === 'dateTime') && value && typeof value === 'string') {
                return new Date(value);
              }
              return value;
            },
          };
        });
        setColumns(cols);
        setPaginationModel({ page: 0, pageSize: 100 });
      } catch (error) {
        console.error('Failed to fetch table schema', error);
      } finally {
        setLoadingSchema(false);
      }
    };

    fetchSchema();
  }, [activeTable, activeDatabase, isCustomQuery]);

  // Fetch Data
  const fetchData = useCallback(async () => {
    if (!activeTable || !activeDatabase || isCustomQuery) return;

    setLoadingData(true);
    try {
      const params = {
        skip: paginationModel.page * paginationModel.pageSize,
        take: paginationModel.pageSize,
        requireTotalCount: true,
        database: activeDatabase,
      };

      const response = await SchemaService.getTableData(activeTable, params);
      
      const dataWithIds = response.data.data.map((row: any, index: number) => ({
        id: row.id || row.ID || `row-${index}-${paginationModel.page}`,
        ...row,
      }));

      setRows(dataWithIds);
      setRowCount(response.data.totalCount || 0);
    } catch (error) {
      console.error('Data loading error', error);
    } finally {
      setLoadingData(false);
    }
  }, [activeTable, activeDatabase, paginationModel, isCustomQuery]);

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

  const handleExecute = async () => {
    if (!sqlQuery) return;
    setLoadingData(true);
    setIsCustomQuery(true);
    try {
      const response = await SchemaService.executeQuery(sqlQuery);
      const rawData = response.data.data;
      
      if (rawData && rawData.length > 0) {
        const fields = Object.keys(rawData[0]);
        const newCols: GridColDef[] = fields.map(field => ({
          field,
          headerName: field,
          width: 150,
          flex: fields.length < 6 ? 1 : 0
        }));
        setColumns(newCols);
        
        const dataWithIds = rawData.map((row: any, index: number) => ({
          id: row.id || row.ID || `row-${index}`,
          ...row,
        }));
        setRows(dataWithIds);
        setRowCount(response.data.count);
      } else {
        setRows([]);
        setRowCount(0);
      }
    } catch (error: any) {
      console.error('Execution error', error);
      const msg = error.response?.data?.error || 'An unexpected error occurred during SQL execution.';
      setNotification({
        open: true,
        title: 'SQL Execution Error',
        message: msg,
        severity: 'error'
      });
    } finally {
      setLoadingData(false);
    }
  };

  if (!activeDatabase) {
    return (
      <Box sx={{ flexGrow: 1, p: 3, display: 'flex', alignItems: 'center', justifyContent: 'center', bgcolor: 'background.default' }}>
        <Typography variant="h6" color="text.secondary">Select a database to start</Typography>
      </Box>
    );
  }

  const handleTabChange = (_: React.SyntheticEvent, newValue: string) => {
    setDbTab(newValue);
  };

  return (
    <Box sx={{ flexGrow: 1, p: 3, bgcolor: 'background.default', display: 'flex', flexDirection: 'column', width: '100%', minWidth: 0, overflow: 'hidden', gap: 2 }}>
      {/* Database Navigation Tabs */}
      <Paper elevation={0} sx={{ 
        flexShrink: 0,
        borderRadius: 3, 
        border: 1, 
        borderColor: 'divider',
        bgcolor: darkMode ? '#111827' : '#ffffff',
        overflow: 'hidden'
      }}>
        <Tabs 
          value={dbTab} 
          onChange={handleTabChange}
          sx={{
            px: 2,
            minHeight: 56,
            '& .MuiTabs-indicator': { height: 3, borderRadius: '3px 3px 0 0' },
            '& .MuiTab-root': { 
              textTransform: 'none', 
              fontWeight: 700, 
              fontSize: '0.9rem',
              minHeight: 56,
              minWidth: 120,
              gap: 1
            }
          }}
        >
          <Tab value="tables" icon={<TableChart sx={{ fontSize: 18 }} />} iconPosition="start" label="Data Explorer" />
          <Tab value="sql" icon={<Terminal sx={{ fontSize: 18 }} />} iconPosition="start" label="SQL Editor" />
          <Tab value="import" icon={<CloudUpload sx={{ fontSize: 18 }} />} iconPosition="start" label="Import" />
          <Tab value="export" icon={<CloudDownload sx={{ fontSize: 18 }} />} iconPosition="start" label="Export" />
          <Tab value="info" icon={<Info sx={{ fontSize: 18 }} />} iconPosition="start" label="Technical Info" />
        </Tabs>
      </Paper>

      {/* Tables View */}
      {dbTab === 'tables' && (
        <Box sx={{ flexGrow: 1, display: 'flex', flexDirection: 'column', minWidth: 0, overflow: 'hidden' }}>
          {!activeTable ? (
            <Box sx={{ flexGrow: 1, display: 'flex', flexDirection: 'column', gap: 2 }}>
              <Typography variant="h6" sx={{ fontWeight: 800 }}>Database Tables: {activeDatabase}</Typography>
              <DatabaseTablesGrid database={activeDatabase} setNotification={setNotification} />
            </Box>
          ) : (
            <>
              <Box sx={{ mb: 1.5, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
                  <Typography variant="h6" sx={{ fontWeight: 800 }}>Table Results: {activeTable}</Typography>
                  <Box sx={{ px: 1.5, py: 0.5, borderRadius: 10, bgcolor: 'rgba(0, 97, 255, 0.1)', color: 'primary.main' }}>
                    <Typography variant="caption" sx={{ fontWeight: 700 }}>{rowCount} rows found</Typography>
                  </Box>
                </Box>
              </Box>
              
              <Paper sx={{ 
                flexGrow: 1, 
                borderRadius: 3, 
                overflow: 'hidden', 
                display: 'flex', 
                flexDirection: 'column', 
                width: '100%', 
                border: 1, 
                borderColor: 'divider',
                boxShadow: '0 4px 12px rgba(0,0,0,0.05)'
              }}>
                {loadingSchema ? (
                  <Box sx={{ display: 'flex', height: '100%', alignItems: 'center', justifyContent: 'center' }}>
                    <CircularProgress />
                  </Box>
                ) : (
                  <DataGrid
                    rows={rows}
                    columns={columns}
                    rowCount={rowCount}
                    loading={loadingData}
                    paginationMode="server"
                    paginationModel={paginationModel}
                    onPaginationModelChange={setPaginationModel}
                    pageSizeOptions={[25, 50, 100]}
                    sx={{
                      border: 'none',
                      '& .MuiDataGrid-row:hover': { bgcolor: 'rgba(0, 97, 255, 0.04)' },
                    }}
                  />
                )}
              </Paper>
            </>
          )}
        </Box>
      )}

      {/* SQL View */}
      {dbTab === 'sql' && (
        <Box sx={{ flexGrow: 1, display: 'flex', flexDirection: 'column', gap: 2, overflow: 'hidden' }}>
          <Paper elevation={0} sx={{ 
            flexShrink: 0, 
            borderRadius: 3, 
            overflow: 'hidden', 
            border: 1, 
            borderColor: 'divider',
            bgcolor: darkMode ? '#111827' : '#ffffff',
          }}>
            <Box sx={{ px: 3, py: 1.5, display: 'flex', alignItems: 'center', justifyContent: 'space-between', bgcolor: 'rgba(0,0,0,0.02)' }}>
              <Typography variant="subtitle2" sx={{ fontWeight: 800 }}>SQL CONSOLE</Typography>
              <Box sx={{ display: 'flex', gap: 1 }}>
                <Button 
                  variant="contained" 
                  size="small" 
                  onClick={handleExecute}
                  disabled={loadingData}
                  startIcon={loadingData ? <CircularProgress size={16} color="inherit" /> : <PlayArrow />}
                  sx={{ borderRadius: 2, textTransform: 'none', fontWeight: 700 }}
                >
                  Execute Query
                </Button>
              </Box>
            </Box>
            <Editor
              height="200px"
              defaultLanguage="sql"
              theme={darkMode ? 'vs-dark' : 'light'}
              value={sqlQuery}
              onChange={(value) => setSqlQuery(value || '')}
              options={{ minimap: { enabled: false }, fontSize: 14, automaticLayout: true }}
            />
          </Paper>
          
          <Paper sx={{ flexGrow: 1, borderRadius: 3, overflow: 'hidden', border: 1, borderColor: 'divider' }}>
            <DataGrid
              rows={rows}
              columns={columns}
              loading={loadingData}
              sx={{ border: 'none' }}
            />
          </Paper>
        </Box>
      )}

      {/* Import/Export Views */}
      {dbTab === 'import' && <TransferContent mode="import" />}
      {dbTab === 'export' && <TransferContent mode="export" />}

      {/* Technical Info View */}
      {dbTab === 'info' && <TechnicalOverview database={activeDatabase} table={activeTable} setNotification={setNotification} />}

      {/* Custom Notification (Snackbar) */}
      <Snackbar open={notification.open} autoHideDuration={6000} onClose={handleCloseNotification} anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}>
        <Alert onClose={handleCloseNotification} severity={notification.severity} variant="filled" sx={{ 
          width: '100%', 
          borderRadius: 2,
          boxShadow: notification.severity === 'success' ? '0 8px 24px rgba(46, 125, 50, 0.25)' : '0 8px 24px rgba(211, 47, 47, 0.25)'
        }}>
          <AlertTitle sx={{ fontWeight: 800 }}>{notification.title}</AlertTitle>
          <Typography variant="body2">{notification.message}</Typography>
        </Alert>
      </Snackbar>
    </Box>
  );
};

export default MainContent;
