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,
  Badge,
  Icon,
  Switch,
  FormHelperText,
  Select,
  Divider,
} from '@chakra-ui/react';
import { FiSettings, FiZap, FiSave, FiCloud, FiServer } from 'react-icons/fi';

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

interface WebDAVConfig {
  provider: 'webdav';
  url: string;
  username: string;
  password: string;
  basePath?: string;
}

type StorageConfig = S3Config | WebDAVConfig;

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

export const StorageConfiguration: React.FC = () => {
  const [config, setConfig] = useState<StorageConfig>({
    provider: 's3',
    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<StorageConfig | 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/storage');
      if (response.ok) {
        const data = await response.json();
        setCurrentConfig(data.config);
        
        // Handle masked passwords - don't set masked values as initial state
        const configWithEmptyPasswords = { ...data.config };
        if (configWithEmptyPasswords.provider === 'webdav' && configWithEmptyPasswords.password === '***') {
          configWithEmptyPasswords.password = '';
        }
        if (configWithEmptyPasswords.provider === 's3') {
          if (configWithEmptyPasswords.accessKeyId === '***') {
            configWithEmptyPasswords.accessKeyId = '';
          }
          if (configWithEmptyPasswords.secretAccessKey === '***') {
            configWithEmptyPasswords.secretAccessKey = '';
          }
        }
        
        setConfig(configWithEmptyPasswords);
      }
    } catch (error) {
      console.error('Error loading storage config:', error);
    } finally {
      setIsLoading(false);
    }
  };

  const handleProviderChange = (provider: 's3' | 'webdav') => {
    if (provider === 's3') {
      setConfig({
        provider: 's3',
        endpoint: '',
        region: 'us-east-1',
        accessKeyId: '',
        secretAccessKey: '',
        bucketName: '',
        useSSL: true,
      });
    } else {
      setConfig({
        provider: 'webdav',
        url: '',
        username: '',
        password: '',
        basePath: '/music-files',
      });
    }
  };

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

  const testConnection = async () => {
    setIsTesting(true);
    setTestResult(null);
    
    try {
      // For testing, merge current form state with existing config to preserve passwords
      const testConfig = { ...currentConfig, ...config };
      
      const response = await fetch('/api/config/storage/test', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(testConfig),
      });

      const result = await response.json();
      
      if (response.ok) {
        setTestResult({
          success: true,
          message: 'Connection successful!',
          details: result,
          provider: testConfig.provider,
        });
        toast({
          title: 'Connection Test Successful',
          description: `${testConfig.provider.toUpperCase()} connection is working properly`,
          status: 'success',
          duration: 5000,
          isClosable: true,
        });
      } else {
        setTestResult({
          success: false,
          message: result.error || 'Connection failed',
          details: result,
          provider: testConfig.provider,
        });
        toast({
          title: 'Connection Test Failed',
          description: result.error || `Failed to connect to ${testConfig.provider.toUpperCase()}`,
          status: 'error',
          duration: 5000,
          isClosable: true,
        });
      }
    } catch (error) {
      console.error('Error testing storage connection:', error);
      setTestResult({
        success: false,
        message: 'Network error or server unavailable',
        provider: testConfig.provider,
      });
      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 {
      // Always send the complete configuration
      const configToSave = { ...config };
      
      const response = await fetch('/api/config/storage', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(configToSave),
      });

      if (response.ok) {
        setCurrentConfig(config);
        toast({
          title: 'Configuration Saved',
          description: `${config.provider.toUpperCase()} 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 storage 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;
    
    // Create a copy of currentConfig with masked values replaced with empty strings for comparison
    const normalizedCurrentConfig = { ...currentConfig };
    if (normalizedCurrentConfig.provider === 'webdav' && normalizedCurrentConfig.password === '***') {
      normalizedCurrentConfig.password = '';
    }
    if (normalizedCurrentConfig.provider === 's3') {
      if (normalizedCurrentConfig.accessKeyId === '***') {
        normalizedCurrentConfig.accessKeyId = '';
      }
      if (normalizedCurrentConfig.secretAccessKey === '***') {
        normalizedCurrentConfig.secretAccessKey = '';
      }
    }
    
    return JSON.stringify(config) !== JSON.stringify(normalizedCurrentConfig);
  };

  const renderS3Config = () => (
    <VStack spacing={6} align="stretch">
      {/* Endpoint */}
      <FormControl>
        <FormLabel color="white">S3 Endpoint</FormLabel>
        <Input
          value={config.provider === 's3' ? 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.provider === 's3' ? 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.provider === 's3' ? 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.provider === 's3' ? 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.provider === 's3' ? 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.provider === 's3' ? config.useSSL : false}
          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>
  );

  const renderWebDAVConfig = () => (
    <VStack spacing={6} align="stretch">
      {/* URL */}
      <FormControl>
        <FormLabel color="white">WebDAV URL</FormLabel>
        <Input
          value={config.provider === 'webdav' ? config.url : ''}
          onChange={(e) => handleInputChange('url', e.target.value)}
          placeholder="https://your-nextcloud.com/remote.php/dav/files/username/"
          bg="gray.700"
          borderColor="gray.600"
          color="white"
          _placeholder={{ color: 'gray.400' }}
          _focus={{ borderColor: 'blue.400', boxShadow: 'none' }}
        />
        <FormHelperText color="gray.400">
          Your Nextcloud WebDAV URL (usually ends with /remote.php/dav/files/username/)
        </FormHelperText>
      </FormControl>

      {/* Username */}
      <FormControl>
        <FormLabel color="white">Username</FormLabel>
        <Input
          value={config.provider === 'webdav' ? config.username : ''}
          onChange={(e) => handleInputChange('username', e.target.value)}
          placeholder="Your Nextcloud username"
          bg="gray.700"
          borderColor="gray.600"
          color="white"
          _placeholder={{ color: 'gray.400' }}
          _focus={{ borderColor: 'blue.400', boxShadow: 'none' }}
        />
      </FormControl>

      {/* Password */}
      <FormControl>
        <FormLabel color="white">Password</FormLabel>
        <Input
          type="password"
          value={config.provider === 'webdav' ? config.password : ''}
          onChange={(e) => handleInputChange('password', e.target.value)}
          placeholder="Your Nextcloud password or app password"
          bg="gray.700"
          borderColor="gray.600"
          color="white"
          _placeholder={{ color: 'gray.400' }}
          _focus={{ borderColor: 'blue.400', boxShadow: 'none' }}
        />
        <FormHelperText color="gray.400">
          Use your Nextcloud password or create an app password for better security
        </FormHelperText>
      </FormControl>

      {/* Base Path */}
      <FormControl>
        <FormLabel color="white">Base Path (Optional)</FormLabel>
        <Input
          value={config.provider === 'webdav' ? config.basePath || '' : ''}
          onChange={(e) => handleInputChange('basePath', 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">
          Subfolder within your WebDAV storage where music files will be stored
        </FormHelperText>
      </FormControl>
    </VStack>
  );

  if (isLoading) {
    return (
      <Box p={8}>
        <VStack spacing={4} align="center">
          <Spinner size="xl" />
          <Text>Loading storage 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">Storage Configuration</Heading>
          </HStack>
          <Text color="gray.400">
            Configure your storage provider for music file storage and playback. Choose between S3-compatible storage or WebDAV (Nextcloud).
          </Text>
        </VStack>

        {/* Provider Selection */}
        <Card bg="gray.800" borderColor="gray.700">
          <CardHeader>
            <Heading size="md" color="white">Storage Provider</Heading>
          </CardHeader>
          <CardBody>
            <VStack spacing={4} align="stretch">
              <FormControl>
                <FormLabel color="white">Select Storage Provider</FormLabel>
                <Select
                  value={config.provider}
                  onChange={(e) => handleProviderChange(e.target.value as 's3' | 'webdav')}
                  bg="gray.700"
                  borderColor="gray.600"
                  color="white"
                  _focus={{ borderColor: 'blue.400', boxShadow: 'none' }}
                >
                  <option value="s3">S3-Compatible Storage (AWS S3, MinIO, etc.)</option>
                  <option value="webdav">WebDAV (Nextcloud, ownCloud, etc.)</option>
                </Select>
              </FormControl>

              <HStack spacing={4} align="center">
                <Icon 
                  as={config.provider === 's3' ? FiCloud : FiServer} 
                  w={5} h={5} 
                  color={config.provider === 's3' ? 'blue.400' : 'green.400'} 
                />
                <Text color="gray.400">
                  {config.provider === 's3' 
                    ? 'S3-compatible storage for scalable cloud storage'
                    : 'WebDAV for self-hosted solutions like Nextcloud'
                  }
                </Text>
              </HStack>
            </VStack>
          </CardBody>
        </Card>

        {/* Configuration Form */}
        <Card bg="gray.800" borderColor="gray.700">
          <CardHeader>
            <Heading size="md" color="white">
              {config.provider === 's3' ? 'S3 Configuration' : 'WebDAV Configuration'}
            </Heading>
          </CardHeader>
          <CardBody>
            {config.provider === 's3' ? renderS3Config() : renderWebDAVConfig()}
          </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 {config.provider.toUpperCase()} 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 {config.provider.toUpperCase()} 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={6} align="stretch">
              {/* S3 Help */}
              <Box>
                <Text color="gray.400" fontWeight="bold" mb={2}>
                  <Icon as={FiCloud} w={4} h={4} mr={2} />
                  S3-Compatible Storage
                </Text>
                <Box pl={4} borderLeft="2px" borderColor="gray.600">
                  <Text color="gray.400" fontSize="sm" mb={2}>
                    <strong>For AWS S3:</strong>
                  </Text>
                  <Text color="gray.400" fontSize="sm" pl={2}>
                    • 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>
                  
                  <Text color="gray.400" fontSize="sm" mt={3} mb={2}>
                    <strong>For MinIO (Local Development):</strong>
                  </Text>
                  <Text color="gray.400" fontSize="sm" pl={2}>
                    • 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>
              </Box>

              <Divider borderColor="gray.600" />

              {/* WebDAV Help */}
              <Box>
                <Text color="gray.400" fontWeight="bold" mb={2}>
                  <Icon as={FiServer} w={4} h={4} mr={2} />
                  WebDAV (Nextcloud/ownCloud)
                </Text>
                <Box pl={4} borderLeft="2px" borderColor="gray.600">
                  <Text color="gray.400" fontSize="sm" mb={2}>
                    <strong>For Nextcloud:</strong>
                  </Text>
                  <Text color="gray.400" fontSize="sm" pl={2}>
                    • URL: https://your-nextcloud.com/remote.php/dav/files/username/<br/>
                    • Username: Your Nextcloud username<br/>
                    • Password: Your Nextcloud password or app password<br/>
                    • Base Path: /music-files (optional subfolder)
                  </Text>
                  
                  <Text color="gray.400" fontSize="sm" mt={3} mb={2}>
                    <strong>For ownCloud:</strong>
                  </Text>
                  <Text color="gray.400" fontSize="sm" pl={2}>
                    • URL: https://your-owncloud.com/remote.php/dav/files/username/<br/>
                    • Username: Your ownCloud username<br/>
                    • Password: Your ownCloud password or app password<br/>
                    • Base Path: /music-files (optional subfolder)
                  </Text>
                  
                  <Text color="gray.400" fontSize="sm" mt={3}>
                    <strong>Note:</strong> For better security, create an app password in your Nextcloud/ownCloud settings instead of using your main password.
                  </Text>
                </Box>
              </Box>
            </VStack>
          </CardBody>
        </Card>
      </VStack>
    </Box>
  );
};
