import React, { useState, useEffect } from 'react';
import {
  Box,
  VStack,
  HStack,
  Text,
  Heading,
  FormControl,
  FormLabel,
  Input,
  Button,
  useToast,
  Alert,
  AlertIcon,
  AlertTitle,
  AlertDescription,
  Card,
  CardBody,
  CardHeader,
  Spinner,
  Divider,
  Badge,
  Icon,
  Switch,
  FormHelperText,
} from '@chakra-ui/react';
import { FiCheck, FiX, FiSettings, FiZap, FiSave } from 'react-icons/fi';

interface S3Config {
  endpoint: string;
  region: string;
  accessKeyId: string;
  secretAccessKey: string;
  bucketName: string;
  useSSL: boolean;
}

interface TestResult {
  success: boolean;
  message: string;
  details?: any;
}

export const S3Configuration: React.FC = () => {
  const [config, setConfig] = useState<S3Config>({
    endpoint: '',
    region: 'us-east-1',
    accessKeyId: '',
    secretAccessKey: '',
    bucketName: '',
    useSSL: true,
  });
  
  const [isLoading, setIsLoading] = useState(false);
  const [isTesting, setIsTesting] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [testResult, setTestResult] = useState<TestResult | null>(null);
  const [currentConfig, setCurrentConfig] = useState<S3Config | null>(null);
  const toast = useToast();

  // Load current configuration on component mount
  useEffect(() => {
    loadCurrentConfig();
  }, []);

  const loadCurrentConfig = async () => {
    setIsLoading(true);
    try {
      const response = await fetch('/api/config/s3');
      if (response.ok) {
        const data = await response.json();
        setCurrentConfig(data.config);
        setConfig(data.config);
      }
    } catch (error) {
      console.error('Error loading S3 config:', error);
    } finally {
      setIsLoading(false);
    }
  };

  const handleInputChange = (field: keyof S3Config, value: string | boolean) => {
    setConfig(prev => ({
      ...prev,
      [field]: value,
    }));
  };

  const testConnection = async () => {
    setIsTesting(true);
    setTestResult(null);
    
    try {
      const response = await fetch('/api/config/s3/test', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(config),
      });

      const result = await response.json();
      
      if (response.ok) {
        setTestResult({
          success: true,
          message: 'Connection successful!',
          details: result,
        });
        toast({
          title: 'Connection Test Successful',
          description: 'S3 bucket connection is working properly',
          status: 'success',
          duration: 5000,
          isClosable: true,
        });
      } else {
        setTestResult({
          success: false,
          message: result.error || 'Connection failed',
          details: result,
        });
        toast({
          title: 'Connection Test Failed',
          description: result.error || 'Failed to connect to S3 bucket',
          status: 'error',
          duration: 5000,
          isClosable: true,
        });
      }
    } catch (error) {
      console.error('Error testing S3 connection:', error);
      setTestResult({
        success: false,
        message: 'Network error or server unavailable',
      });
      toast({
        title: 'Connection Test Failed',
        description: 'Network error or server unavailable',
        status: 'error',
        duration: 5000,
        isClosable: true,
      });
    } finally {
      setIsTesting(false);
    }
  };

  const saveConfiguration = async () => {
    setIsSaving(true);
    
    try {
      const response = await fetch('/api/config/s3', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(config),
      });

      if (response.ok) {
        setCurrentConfig(config);
        toast({
          title: 'Configuration Saved',
          description: 'S3 configuration has been saved successfully',
          status: 'success',
          duration: 3000,
          isClosable: true,
        });
      } else {
        const error = await response.json();
        throw new Error(error.error || 'Failed to save configuration');
      }
    } catch (error) {
      console.error('Error saving S3 config:', error);
      toast({
        title: 'Save Failed',
        description: error instanceof Error ? error.message : 'Failed to save configuration',
        status: 'error',
        duration: 5000,
        isClosable: true,
      });
    } finally {
      setIsSaving(false);
    }
  };

  const hasChanges = () => {
    if (!currentConfig) return true;
    return JSON.stringify(config) !== JSON.stringify(currentConfig);
  };

  if (isLoading) {
    return (
      <Box p={8}>
        <VStack spacing={4} align="center">
          <Spinner size="xl" />
          <Text>Loading S3 configuration...</Text>
        </VStack>
      </Box>
    );
  }

  return (
    <Box p={8} maxW="800px" mx="auto">
      <VStack spacing={8} align="stretch">
        {/* Header */}
        <VStack spacing={2} align="start">
          <HStack spacing={3}>
            <Icon as={FiSettings} w={6} h={6} color="blue.400" />
            <Heading size="lg" color="white">S3 Configuration</Heading>
          </HStack>
          <Text color="gray.400">
            Configure your S3-compatible storage connection for music file storage and playback.
          </Text>
        </VStack>

        {/* Configuration Form */}
        <Card bg="gray.800" borderColor="gray.700">
          <CardHeader>
            <Heading size="md" color="white">Connection Settings</Heading>
          </CardHeader>
          <CardBody>
            <VStack spacing={6} align="stretch">
              {/* Endpoint */}
              <FormControl>
                <FormLabel color="white">S3 Endpoint</FormLabel>
                <Input
                  value={config.endpoint}
                  onChange={(e) => handleInputChange('endpoint', e.target.value)}
                  placeholder="https://s3.amazonaws.com or http://localhost:9000 for MinIO"
                  bg="gray.700"
                  borderColor="gray.600"
                  color="white"
                  _placeholder={{ color: 'gray.400' }}
                  _focus={{ borderColor: 'blue.400', boxShadow: 'none' }}
                />
                <FormHelperText color="gray.400">
                  For AWS S3, use: https://s3.amazonaws.com. For MinIO: http://localhost:9000
                </FormHelperText>
              </FormControl>

              {/* Region */}
              <FormControl>
                <FormLabel color="white">Region</FormLabel>
                <Input
                  value={config.region}
                  onChange={(e) => handleInputChange('region', e.target.value)}
                  placeholder="us-east-1"
                  bg="gray.700"
                  borderColor="gray.600"
                  color="white"
                  _placeholder={{ color: 'gray.400' }}
                  _focus={{ borderColor: 'blue.400', boxShadow: 'none' }}
                />
                <FormHelperText color="gray.400">
                  AWS region (e.g., us-east-1, eu-west-1) or 'us-east-1' for MinIO
                </FormHelperText>
              </FormControl>

              {/* Access Key */}
              <FormControl>
                <FormLabel color="white">Access Key ID</FormLabel>
                <Input
                  value={config.accessKeyId}
                  onChange={(e) => handleInputChange('accessKeyId', e.target.value)}
                  placeholder="Your S3 access key"
                  bg="gray.700"
                  borderColor="gray.600"
                  color="white"
                  _placeholder={{ color: 'gray.400' }}
                  _focus={{ borderColor: 'blue.400', boxShadow: 'none' }}
                />
              </FormControl>

              {/* Secret Key */}
              <FormControl>
                <FormLabel color="white">Secret Access Key</FormLabel>
                <Input
                  type="password"
                  value={config.secretAccessKey}
                  onChange={(e) => handleInputChange('secretAccessKey', e.target.value)}
                  placeholder="Your S3 secret key"
                  bg="gray.700"
                  borderColor="gray.600"
                  color="white"
                  _placeholder={{ color: 'gray.400' }}
                  _focus={{ borderColor: 'blue.400', boxShadow: 'none' }}
                />
              </FormControl>

              {/* Bucket Name */}
              <FormControl>
                <FormLabel color="white">Bucket Name</FormLabel>
                <Input
                  value={config.bucketName}
                  onChange={(e) => handleInputChange('bucketName', e.target.value)}
                  placeholder="music-files"
                  bg="gray.700"
                  borderColor="gray.600"
                  color="white"
                  _placeholder={{ color: 'gray.400' }}
                  _focus={{ borderColor: 'blue.400', boxShadow: 'none' }}
                />
                <FormHelperText color="gray.400">
                  The S3 bucket where music files will be stored
                </FormHelperText>
              </FormControl>

              {/* Use SSL */}
              <FormControl display="flex" alignItems="center">
                <FormLabel htmlFor="use-ssl" mb="0" color="white">
                  Use SSL/TLS
                </FormLabel>
                <Switch
                  id="use-ssl"
                  isChecked={config.useSSL}
                  onChange={(e) => handleInputChange('useSSL', e.target.checked)}
                  colorScheme="blue"
                />
                <FormHelperText color="gray.400" ml={3}>
                  Enable for HTTPS connections (recommended for production)
                </FormHelperText>
              </FormControl>
            </VStack>
          </CardBody>
        </Card>

        {/* Test Connection */}
        <Card bg="gray.800" borderColor="gray.700">
          <CardHeader>
            <HStack spacing={3}>
              <Icon as={FiZap} w={5} h={5} color="blue.400" />
              <Heading size="md" color="white">Test Connection</Heading>
            </HStack>
          </CardHeader>
          <CardBody>
            <VStack spacing={4} align="stretch">
              <Text color="gray.400">
                Test your S3 configuration to ensure it's working properly before saving.
              </Text>
              
              <Button
                leftIcon={isTesting ? <Spinner size="sm" /> : <FiZap />}
                onClick={testConnection}
                isLoading={isTesting}
                loadingText="Testing..."
                colorScheme="blue"
                _hover={{ bg: "blue.700" }}
              >
                Test Connection
              </Button>

              {testResult && (
                <Alert
                  status={testResult.success ? 'success' : 'error'}
                  variant="subtle"
                  flexDirection="column"
                  alignItems="center"
                  justifyContent="center"
                  textAlign="center"
                  height="auto"
                  py={4}
                >
                  <AlertIcon boxSize="24px" />
                  <AlertTitle mt={2} mb={1} fontSize="lg">
                    {testResult.success ? 'Connection Successful' : 'Connection Failed'}
                  </AlertTitle>
                  <AlertDescription maxWidth="sm">
                    {testResult.message}
                  </AlertDescription>
                  {testResult.details && (
                    <Box mt={2} p={3} bg="gray.700" borderRadius="md" fontSize="sm">
                      <Text color="gray.300" fontWeight="bold">Details:</Text>
                      <Text color="gray.400" fontFamily="mono">
                        {JSON.stringify(testResult.details, null, 2)}
                      </Text>
                    </Box>
                  )}
                </Alert>
              )}
            </VStack>
          </CardBody>
        </Card>

        {/* Save Configuration */}
        <Card bg="gray.800" borderColor="gray.700">
          <CardHeader>
            <HStack spacing={3}>
              <Icon as={FiSave} w={5} h={5} color="green.400" />
              <Heading size="md" color="white">Save Configuration</Heading>
            </HStack>
          </CardHeader>
          <CardBody>
            <VStack spacing={4} align="stretch">
              <Text color="gray.400">
                Save your S3 configuration to use it for music file storage and playback.
              </Text>
              
              <HStack spacing={3}>
                <Button
                  leftIcon={isSaving ? <Spinner size="sm" /> : <FiSave />}
                  onClick={saveConfiguration}
                  isLoading={isSaving}
                  loadingText="Saving..."
                  colorScheme="green"
                  isDisabled={!hasChanges()}
                  _hover={{ bg: "green.700" }}
                >
                  Save Configuration
                </Button>
                
                {currentConfig && (
                  <Badge colorScheme="blue" variant="subtle" bg="blue.900" color="blue.200">
                    Configuration Loaded
                  </Badge>
                )}
              </HStack>

              {!hasChanges() && currentConfig && (
                <Alert status="info" variant="subtle">
                  <AlertIcon />
                  <Text color="gray.300">No changes to save</Text>
                </Alert>
              )}
            </VStack>
          </CardBody>
        </Card>

        {/* Help Section */}
        <Card bg="gray.800" borderColor="gray.700">
          <CardHeader>
            <Heading size="md" color="white">Configuration Help</Heading>
          </CardHeader>
          <CardBody>
            <VStack spacing={4} align="stretch">
              <Text color="gray.400">
                <strong>For AWS S3:</strong>
              </Text>
              <Box pl={4} borderLeft="2px" borderColor="gray.600">
                <Text color="gray.400" fontSize="sm">
                  • Endpoint: https://s3.amazonaws.com<br/>
                  • Region: Your AWS region (e.g., us-east-1)<br/>
                  • Access Key: Your AWS access key<br/>
                  • Secret Key: Your AWS secret key<br/>
                  • Bucket: Your S3 bucket name
                </Text>
              </Box>

              <Text color="gray.400" mt={4}>
                <strong>For MinIO (Local Development):</strong>
              </Text>
              <Box pl={4} borderLeft="2px" borderColor="gray.600">
                <Text color="gray.400" fontSize="sm">
                  • Endpoint: http://localhost:9000<br/>
                  • Region: us-east-1<br/>
                  • Access Key: minioadmin<br/>
                  • Secret Key: minioadmin<br/>
                  • Bucket: Create a bucket named 'music-files'
                </Text>
              </Box>

              <Text color="gray.400" mt={4}>
                <strong>For Other S3-Compatible Services:</strong>
              </Text>
              <Box pl={4} borderLeft="2px" borderColor="gray.600">
                <Text color="gray.400" fontSize="sm">
                  • Endpoint: Your service's endpoint URL<br/>
                  • Region: Your service's region<br/>
                  • Access Key: Your service access key<br/>
                  • Secret Key: Your service secret key<br/>
                  • Bucket: Your bucket name
                </Text>
              </Box>
            </VStack>
          </CardBody>
        </Card>
      </VStack>
    </Box>
  );
}; 