import React, { useState } from 'react';
import {
  Box,
  Typography,
  Tab,
  Tabs,
  Paper,
  Grid,
  TextField,
  FormControlLabel,
  Switch,
  Button,
  CircularProgress,
  Alert,
  Divider,
  IconButton,
  Tooltip,
  InputAdornment,
  Card,
  CardContent,
  CardHeader,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  MenuItem,
  Select,
  FormControl,
  InputLabel
} from '@mui/material';
import {
  Save as SaveIcon,
  Refresh as RefreshIcon,
  Visibility as VisibilityIcon,
  VisibilityOff as VisibilityOffIcon,
  Add as AddIcon,
  Delete as DeleteIcon
} from '@mui/icons-material';
import { useAdminSettings, useUpdateSettings, useUpdateSetting, useDeleteSetting } from '../../hooks/settingsAdminHooks';

function TabPanel({ children, value, index, ...other }) {
  return (
    <div
      role="tabpanel"
      hidden={value !== index}
      id={`settings-tabpanel-${index}`}
      aria-labelledby={`settings-tab-${index}`}
      {...other}
    >
      {value === index && (
        <Box sx={{ p: 3 }}>
          {children}
        </Box>
      )}
    </div>
  );
}

const AdminSettingsPage = () => {
  const [activeTab, setActiveTab] = useState(0);
  const [formData, setFormData] = useState({});
  const [showPasswords, setShowPasswords] = useState({});
  const [newSetting, setNewSetting] = useState({
    key: '',
    value: '',
    category: ''
  });
  const [showNewSettingForm, setShowNewSettingForm] = useState(false);
  const [settingToDelete, setSettingToDelete] = useState(null);
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  
  // Fetch settings
  const { data: settingsData, isLoading, error, refetch } = useAdminSettings();
  
  // Update settings mutation
  const updateSettings = useUpdateSettings();
  const updateSetting = useUpdateSetting();
  const deleteSetting = useDeleteSetting();
  
  // Handle tab change
  const handleTabChange = (event, newValue) => {
    setActiveTab(newValue);
  };
  
  // Initialize form data when settings are loaded
  React.useEffect(() => {
    if (settingsData) {
      const initialData = {};
      Object.keys(settingsData).forEach(category => {
        settingsData[category].forEach(setting => {
          initialData[setting.key] = setting.value;
        });
      });
      setFormData(initialData);
    }
  }, [settingsData]);
  
  // Handle form input changes
  const handleChange = (e) => {
    const { name, value, checked, type } = e.target;
    setFormData({
      ...formData,
      [name]: type === 'checkbox' ? checked.toString() : value
    });
  };
  
  // Toggle password visibility
  const togglePasswordVisibility = (key) => {
    setShowPasswords({
      ...showPasswords,
      [key]: !showPasswords[key]
    });
  };
  
  // Handle new setting form changes
  const handleNewSettingChange = (e) => {
    const { name, value } = e.target;
    setNewSetting({
      ...newSetting,
      [name]: value
    });
  };
  
  // Add new setting
  const handleAddNewSetting = async () => {
    if (!newSetting.key || !newSetting.category) {
      return;
    }
    
    try {
      await updateSetting.mutateAsync({
        key: newSetting.key,
        value: newSetting.value,
        category: newSetting.category
      });
      
      setNewSetting({
        key: '',
        value: '',
        category: ''
      });
      setShowNewSettingForm(false);
      
      // Refresh settings data
      refetch();
    } catch (error) {
      console.error('Failed to add new setting:', error);
    }
  };
  
  // Open delete setting dialog
  const handleOpenDeleteDialog = (setting) => {
    setSettingToDelete(setting);
    setDeleteDialogOpen(true);
  };
  
  // Confirm delete setting
  const handleConfirmDelete = async () => {
    if (settingToDelete) {
      try {
        await deleteSetting.mutateAsync(settingToDelete.key);
        setDeleteDialogOpen(false);
        setSettingToDelete(null);
        
        // Refresh settings data
        refetch();
      } catch (error) {
        console.error('Failed to delete setting:', error);
      }
    }
  };
  
  // Save all settings
  const handleSaveSettings = async () => {
    const settingsToUpdate = [];
    
    if (settingsData) {
      // Prepare settings array for batch update
      Object.keys(settingsData).forEach(category => {
        settingsData[category].forEach(setting => {
          if (formData[setting.key] !== setting.value) {
            settingsToUpdate.push({
              key: setting.key,
              value: formData[setting.key],
              category: setting.category
            });
          }
        });
      });
      
      if (settingsToUpdate.length > 0) {
        try {
          await updateSettings.mutateAsync(settingsToUpdate);
        } catch (error) {
          console.error('Failed to update settings:', error);
        }
      }
    }
  };
  
  // Loading state
  if (isLoading) {
    return (
      <Box sx={{ display: 'flex', justifyContent: 'center', py: 4 }}>
        <CircularProgress />
      </Box>
    );
  }
  
  // Error state
  if (error) {
    return (
      <Alert severity="error" sx={{ my: 2 }}>
        Error loading settings: {error.message}
      </Alert>
    );
  }
  
  // Get category names for tabs
  const categories = settingsData ? Object.keys(settingsData) : [];
  
  return (
    <Box>
      <Typography variant="h4" component="h1" gutterBottom>
        System Settings
      </Typography>
      
      <Paper sx={{ mb: 4 }}>
        <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
          <Tabs 
            value={activeTab} 
            onChange={handleTabChange} 
            aria-label="settings tabs"
            variant="scrollable"
            scrollButtons="auto"
          >
            {categories.map((category, index) => (
              <Tab key={category} label={category.charAt(0).toUpperCase() + category.slice(1)} id={`settings-tab-${index}`} />
            ))}
          </Tabs>
        </Box>
        
        {categories.map((category, index) => (
          <TabPanel key={category} value={activeTab} index={index}>
            <Box sx={{ mb: 2, display: 'flex', justifyContent: 'space-between' }}>
              <Typography variant="h6" gutterBottom>
                {category.charAt(0).toUpperCase() + category.slice(1)} Settings
              </Typography>
              <Button 
                variant="outlined" 
                startIcon={<AddIcon />}
                onClick={() => {
                  setNewSetting({...newSetting, category});
                  setShowNewSettingForm(true);
                }}
              >
                Add Setting
              </Button>
            </Box>
            
            {category === 'payment' && <Grid container spacing={3} sx={{ mb: 4 }}>
              <Grid item xs={12}>
                <FormControlLabel
                  control={
                    <Switch
                      checked={formData['stripe_enabled'] === 'true'}
                      onChange={handleChange}
                      name="stripe_enabled"
                      color="primary"
                    />
                  }
                  label={formData['stripe_enabled'] === 'true' ? 'Stripe is Enabled' : 'Stripe is Disabled'}
                />
              </Grid>
              
              <Grid item xs={12}>
                <TextField
                  fullWidth
                  name="stripe_public_key"
                  label="Stripe Public Key"
                  value={formData['stripe_public_key'] || ''}
                  onChange={handleChange}
                  variant="outlined"
                  helperText="Publishable key that starts with 'pk_test_' or 'pk_live_'"
                />
              </Grid>
              
              <Grid item xs={12}>
                <TextField
                  fullWidth
                  name="stripe_secret_key"
                  label="Stripe Secret Key"
                  type={showPasswords['stripe_secret_key'] ? 'text' : 'password'}
                  value={formData['stripe_secret_key'] || ''}
                  onChange={handleChange}
                  variant="outlined"
                  helperText="Secret key that starts with 'sk_test_' or 'sk_live_'"
                  InputProps={{
                    endAdornment: (
                      <InputAdornment position="end">
                        <IconButton
                          onClick={() => togglePasswordVisibility('stripe_secret_key')}
                          edge="end"
                        >
                          {showPasswords['stripe_secret_key'] ? <VisibilityOffIcon /> : <VisibilityIcon />}
                        </IconButton>
                      </InputAdornment>
                    )
                  }}
                />
              </Grid>
              
              <Grid item xs={12}>
                <TextField
                  fullWidth
                  name="stripe_webhook_secret"
                  label="Stripe Webhook Secret"
                  type={showPasswords['stripe_webhook_secret'] ? 'text' : 'password'}
                  value={formData['stripe_webhook_secret'] || ''}
                  onChange={handleChange}
                  variant="outlined"
                  helperText="Webhook signing secret that starts with 'whsec_'"
                  InputProps={{
                    endAdornment: (
                      <InputAdornment position="end">
                        <IconButton
                          onClick={() => togglePasswordVisibility('stripe_webhook_secret')}
                          edge="end"
                        >
                          {showPasswords['stripe_webhook_secret'] ? <VisibilityOffIcon /> : <VisibilityIcon />}
                        </IconButton>
                      </InputAdornment>
                    )
                  }}
                />
              </Grid>
              
              <Grid item xs={12}>
                <Alert severity="info">
                  <Typography variant="body2">
                    To set up Stripe integration:
                  </Typography>
                  <ol>
                    <li>Create a Stripe account at <a href="https://stripe.com" target="_blank" rel="noopener">stripe.com</a></li>
                    <li>Obtain your API keys from the Stripe Dashboard</li>
                    <li>Set up a webhook endpoint at: <code>{`${window.location.protocol}//${window.location.host}/api/payment/webhook`}</code></li>
                    <li>Copy the webhook signing secret here</li>
                  </ol>
                </Alert>
              </Grid>
            </Grid>}
            <Grid container spacing={3}>
              {settingsData[category].map((setting) => {
                if(setting.key.toUpperCase().includes("STRIPE"))
                  return null

                return (
                  <Grid item xs={12} md={6} key={setting.key}> 
                    <Card variant="outlined">
                      <CardContent>
                        <Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 2 }}>
                          <Typography variant="subtitle1" fontWeight="bold">
                            {setting.key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}
                          </Typography>
                          <Tooltip title="Delete Setting">
                            <IconButton 
                              color="error" 
                              size="small"
                              onClick={() => handleOpenDeleteDialog(setting)}
                            >
                              <DeleteIcon />
                            </IconButton>
                          </Tooltip>
                        </Box>
                        
                        {setting.key.includes('password') || setting.key.includes('secret') || setting.key.includes('key') ? (
                          <TextField
                            fullWidth
                            name={setting.key}
                            label="Value"
                            type={showPasswords[setting.key] ? 'text' : 'password'}
                            value={formData[setting.key] || ''}
                            onChange={handleChange}
                            variant="outlined"
                            InputProps={{
                              endAdornment: (
                                <InputAdornment position="end">
                                  <IconButton
                                    onClick={() => togglePasswordVisibility(setting.key)}
                                    edge="end"
                                  >
                                    {showPasswords[setting.key] ? <VisibilityOffIcon /> : <VisibilityIcon />}
                                  </IconButton>
                                </InputAdornment>
                              )
                            }}
                          />
                        ) : setting.key.includes('enabled') || setting.key.includes('active') ? (
                          <FormControlLabel
                            control={
                              <Switch
                                checked={formData[setting.key] === 'true'}
                                onChange={handleChange}
                                name={setting.key}
                                color="primary"
                              />
                            }
                            label={formData[setting.key] === 'true' ? 'Enabled' : 'Disabled'}
                          />
                        ) : (
                          <TextField
                            fullWidth
                            name={setting.key}
                            label="Value"
                            value={formData[setting.key] || ''}
                            onChange={handleChange}
                            variant="outlined"
                          />
                        )}
                        
                        <Typography variant="caption" color="text.secondary" sx={{ mt: 1, display: 'block' }}>
                          Last updated: {new Date(setting.updated_at).toLocaleString()}
                        </Typography>
                      </CardContent>
                    </Card>
                  </Grid>
                )
              }
              )}
            </Grid>
          </TabPanel>
        ))}
        
        <Box sx={{ display: 'flex', justifyContent: 'flex-end', p: 2 }}>
          <Button
            variant="outlined"
            startIcon={<RefreshIcon />}
            onClick={refetch}
            sx={{ mr: 2 }}
          >
            Refresh
          </Button>
          <Button
            variant="contained"
            startIcon={<SaveIcon />}
            onClick={handleSaveSettings}
            disabled={updateSettings.isLoading}
          >
            {updateSettings.isLoading ? <CircularProgress size={24} /> : 'Save Changes'}
          </Button>
        </Box>
      </Paper>
      
      {/* New Setting Dialog */}
      <Dialog open={showNewSettingForm} onClose={() => setShowNewSettingForm(false)} maxWidth="sm" fullWidth>
        <DialogTitle>Add New Setting</DialogTitle>
        <DialogContent>
          <Box sx={{ pt: 1 }}>
            <FormControl fullWidth margin="normal">
              <InputLabel id="category-label">Category</InputLabel>
              <Select
                labelId="category-label"
                name="category"
                value={newSetting.category}
                onChange={handleNewSettingChange}
                label="Category"
              >
                {categories.map((category) => (
                  <MenuItem key={category} value={category}>
                    {category.charAt(0).toUpperCase() + category.slice(1)}
                  </MenuItem>
                ))}
                <MenuItem value="new">New Category...</MenuItem>
              </Select>
            </FormControl>
            
            {newSetting.category === 'new' && (
              <TextField
                fullWidth
                margin="normal"
                name="category"
                label="New Category Name"
                value={newSetting.customCategory || ''}
                onChange={(e) => setNewSetting({...newSetting, customCategory: e.target.value})}
              />
            )}
            
            <TextField
              fullWidth
              margin="normal"
              name="key"
              label="Setting Key"
              value={newSetting.key}
              onChange={handleNewSettingChange}
              helperText="Use lowercase letters, numbers and underscores (e.g., stripe_public_key)"
            />
            
            <TextField
              fullWidth
              margin="normal"
              name="value"
              label="Setting Value"
              value={newSetting.value}
              onChange={handleNewSettingChange}
              multiline={newSetting.key.includes('description') || newSetting.value.length > 50}
              rows={newSetting.key.includes('description') ? 4 : 1}
            />
          </Box>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setShowNewSettingForm(false)}>Cancel</Button>
          <Button 
            onClick={handleAddNewSetting} 
            variant="contained" 
            disabled={!newSetting.key || !(newSetting.category || newSetting.customCategory) || updateSetting.isLoading}
          >
            {updateSetting.isLoading ? <CircularProgress size={24} /> : 'Add Setting'}
          </Button>
        </DialogActions>
      </Dialog>
      
      {/* Delete Setting Dialog */}
      <Dialog open={deleteDialogOpen} onClose={() => setDeleteDialogOpen(false)}>
        <DialogTitle>Confirm Deletion</DialogTitle>
        <DialogContent>
          <Typography>
            Are you sure you want to delete the setting "{settingToDelete?.key}"?
            This action cannot be undone.
          </Typography>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setDeleteDialogOpen(false)}>Cancel</Button>
          <Button 
            onClick={handleConfirmDelete} 
            color="error" 
            variant="contained"
            disabled={deleteSetting.isLoading}
          >
            {deleteSetting.isLoading ? <CircularProgress size={24} /> : 'Delete'}
          </Button>
        </DialogActions>
      </Dialog>
    </Box>
  );
};

export default AdminSettingsPage;