import { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { IconDatabase, IconBrandMysql, IconArrowRight, IconLoader2, IconAlertCircle, IconRefresh } from '@tabler/icons-react';
import AIVisualization from '../components/AIVisualization';

interface QueryResults {
  results: any;
  query: string;
  visualization?: {
    type: 'bar' | 'pie' | 'line';
    config: any;
  };
}

interface ApiError {
  message: string;
  details?: string | Record<string, string | null>;
}

export default function Home() {
  const [dbConfig, setDbConfig] = useState({
    host: '',
    port: '3306',
    database: '',
    username: '',
    password: ''
  });
  const [tables, setTables] = useState<string[]>([]);
  const [selectedTable, setSelectedTable] = useState('');
  const [prompt, setPrompt] = useState('');
  const [results, setResults] = useState<QueryResults | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<ApiError | null>(null);

  const [dbUri, setDbUri] = useState('');
  const [showDbConfig, setShowDbConfig] = useState(false);

  useEffect(() => {
    const uri = `mysql://${dbConfig.username}:${dbConfig.password}@${dbConfig.host}:${dbConfig.port}/${dbConfig.database}`;
    setDbUri(uri);
  }, [dbConfig]);

  const fetchTables = async () => {
    if (!dbUri) return;
    
    setLoading(true);
    setError(null);
    try {
      const response = await fetch('/api/tables', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ dbUri }),
      });
      
      const data = await response.json();
      
      if (!response.ok) {
        throw new Error(data.message);
      }
      
      setTables(data.tables);
    } catch (err: any) {
      setError({
        message: 'Failed to fetch tables',
        details: err.message
      });
    } finally {
      setLoading(false);
    }
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    
    if (!selectedTable) {
      setError({
        message: "Table selection required",
        details: "Please select a table before submitting the query"
      });
      return;
    }

    setLoading(true);
    setError(null);
    setResults(null);

    try {
      const response = await fetch('/api/sql', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ 
          dbUri, 
          userPrompt: `${prompt} from table ${selectedTable}` 
        }),
      });
      
      const data = await response.json();
      
      if (!response.ok) {
        throw {
          message: data.message || 'An error occurred',
          details: data.details
        };
      }
      
      setResults(data);
    } catch (err: any) {
      setError({
        message: err.message || 'Failed to process request',
        details: err.details
      });
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800">
      <div className="container mx-auto px-4 py-12 max-w-4xl">
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          className="text-center mb-12"
        >
          <div className="flex items-center justify-center gap-3 mb-4">
            <IconBrandMysql className="w-10 h-10 text-blue-500" />
            <IconArrowRight className="w-6 h-6 text-gray-400" />
            <IconDatabase className="w-10 h-10 text-blue-500" />
          </div>
          <h1 className="text-4xl font-bold text-gray-800 dark:text-white mb-4">
            Text to SQL Converter
          </h1>
          <p className="text-gray-600 dark:text-gray-300">
            Transform natural language into SQL queries using AI
          </p>
        </motion.div>

        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.2 }}
          className="bg-white dark:bg-gray-800 rounded-2xl shadow-xl p-6 mb-8"
        >
          <form onSubmit={handleSubmit} className="space-y-6">
            {error && (
              <motion.div
                initial={{ opacity: 0, height: 0 }}
                animate={{ opacity: 1, height: 'auto' }}
                exit={{ opacity: 0, height: 0 }}
                className="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4"
              >
                <div className="flex items-center gap-2 text-red-800 dark:text-red-200">
                  <IconAlertCircle className="w-5 h-5" />
                  <p className="font-medium">{error.message}</p>
                </div>
                {error.details && (
                  <p className="mt-2 text-sm text-red-600 dark:text-red-300">
                    {typeof error.details === 'string' 
                      ? error.details 
                      : Object.entries(error.details)
                          .filter(([_, value]) => value)
                          .map(([_, value]) => value)
                          .join(', ')}
                  </p>
                )}
              </motion.div>
            )}

            <div className="space-y-4">
              <div className="flex justify-between items-center">
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-200">
                  Database Connection
                </label>
                <button
                  type="button"
                  onClick={() => setShowDbConfig(!showDbConfig)}
                  className="flex items-center gap-2 text-sm text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300"
                >
                  {showDbConfig ? (
                    <>Hide Connection Details <IconArrowRight className="w-4 h-4 rotate-90" /></>
                  ) : (
                    <>Show Connection Details <IconArrowRight className="w-4 h-4 -rotate-90" /></>
                  )}
                </button>
              </div>
              
              <AnimatePresence>
                {showDbConfig && (
                  <motion.div
                    initial={{ opacity: 0, height: 0 }}
                    animate={{ opacity: 1, height: 'auto' }}
                    exit={{ opacity: 0, height: 0 }}
                    transition={{ duration: 0.2 }}
                    className="overflow-hidden"
                  >
                    <div className="grid grid-cols-2 gap-4">
                      <div>
                        <input
                          type="text"
                          value={dbConfig.host}
                          onChange={(e) => setDbConfig(prev => ({ ...prev, host: e.target.value }))}
                          className="w-full px-4 py-3 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 focus:border-transparent transition-all"
                          placeholder="Server Host"
                        />
                      </div>
                      <div>
                        <input
                          type="text"
                          value={dbConfig.port}
                          onChange={(e) => setDbConfig(prev => ({ ...prev, port: e.target.value }))}
                          className="w-full px-4 py-3 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 focus:border-transparent transition-all"
                          placeholder="Port"
                        />
                      </div>
                      <div>
                        <input
                          type="text"
                          value={dbConfig.database}
                          onChange={(e) => setDbConfig(prev => ({ ...prev, database: e.target.value }))}
                          className="w-full px-4 py-3 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 focus:border-transparent transition-all"
                          placeholder="Database Name"
                        />
                      </div>
                      <div>
                        <input
                          type="text"
                          value={dbConfig.username}
                          onChange={(e) => setDbConfig(prev => ({ ...prev, username: e.target.value }))}
                          className="w-full px-4 py-3 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 focus:border-transparent transition-all"
                          placeholder="Username"
                        />
                      </div>
                      <div className="col-span-2">
                        <input
                          type="password"
                          value={dbConfig.password}
                          onChange={(e) => setDbConfig(prev => ({ ...prev, password: e.target.value }))}
                          className="w-full px-4 py-3 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 focus:border-transparent transition-all"
                          placeholder="Password"
                        />
                      </div>
                    </div>
                  </motion.div>
                )}
              </AnimatePresence>
            </div>

            <div>
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-2">
                Select Table
              </label>
              <div className="flex gap-4">
                <select
                  value={selectedTable}
                  onChange={(e) => setSelectedTable(e.target.value)}
                  className="flex-1 px-4 py-3 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 focus:border-transparent transition-all"
                  disabled={tables.length === 0}
                >
                  <option value="">Select a table</option>
                  {tables.map((table) => (
                    <option key={table} value={table}>
                      {table}
                    </option>
                  ))}
                </select>
                <button
                  type="button"
                  onClick={fetchTables}
                  disabled={!dbUri || loading}
                  className="px-4 py-3 rounded-lg bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 transition-all disabled:opacity-50"
                >
                  {loading ? (
                    <IconLoader2 className="w-5 h-5 animate-spin" />
                  ) : (
                    <IconRefresh className="w-5 h-5" />
                  )}
                </button>
              </div>
            </div>

            <div>
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-2">
                Your Query
              </label>
              <textarea
                value={prompt}
                onChange={(e) => setPrompt(e.target.value)}
                rows={4}
                className="w-full px-4 py-3 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 focus:border-transparent transition-all"
                placeholder="Example: Show me the first 5 users from the users table"
              />
            </div>

            <button
              type="submit"
              disabled={loading}
              className="w-full bg-blue-500 hover:bg-blue-600 text-white font-medium py-3 px-6 rounded-lg transition-all transform hover:scale-[1.02] active:scale-[0.98] disabled:opacity-70 disabled:cursor-not-allowed flex items-center justify-center gap-2"
            >
              {loading ? (
                <>
                  <IconLoader2 className="w-5 h-5 animate-spin" />
                  Converting...
                </>
              ) : (
                'Convert to SQL'
              )}
            </button>
          </form>
        </motion.div>

        {results && (
          <motion.div
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
            className="bg-white dark:bg-gray-800 rounded-2xl shadow-xl p-6"
          >
            <h2 className="text-xl font-semibold text-gray-800 dark:text-white mb-4">
              Generated SQL & Results
            </h2>
            <div className="bg-gray-50 dark:bg-gray-900 rounded-lg p-4 mb-4">
              <h3 className="text-sm font-medium text-gray-600 dark:text-gray-300 mb-2">
                SQL Query
              </h3>
              <pre className="text-sm text-gray-800 dark:text-gray-200 whitespace-pre-wrap">
                {results.query}
              </pre>
            </div>
            <div className="bg-gray-50 dark:bg-gray-900 rounded-lg p-4">
              <h3 className="text-sm font-medium text-gray-600 dark:text-gray-300 mb-2">
                Query Results
              </h3>
              <pre className="text-sm text-gray-800 dark:text-gray-200 whitespace-pre-wrap">
                {JSON.stringify(results.results, null, 2)}
              </pre>
            </div>
            {results?.visualization && (
              <div className="bg-gray-50 dark:bg-gray-900 rounded-lg p-4 mt-4">
                <h3 className="text-sm font-medium text-gray-600 dark:text-gray-300 mb-4">
                  AI Generated Visualization
                </h3>
                <AIVisualization visualization={results.visualization} />
              </div>
            )}
          </motion.div>
        )}
      </div>
    </div>
  );
}