import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { useToast } from '@/hooks/useToast';
import { useKubectl, useNamespacesInfo } from '@/hooks/useKubectl';
import { useGlobalNamespace } from '@/hooks/useGlobalNamespace';
import {
  ArrowLeft,
  Globe,
  Download,
  CheckCircle,
  Loader2,
  Settings,
  AlertCircle,
  Eye,
  EyeOff,
  FileText,
  Code,
  Database,
} from 'lucide-react';

interface ParsedUrlData {
  key: string;
  value: string;
  isValid: boolean;
  error?: string;
}

function ConfigMapImportUrlPage() {
  const navigate = useNavigate();
  const { showToast } = useToast();
  const { executeCommand } = useKubectl();
  const { namespaces } = useNamespacesInfo();
  const { selectedNamespace: globalNamespace } = useGlobalNamespace();

  const [configMapName, setConfigMapName] = useState('');
  const [selectedNamespace, setSelectedNamespace] = useState(() => {
    return globalNamespace === 'all' ? 'default' : globalNamespace;
  });
  const [url, setUrl] = useState('');
  const [fileFormat, setFileFormat] = useState<'auto' | 'env' | 'json' | 'yaml' | 'properties' | 'ini'>('auto');
  const [fetchedContent, setFetchedContent] = useState('');
  const [parsedData, setParsedData] = useState<ParsedUrlData[]>([]);
  const [showPreview, setShowPreview] = useState(false);
  const [creating, setCreating] = useState(false);
  const [fetching, setFetching] = useState(false);

  const detectFileFormat = (url: string, content: string): 'env' | 'json' | 'yaml' | 'properties' | 'ini' => {
    // First, try to detect from URL extension
    const urlLower = url.toLowerCase();
    if (urlLower.includes('.env')) return 'env';
    if (urlLower.includes('.json')) return 'json';
    if (urlLower.includes('.yaml') || urlLower.includes('.yml')) return 'yaml';
    if (urlLower.includes('.properties')) return 'properties';
    if (urlLower.includes('.ini') || urlLower.includes('.cfg')) return 'ini';

    // Try to detect from content
    const lines = content.split('\n').filter(line => line.trim() && !line.trim().startsWith('#'));
    
    // Check for JSON
    if (content.trim().startsWith('{') && content.trim().endsWith('}')) {
      try {
        JSON.parse(content);
        return 'json';
      } catch {
        // Not valid JSON
      }
    }

    // Check for YAML (looks for key: value pattern)
    if (lines.some(line => /^[a-zA-Z_][a-zA-Z0-9_]*:\s*/.test(line.trim()))) {
      return 'yaml';
    }

    // Check for INI (looks for [section] headers)
    if (lines.some(line => /^\[[^\]]+\]$/.test(line.trim()))) {
      return 'ini';
    }

    // Check for properties (key=value with dots in keys)
    if (lines.some(line => /^[a-zA-Z_][a-zA-Z0-9_.]*\s*=/.test(line.trim()))) {
      return 'properties';
    }

    // Default to env format
    return 'env';
  };

  const parseContent = (content: string, format: 'env' | 'json' | 'yaml' | 'properties' | 'ini'): ParsedUrlData[] => {
    const data: ParsedUrlData[] = [];

    try {
      switch (format) {
        case 'env':
          return parseEnvContent(content);
        case 'json':
          return parseJsonContent(content);
        case 'yaml':
          return parseYamlContent(content);
        case 'properties':
          return parsePropertiesContent(content);
        case 'ini':
          return parseIniContent(content);
        default:
          return [];
      }
    } catch (error) {
      return [{
        key: 'parse-error',
        value: '',
        isValid: false,
        error: `Erro ao parsear conteúdo: ${error instanceof Error ? error.message : 'Erro desconhecido'}`,
      }];
    }
  };

  const parseEnvContent = (content: string): ParsedUrlData[] => {
    const lines = content.split('\n');
    const data: ParsedUrlData[] = [];

    lines.forEach((line) => {
      const trimmedLine = line.trim();
      if (!trimmedLine || trimmedLine.startsWith('#')) return;

      const equalsIndex = trimmedLine.indexOf('=');
      if (equalsIndex === -1) return;

      const key = trimmedLine.substring(0, equalsIndex).trim();
      const value = trimmedLine.substring(equalsIndex + 1).trim().replace(/^[\"']|[\"']$/g, '');

      if (key && /^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
        data.push({ key, value, isValid: true });
      } else {
        data.push({ key, value, isValid: false, error: 'Nome de variável inválido' });
      }
    });

    return data;
  };

  const parseJsonContent = (content: string): ParsedUrlData[] => {
    const parsed = JSON.parse(content);
    const flattened = flattenObject(parsed);
    const data: ParsedUrlData[] = [];

    for (const [key, value] of Object.entries(flattened)) {
      const stringValue = typeof value === 'string' ? value : JSON.stringify(value);
      if (/^[a-zA-Z_][a-zA-Z0-9_.-]*$/.test(key)) {
        data.push({ key, value: stringValue, isValid: true });
      } else {
        data.push({ key, value: stringValue, isValid: false, error: 'Nome de chave inválido' });
      }
    }

    return data;
  };

  const parseYamlContent = (content: string): ParsedUrlData[] => {
    // Simple YAML parser - basic implementation
    const lines = content.split('\n');
    const data: ParsedUrlData[] = [];
    let currentPath: string[] = [];

    lines.forEach((line) => {
      const trimmedLine = line.trim();
      if (!trimmedLine || trimmedLine.startsWith('#')) return;

      const indent = line.length - line.trimStart().length;
      const level = Math.floor(indent / 2);

      const colonIndex = trimmedLine.indexOf(':');
      if (colonIndex === -1) return;

      const key = trimmedLine.substring(0, colonIndex).trim();
      const value = trimmedLine.substring(colonIndex + 1).trim();

      // Adjust path based on indentation
      currentPath = currentPath.slice(0, level);
      const fullKey = [...currentPath, key].join('.');

      if (value && value !== '') {
        if (/^[a-zA-Z_][a-zA-Z0-9_.-]*$/.test(fullKey)) {
          data.push({ key: fullKey, value, isValid: true });
        } else {
          data.push({ key: fullKey, value, isValid: false, error: 'Nome de chave inválido' });
        }
      } else {
        currentPath.push(key);
      }
    });

    return data;
  };

  const parsePropertiesContent = (content: string): ParsedUrlData[] => {
    const lines = content.split('\n');
    const data: ParsedUrlData[] = [];

    lines.forEach((line) => {
      const trimmedLine = line.trim();
      if (!trimmedLine || trimmedLine.startsWith('#') || trimmedLine.startsWith('!')) return;

      const equalsIndex = trimmedLine.indexOf('=');
      if (equalsIndex === -1) return;

      const key = trimmedLine.substring(0, equalsIndex).trim();
      const value = trimmedLine.substring(equalsIndex + 1).trim();

      if (/^[a-zA-Z_][a-zA-Z0-9_.-]*$/.test(key)) {
        data.push({ key, value, isValid: true });
      } else {
        data.push({ key, value, isValid: false, error: 'Nome de chave inválido' });
      }
    });

    return data;
  };

  const parseIniContent = (content: string): ParsedUrlData[] => {
    const lines = content.split('\n');
    const data: ParsedUrlData[] = [];
    let currentSection = '';

    lines.forEach((line) => {
      const trimmedLine = line.trim();
      if (!trimmedLine || trimmedLine.startsWith(';') || trimmedLine.startsWith('#')) return;

      if (trimmedLine.startsWith('[') && trimmedLine.endsWith(']')) {
        currentSection = trimmedLine.slice(1, -1);
        return;
      }

      const equalsIndex = trimmedLine.indexOf('=');
      if (equalsIndex === -1) return;

      const key = trimmedLine.substring(0, equalsIndex).trim();
      const value = trimmedLine.substring(equalsIndex + 1).trim();
      const fullKey = currentSection ? `${currentSection}.${key}` : key;

      if (/^[a-zA-Z_][a-zA-Z0-9_.-]*$/.test(fullKey)) {
        data.push({ key: fullKey, value, isValid: true });
      } else {
        data.push({ key: fullKey, value, isValid: false, error: 'Nome de chave inválido' });
      }
    });

    return data;
  };

  const flattenObject = (obj: any, prefix = ''): Record<string, any> => {
    const flattened: Record<string, any> = {};
    
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        const newKey = prefix ? `${prefix}.${key}` : key;
        
        if (obj[key] !== null && typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
          Object.assign(flattened, flattenObject(obj[key], newKey));
        } else {
          flattened[newKey] = obj[key];
        }
      }
    }
    
    return flattened;
  };

  const handleFetchUrl = async () => {
    if (!url.trim()) {
      showToast({
        title: 'Erro',
        description: 'URL é obrigatória',
        variant: 'destructive',
      });
      return;
    }

    setFetching(true);
    try {
      const response = await fetch(url);
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      const content = await response.text();
      setFetchedContent(content);

      // Detect format if auto
      const detectedFormat = fileFormat === 'auto' ? detectFileFormat(url, content) : fileFormat;
      const parsed = parseContent(content, detectedFormat);
      setParsedData(parsed);

      showToast({
        title: 'Conteúdo Carregado',
        description: `Arquivo carregado com sucesso. Formato detectado: ${detectedFormat.toUpperCase()}`,
        variant: 'success',
      });
    } catch (error) {
      const errorMsg = error instanceof Error ? error.message : 'Erro desconhecido';
      showToast({
        title: 'Erro ao Carregar URL',
        description: errorMsg,
        variant: 'destructive',
      });
    } finally {
      setFetching(false);
    }
  };

  const handleContentChange = (content: string) => {
    setFetchedContent(content);
    
    if (content.trim()) {
      // Detect format if auto
      const detectedFormat = fileFormat === 'auto' ? detectFileFormat(url, content) : fileFormat;
      const parsed = parseContent(content, detectedFormat);
      setParsedData(parsed);
    } else {
      setParsedData([]);
    }
  };

  const validateForm = () => {
    if (!configMapName.trim()) {
      showToast({
        title: 'Erro de Validação',
        description: 'Nome do ConfigMap é obrigatório',
        variant: 'destructive',
      });
      return false;
    }

    if (!selectedNamespace) {
      showToast({
        title: 'Erro de Validação',
        description: 'Namespace é obrigatório',
        variant: 'destructive',
      });
      return false;
    }

    const validData = parsedData.filter((d) => d.isValid);
    if (validData.length === 0) {
      showToast({
        title: 'Erro de Validação',
        description: 'Nenhum dado válido encontrado',
        variant: 'destructive',
      });
      return false;
    }

    return true;
  };

  const handleCreateConfigMap = async () => {
    if (!validateForm()) return;

    setCreating(true);
    try {
      const validData = parsedData.filter((d) => d.isValid);

      let command = `kubectl create configmap "${configMapName}" -n "${selectedNamespace}"`;

      validData.forEach((item) => {
        command += ` --from-literal="${item.key}"="${item.value}"`;
      });

      const result = await executeCommand(command);

      if (result.success) {
        showToast({
          title: 'ConfigMap Criado com Sucesso',
          description: `ConfigMap "${configMapName}" foi criado com ${validData.length} entradas`,
          variant: 'success',
        });
        navigate('/storage/configmaps');
      } else {
        showToast({
          title: 'Erro ao Criar ConfigMap',
          description: result.error || 'Falha ao criar o ConfigMap',
          variant: 'destructive',
        });
      }
    } catch (error) {
      const errorMsg = error instanceof Error ? error.message : 'Erro inesperado';
      showToast({
        title: 'Erro',
        description: errorMsg,
        variant: 'destructive',
      });
    } finally {
      setCreating(false);
    }
  };

  const validData = parsedData.filter((d) => d.isValid);
  const invalidData = parsedData.filter((d) => !d.isValid);

  const formatIcons = {
    auto: Globe,
    env: FileText,
    json: Code,
    yaml: Settings,
    properties: Database,
    ini: FileText,
  };

  const FormatIcon = formatIcons[fileFormat];

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center space-x-4">
          <Button variant="ghost" size="icon" onClick={() => navigate(-1)}>
            <ArrowLeft className="h-4 w-4" />
          </Button>
          <div>
            <h1 className="text-3xl font-bold text-foreground flex items-center">
              <Globe className="h-8 w-8 mr-3 text-teal-600" />
              Importar de URL Remota
            </h1>
            <p className="text-muted-foreground">
              Importe configurações de uma URL remota (GitHub, GitLab, etc.)
            </p>
          </div>
        </div>
      </div>

      {/* Basic Info */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center">
            <Settings className="h-5 w-5 mr-2" />
            Informações Básicas
          </CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <Label htmlFor="configMapName">Nome do ConfigMap</Label>
              <Input
                id="configMapName"
                placeholder="ex: app-config"
                value={configMapName}
                onChange={(e) => setConfigMapName(e.target.value)}
              />
            </div>
            <div>
              <Label htmlFor="namespace">Namespace</Label>
              <Select
                value={selectedNamespace}
                onValueChange={setSelectedNamespace}
              >
                <SelectTrigger>
                  <SelectValue placeholder="Selecione o namespace" />
                </SelectTrigger>
                <SelectContent>
                  {namespaces.map((ns) => (
                    <SelectItem key={ns.name} value={ns.name}>
                      {ns.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* URL Input */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center">
            <Globe className="h-5 w-5 mr-2" />
            URL Remota
          </CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div>
            <Label htmlFor="url">URL do Arquivo</Label>
            <Input
              id="url"
              placeholder="https://raw.githubusercontent.com/user/repo/main/config.env"
              value={url}
              onChange={(e) => setUrl(e.target.value)}
            />
            <p className="text-sm text-muted-foreground mt-1">
              Exemplos: GitHub raw, GitLab raw, ou qualquer URL pública
            </p>
          </div>

          <div>
            <Label htmlFor="fileFormat">Formato do Arquivo</Label>
            <Select value={fileFormat} onValueChange={(value) => setFileFormat(value as 'auto' | 'env' | 'json' | 'yaml' | 'properties' | 'ini')}>
              <SelectTrigger>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="auto">
                  <div className="flex items-center">
                    <Globe className="h-4 w-4 mr-2" />
                    Auto-detectar
                  </div>
                </SelectItem>
                <SelectItem value="env">
                  <div className="flex items-center">
                    <FileText className="h-4 w-4 mr-2" />
                    Arquivo .env
                  </div>
                </SelectItem>
                <SelectItem value="json">
                  <div className="flex items-center">
                    <Code className="h-4 w-4 mr-2" />
                    Arquivo JSON
                  </div>
                </SelectItem>
                <SelectItem value="yaml">
                  <div className="flex items-center">
                    <Settings className="h-4 w-4 mr-2" />
                    Arquivo YAML
                  </div>
                </SelectItem>
                <SelectItem value="properties">
                  <div className="flex items-center">
                    <Database className="h-4 w-4 mr-2" />
                    Arquivo .properties
                  </div>
                </SelectItem>
                <SelectItem value="ini">
                  <div className="flex items-center">
                    <FileText className="h-4 w-4 mr-2" />
                    Arquivo .ini
                  </div>
                </SelectItem>
              </SelectContent>
            </Select>
          </div>

          <Button
            onClick={handleFetchUrl}
            disabled={fetching || !url.trim()}
            className="w-full"
          >
            {fetching ? (
              <>
                <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                Carregando...
              </>
            ) : (
              <>
                <Download className="h-4 w-4 mr-2" />
                Carregar Arquivo
              </>
            )}
          </Button>
        </CardContent>
      </Card>

      {/* Fetched Content */}
      {fetchedContent && (
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center">
              <FormatIcon className="h-5 w-5 mr-2" />
              Conteúdo Carregado
            </CardTitle>
          </CardHeader>
          <CardContent>
            <div className="space-y-2">
              <Label htmlFor="fetchedContent">
                Edite o conteúdo conforme necessário antes de processar
              </Label>
              <Textarea
                id="fetchedContent"
                value={fetchedContent}
                onChange={(e) => handleContentChange(e.target.value)}
                rows={8}
                className="font-mono text-sm"
                placeholder="Conteúdo carregado aparecerá aqui..."
              />
              <p className="text-sm text-muted-foreground">
                💡 Dica: Você pode editar o conteúdo para remover linhas indesejadas ou fazer ajustes antes de processar
              </p>
            </div>
          </CardContent>
        </Card>
      )}

      {/* Preview */}
      {parsedData.length > 0 && (
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center justify-between">
              <div className="flex items-center">
                <Eye className="h-5 w-5 mr-2" />
                Pré-visualização
              </div>
              <Button
                variant="outline"
                size="sm"
                onClick={() => setShowPreview(!showPreview)}
              >
                {showPreview ? (
                  <EyeOff className="h-4 w-4" />
                ) : (
                  <Eye className="h-4 w-4" />
                )}
                {showPreview ? 'Ocultar' : 'Mostrar'}
              </Button>
            </CardTitle>
          </CardHeader>
          <CardContent>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
              <div className="flex items-center space-x-2">
                <CheckCircle className="h-5 w-5 text-green-600" />
                <span className="text-sm font-medium">
                  {validData.length} entradas válidas
                </span>
              </div>
              {invalidData.length > 0 && (
                <div className="flex items-center space-x-2">
                  <AlertCircle className="h-5 w-5 text-red-600" />
                  <span className="text-sm font-medium text-red-600">
                    {invalidData.length} entradas inválidas
                  </span>
                </div>
              )}
            </div>

            {showPreview && (
              <div className="space-y-4">
                {validData.length > 0 && (
                  <div>
                    <h4 className="font-medium text-green-700 mb-2">
                      Entradas Válidas:
                    </h4>
                    <div className="bg-green-50 p-3 rounded-md space-y-1 max-h-60 overflow-y-auto">
                      {validData.map((item, index) => (
                        <div key={index} className="text-sm font-mono">
                          <span className="text-green-800 font-medium">
                            {item.key}
                          </span>
                          <span className="text-gray-600">=</span>
                          <span className="text-green-700">{item.value}</span>
                        </div>
                      ))}
                    </div>
                  </div>
                )}

                {invalidData.length > 0 && (
                  <div>
                    <h4 className="font-medium text-red-700 mb-2">
                      Entradas Inválidas:
                    </h4>
                    <div className="bg-red-50 p-3 rounded-md space-y-1">
                      {invalidData.map((item, index) => (
                        <div key={index} className="text-sm">
                          <div className="font-mono text-red-800">
                            {item.key || '(erro)'}
                          </div>
                          <div className="text-red-600 text-xs">
                            {item.error}
                          </div>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            )}
          </CardContent>
        </Card>
      )}

      {/* Actions */}
      <div className="flex items-center justify-between pt-6">
        <Button variant="outline" onClick={() => navigate(-1)}>
          <ArrowLeft className="h-4 w-4 mr-2" />
          Voltar
        </Button>
        <Button
          onClick={handleCreateConfigMap}
          disabled={creating || validData.length === 0}
        >
          {creating ? (
            <>
              <Loader2 className="h-4 w-4 mr-2 animate-spin" />
              Criando...
            </>
          ) : (
            <>
              <CheckCircle className="h-4 w-4 mr-2" />
              Criar ConfigMap
            </>
          )}
        </Button>
      </div>
    </div>
  );
}

export default ConfigMapImportUrlPage;