import { useState, useEffect } from 'react';
import {
  Box,
  Typography,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Card,
  CardContent,
  Button,
  Chip,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  TextField,
  Grid,
  Alert,
  CircularProgress,
  LinearProgress,
} from '@mui/material';
import {
  Security as SecurityIcon,
  Refresh as RefreshIcon,
  Edit as EditIcon,
  Delete as DeleteIcon,
  Add as AddIcon,
  CheckCircle as CheckCircleIcon,
  Error as ErrorIcon,
  Warning as WarningIcon,
} from '@mui/icons-material';
import toast from 'react-hot-toast';
import { apiJson, apiFetch } from '../lib/api';
import { logger } from '../lib/logger';

interface Server {
  id: number;
  name: string;
  host: string;
  port: number;
  company_db?: string;
  connection_status: string;
  last_connected?: string;
  is_active: boolean;
}

interface ServerConfig {
  name: string;
  host: string;
  port: number;
  username?: string;
  password?: string;
  api_key?: string;
  company_db?: string;
  use_https?: boolean;
  verify_ssl?: boolean;
  use_ssl?: boolean;
}

interface ConnectionTestResult {
  success: boolean;
  message: string;
  latency_ms?: number;
  error?: {
    error_type: string;
    error_code: string;
    message: string;
    details?: string;
  };
  requires_2fa?: boolean;
  session_id?: string;
  two_factor_method?: string;
}


type ServerType = 'plesk' | 'sap';

export const ServersPage: React.FC = () => {

  const [pleskServers, setPleskServers] = useState<Server[]>([]);
  const [sapServers, setSapServers] = useState<Server[]>([]);
  const [loading, setLoading] = useState(false);
  const [dialogOpen, setDialogOpen] = useState(false);
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [serverToDelete, setServerToDelete] = useState<{id: number, type: ServerType} | null>(null);
  const [serverType, setServerType] = useState<ServerType>('plesk');
  const [editingServer, setEditingServer] = useState<Server | null>(null);
  const [testingServerId, setTestingServerId] = useState<number | null>(null);
  const [testResult, setTestResult] = useState<ConnectionTestResult | null>(null);

  const [config, setConfig] = useState<ServerConfig>({
    name: '',
    host: '',
    port: 8443,
    username: '',
    password: '',
    api_key: '',
    company_db: '',
    use_https: true,
    verify_ssl: true,
    use_ssl: true,
  });

  const [formErrors, setFormErrors] = useState<Record<string, string>>({});

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

  const fetchServers = async () => {
    setLoading(true);
    try {
      const [pleskData, sapData] = await Promise.all([
        apiJson<Server[]>('/servers/plesk').catch(() => []),
        apiJson<Server[]>('/servers/sap').catch(() => []),
      ]);
      setPleskServers(Array.isArray(pleskData) ? pleskData : []);
      setSapServers(Array.isArray(sapData) ? sapData : []);
    } catch (error) {
      logger.error('Failed to fetch servers:', error);
      toast.error('Failed to load servers');
    } finally {
      setLoading(false);
    }
  };

  const validateForm = (): boolean => {
    const errors: Record<string, string> = {};

    if (!config.name.trim()) {
      errors.name = 'Name is required';
    }

    if (!config.host.trim()) {
      errors.host = 'Host is required';
    } else if (!/^[a-zA-Z0-9._-]+(:\d+)?$/.test(config.host) && !/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(:\d+)?$/.test(config.host)) {
      errors.host = 'Invalid host format';
    }

    if (config.port < 1 || config.port > 65535) {
      errors.port = 'Port must be between 1 and 65535';
    }

    if (serverType === 'plesk') {
      if (!config.api_key && !config.username) {
        errors.api_key = 'API key or username is required';
      }
      if (config.username && !config.password) {
        errors.password = 'Password is required when username is provided';
      }
    } else {
      if (!config.company_db?.trim()) {
        errors.company_db = 'Company database is required';
      }
      if (!config.username?.trim()) {
        errors.username = 'Username is required';
      }
      if (!config.password?.trim()) {
        errors.password = 'Password is required';
      }
    }

    setFormErrors(errors);
    return Object.keys(errors).length === 0;
  };

  const handleOpenDialog = (server?: Server, type?: ServerType) => {
    if (server) {
      setServerType(type || (server.host.includes('sap') ? 'sap' as ServerType : 'plesk' as ServerType));
      setEditingServer(server);
      setConfig({
        name: server.name,
        host: server.host,
        port: server.port,
        username: '',
        password: '',
        api_key: '',
        company_db: server.company_db || '',
        use_https: true,
        verify_ssl: true,
        use_ssl: true,
      });
    } else {
      setServerType(type || 'plesk');
      setEditingServer(null);
      setConfig({
        name: '',
        host: '',
        port: type === 'plesk' ? 8443 : 50000,
        username: '',
        password: '',
        api_key: '',
        company_db: '',
        use_https: true,
        verify_ssl: true,
        use_ssl: true,
      });
    }
    setFormErrors({});
    setTestResult(null);
    setDialogOpen(true);
  };

  const handleCloseDialog = () => {
    setDialogOpen(false);
    setEditingServer(null);
    setFormErrors({});
    setTestResult(null);
  };

  const handleSave = async () => {
    if (!validateForm()) {
      toast.error('Please fix the form errors');
      return;
    }

    setLoading(true);
    try {
      const endpoint = `/servers/${serverType}`;
      const method = editingServer ? 'PUT' : 'POST';
      const path = editingServer ? `${endpoint}/${editingServer.id}` : endpoint;

      const response = await apiJson<{message?: string; error?: string}>(path, {
        method: method,
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(config),
      });

      if (response.error) {
        toast.error(response.error);
        return;
      }

      toast.success(editingServer ? 'Server updated successfully' : 'Server added successfully');
      fetchServers();
      handleCloseDialog();
    } catch (error) {
      logger.error('Failed to save server:', error);
      toast.error('Failed to save server');
    } finally {
      setLoading(false);
    }
  };

  const handleDeleteClick = (id: number, type: ServerType) => {
    setServerToDelete({ id, type });
    setDeleteDialogOpen(true);
  };

  const handleDeleteConfirm = async () => {
    if (!serverToDelete) return;

    try {
      await apiFetch(`/servers/${serverToDelete.type}/${serverToDelete.id}`, { method: 'DELETE' });
      toast.success('Server deleted successfully');
      fetchServers();
    } catch (error) {
      logger.error('Failed to delete server:', error);
      toast.error('Failed to delete server');
    } finally {
      setDeleteDialogOpen(false);
      setServerToDelete(null);
    }
  };

  const handleTestConnection = async (server: Server, type: ServerType) => {
    setTestingServerId(server.id);
    setTestResult(null);

    try {
      const result = await apiJson<ConnectionTestResult>(`/servers/${type}/${server.id}/test`, {
        method: 'POST',
      });

      setTestResult(result);

      if (result.success) {
        toast.success(`Connection successful (${result.latency_ms}ms)`);
        fetchServers(); // Refresh to update status
      } else if (result.requires_2fa) {
        toast('Two-factor authentication required', { icon: '🔐' });
      } else {
        const errorMsg = result.error?.message || result.message;
        toast.error(`Connection failed: ${errorMsg}`);
      }
    } catch (error) {
      logger.error('Connection test failed:', error);
      toast.error('Connection test failed');
    } finally {
      setTestingServerId(null);
    }
  };

  const getStatusColor = (status: string): 'default' | 'error' | 'warning' | 'success' => {
    switch (status) {
      case 'connected': return 'success';
      case 'disconnected': return 'error';
      case 'unknown': return 'default';
      default: return 'warning';
    }
  };

  const getStatusIcon = (status: string) => {
    switch (status) {
      case 'connected': return <CheckCircleIcon fontSize="small" color="success" />;
      case 'disconnected': return <ErrorIcon fontSize="small" color="error" />;
      default: return <WarningIcon fontSize="small" color="warning" />;
    }
  };

  const renderServers = (servers: Server[], type: ServerType) => (
    <Card>
      <CardContent>
        <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
          <Typography variant="h6">
            {type === 'plesk' ? 'Plesk Servers' : 'SAP Servers'}
          </Typography>
          <Button
            variant="contained"
            startIcon={<AddIcon />}
            onClick={() => handleOpenDialog(undefined, type)}
          >
            {type === 'plesk' ? 'Add Plesk Server' : 'Add SAP Server'}
          </Button>
        </Box>

        {loading && <LinearProgress sx={{ mb: 2 }} />}

        <TableContainer>
          <Table>
            <TableHead>
              <TableRow>
                <TableCell>Name</TableCell>
                <TableCell>Host</TableCell>
                <TableCell>Port</TableCell>
                {type === 'sap' && <TableCell>Company DB</TableCell>}
                <TableCell>Status</TableCell>
                <TableCell>Last Connected</TableCell>
                <TableCell>Actions</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {servers.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={type === 'sap' ? 7 : 6} align="center">
                    <Typography variant="body2" color="textSecondary">
                      No servers configured
                    </Typography>
                  </TableCell>
                </TableRow>
              ) : (
                servers.map((server) => (
                  <TableRow key={server.id}>
                    <TableCell>
                      <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
                        <SecurityIcon fontSize="small" color={server.is_active ? 'primary' : 'disabled'} />
                        <Typography variant="body2">{server.name}</Typography>
                      </Box>
                    </TableCell>
                    <TableCell>{server.host}</TableCell>
                    <TableCell>{server.port}</TableCell>
                    {type === 'sap' && <TableCell>{server.company_db || '-'}</TableCell>}
                    <TableCell>
                      <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
                        {getStatusIcon(server.connection_status)}
                        <Chip
                          label={server.connection_status}
                          color={getStatusColor(server.connection_status)}
                          size="small"
                        />
                      </Box>
                    </TableCell>
                    <TableCell>
                      {server.last_connected
                        ? new Date(server.last_connected).toLocaleString()
                        : '-'}
                    </TableCell>
                    <TableCell>
                      <Box sx={{ display: 'flex', gap: 0.5 }}>
                        <Button
                          size="small"
                          variant="outlined"
                          startIcon={testingServerId === server.id ? <CircularProgress size={16} /> : <RefreshIcon />}
                          onClick={() => handleTestConnection(server, type)}
                          disabled={testingServerId === server.id}
                        >
                          {testingServerId === server.id ? 'Testing...' : 'Test'}
                        </Button>
                        <Button
                          size="small"
                          variant="outlined"
                          startIcon={<EditIcon />}
                          onClick={() => handleOpenDialog(server, type)}
                        >
                          Edit
                        </Button>
                        <Button
                          size="small"
                          variant="outlined"
                          color="error"
                          startIcon={<DeleteIcon />}
                          onClick={() => handleDeleteClick(server.id, type)}
                        >
                          Delete
                        </Button>
                      </Box>
                    </TableCell>
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </TableContainer>
      </CardContent>
    </Card>
  );

  return (
    <Box sx={{ flexGrow: 1 }}>
      <Box sx={{ mb: 3 }}>
        <Typography variant="h4">Server Management</Typography>
      </Box>

      <Box sx={{ display: 'flex', gap: 1, mb: 3 }}>
        <Button
          variant="contained"
          startIcon={<RefreshIcon />}
          onClick={fetchServers}
          disabled={loading}
        >
          Refresh
        </Button>
      </Box>

      {renderServers(pleskServers, 'plesk')}
      <Box sx={{ mb: 3 }} />
      {renderServers(sapServers, 'sap')}

      {/* Add/Edit Server Dialog */}
      <Dialog open={dialogOpen} onClose={handleCloseDialog} maxWidth="sm" fullWidth>
        <DialogTitle>
          {editingServer
            ? `Edit ${serverType === 'plesk' ? 'Plesk' : 'SAP'} Server`
            : `Add ${serverType === 'plesk' ? 'Plesk' : 'SAP'} Server`}
        </DialogTitle>
        <DialogContent>
          <Box component="form" sx={{ mt: 2 }}>
            <TextField
              fullWidth
              label="Server Name"
              value={config.name}
              onChange={(e) => setConfig({ ...config, name: e.target.value })}
              margin="normal"
              required
              error={!!formErrors.name}
              helperText={formErrors.name}
            />

            <Grid container spacing={2}>
              <Grid item xs={8}>
                <TextField
                  fullWidth
                  label="Host"
                  value={config.host}
                  onChange={(e) => setConfig({ ...config, host: e.target.value })}
                  margin="normal"
                  required
                  error={!!formErrors.host}
                  helperText={formErrors.host || 'e.g., plesk.example.com or 192.168.1.1'}
                />
              </Grid>
              <Grid item xs={4}>
                <TextField
                  fullWidth
                  type="number"
                  label="Port"
                  value={config.port}
                  onChange={(e) => setConfig({ ...config, port: parseInt(e.target.value) || 0 })}
                  margin="normal"
                  error={!!formErrors.port}
                  helperText={formErrors.port}
                />
              </Grid>
            </Grid>

            {serverType === 'plesk' ? (
              <>
                <TextField
                  fullWidth
                  label="API Key"
                  type="password"
                  value={config.api_key || ''}
                  onChange={(e) => setConfig({ ...config, api_key: e.target.value })}
                  margin="normal"
                  error={!!formErrors.api_key}
                  helperText={formErrors.api_key || 'Provide either API key or username/password'}
                />
                <TextField
                  fullWidth
                  label="Username (optional)"
                  value={config.username || ''}
                  onChange={(e) => setConfig({ ...config, username: e.target.value })}
                  margin="normal"
                />
                <TextField
                  fullWidth
                  label="Password (optional)"
                  type="password"
                  value={config.password || ''}
                  onChange={(e) => setConfig({ ...config, password: e.target.value })}
                  margin="normal"
                  error={!!formErrors.password}
                  helperText={formErrors.password}
                />
              </>
            ) : (
              <>
                <TextField
                  fullWidth
                  label="Company Database"
                  value={config.company_db || ''}
                  onChange={(e) => setConfig({ ...config, company_db: e.target.value })}
                  margin="normal"
                  required
                  error={!!formErrors.company_db}
                  helperText={formErrors.company_db || 'e.g., SBODEMOUS'}
                />
                <TextField
                  fullWidth
                  label="Username"
                  value={config.username || ''}
                  onChange={(e) => setConfig({ ...config, username: e.target.value })}
                  margin="normal"
                  required
                  error={!!formErrors.username}
                  helperText={formErrors.username}
                />
                <TextField
                  fullWidth
                  label="Password"
                  type="password"
                  value={config.password || ''}
                  onChange={(e) => setConfig({ ...config, password: e.target.value })}
                  margin="normal"
                  required
                  error={!!formErrors.password}
                  helperText={formErrors.password}
                />
              </>
            )}

            {testResult && (
              <Alert
                severity={testResult.success ? 'success' : testResult.requires_2fa ? 'warning' : 'error'}
                sx={{ mt: 2 }}
              >
                <Typography variant="body2">
                  {testResult.message}
                </Typography>
                {testResult.latency_ms && (
                  <Typography variant="caption" display="block">
                    Latency: {testResult.latency_ms}ms
                  </Typography>
                )}
                {testResult.error && (
                  <Typography variant="caption" display="block" color="error">
                    Error Code: {testResult.error.error_code}
                  </Typography>
                )}
              </Alert>
            )}
          </Box>
        </DialogContent>
        <DialogActions>
          <Button onClick={handleCloseDialog}>Cancel</Button>
          <Button
            variant="outlined"
            onClick={() => {
              // Test connection with current form data
              const testServer: Server = {
                id: 0,
                name: config.name,
                host: config.host,
                port: config.port,
                company_db: config.company_db,
                connection_status: 'unknown',
                is_active: true,
              };
              handleTestConnection(testServer, serverType);
            }}
            disabled={loading || testingServerId !== null}
          >
            Test Connection
          </Button>
          <Button variant="contained" onClick={handleSave} disabled={loading}>
            {editingServer ? 'Update' : 'Add'}
          </Button>
        </DialogActions>
      </Dialog>

      {/* Delete Confirmation Dialog */}
      <Dialog open={deleteDialogOpen} onClose={() => setDeleteDialogOpen(false)}>
        <DialogTitle>Confirm Delete</DialogTitle>
        <DialogContent>
          <Typography>
            Are you sure you want to delete this server? This action cannot be undone.
          </Typography>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setDeleteDialogOpen(false)}>Cancel</Button>
          <Button onClick={handleDeleteConfirm} color="error" variant="contained">
            Delete
          </Button>
        </DialogActions>
      </Dialog>
    </Box>
  );
};

export default ServersPage;
