
import React, { useState, useEffect, useRef } from 'react';
import { PlexConnectionSettings, PlexServerConnection, PlexLibrary } from '../types';
import { apiService } from '../services/api';
import { X, Server, Lock, User, Key, Globe, Eye, EyeOff, CheckCircle, Library, ChevronDown, ChevronRight, Settings, Loader2 } from 'lucide-react';

interface ConnectionModalProps {
  isOpen: boolean;
  onClose: () => void;
  onConnectSuccess: (serverInfo: PlexServerConnection) => void;
  onShowMessage: (message: string) => void;
}

const ConnectionModal: React.FC<ConnectionModalProps> = ({ isOpen, onClose, onConnectSuccess, onShowMessage }) => {
  const [formData, setFormData] = useState<PlexConnectionSettings>({
    protocol: 'http',
    address: '',
    port: '32400',
    token: '',
    username: '',
    password: '',
    timeout: 9
  });

  const [isConnecting, setIsConnecting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [showPassword, setShowPassword] = useState(false);
  const [showAdvanced, setShowAdvanced] = useState(false);
  
  // Post-connection state
  const [connectedServerInfo, setConnectedServerInfo] = useState<PlexServerConnection | null>(null);
  const [libraries, setLibraries] = useState<PlexLibrary[]>([]);
  const [selectedLibraryId, setSelectedLibraryId] = useState<string>('');

  const abortControllerRef = useRef<AbortController | null>(null);

  // Reset state when opening
  useEffect(() => {
    if (isOpen) {
      setError(null);
      setConnectedServerInfo(null);
      setLibraries([]);
      setSelectedLibraryId('');
    }
    return () => {
       // Cleanup any pending request if modal closes
       if (abortControllerRef.current) {
         abortControllerRef.current.abort();
       }
    };
  }, [isOpen]);

  if (!isOpen) return null;

  const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const handleTimeoutChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const val = parseInt(e.target.value) || 0;
    setFormData(prev => ({ ...prev, timeout: val }));
  };

  const handleLibraryChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
    const newId = e.target.value;
    setSelectedLibraryId(newId);
    
    const lib = libraries.find(l => l.id === newId);
    if (lib && connectedServerInfo) {
       const updatedInfo = { ...connectedServerInfo, libraryName: lib.title };
       setConnectedServerInfo(updatedInfo);
       onConnectSuccess(updatedInfo);
       onShowMessage(`Library switched to ${lib.title}`);
    }
  };

  const isTokenProvided = formData.token.trim().length > 0;
  
  const disabledInputClass = isTokenProvided 
    ? "bg-gray-700/50 text-gray-500 line-through decoration-gray-500 cursor-not-allowed border-gray-700" 
    : "bg-gray-800 text-gray-100 border-gray-600 focus:border-plex-orange focus:ring-1 focus:ring-plex-orange";

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    
    // If already connecting, this acts as Cancel
    if (isConnecting) {
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
        abortControllerRef.current = null;
        setIsConnecting(false);
        setError("Connection cancelled by user.");
      }
      return;
    }

    setError(null);
    setIsConnecting(true);

    const abortController = new AbortController();
    abortControllerRef.current = abortController;

    const result = await apiService.connectToPlex(formData, abortController.signal);

    // Only proceed if we weren't aborted/cancelled (though apiService handles error msg)
    if (abortController.signal.aborted) return;

    setIsConnecting(false);
    abortControllerRef.current = null;

    if (result.status === 'success' && result.data) {
      setFormData(prev => ({
        ...prev,
        token: result.data.token,
        username: '',
        password: ''
      }));

      const info = result.data.serverInfo;
      setConnectedServerInfo(info);
      onShowMessage(`Successfully connected to ${info.name || 'Plex Server'}`);
      
      const libs = info.libraries || [];
      setLibraries(libs);
      if (libs.length > 0) {
          const defaultLib = libs[0];
          setSelectedLibraryId(defaultLib.id);
          onConnectSuccess({
              ...info,
              libraryName: defaultLib.title
          });
      } else {
          onConnectSuccess(info);
      }
    } else {
      setError(result.message || "Connection failed");
    }
  };

  const isConnected = !!connectedServerInfo;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm">
      <div className="bg-gray-900 border border-gray-700 rounded-xl shadow-2xl w-full max-w-md overflow-hidden animate-in fade-in zoom-in duration-200 flex flex-col max-h-[90vh]">
        
        {/* Header */}
        <div className="px-6 py-4 bg-gray-800 border-b border-gray-700 flex items-center justify-between flex-none">
          <h3 className="text-lg font-semibold text-white flex items-center gap-2">
            <Server size={18} className={isConnected ? "text-green-400" : "text-plex-orange"} />
            {isConnected ? 'Server Connected' : 'Connect Plex Server'}
          </h3>
          <button onClick={onClose} className="text-gray-400 hover:text-white transition-colors">
            <X size={20} />
          </button>
        </div>

        {/* Body */}
        <div className="p-6 overflow-y-auto custom-scrollbar">
            <form onSubmit={handleSubmit} className="space-y-4">
            
            {error && (
                <div className="p-3 bg-red-500/10 border border-red-500/20 text-red-400 text-xs rounded-md">
                {error}
                </div>
            )}

            {/* Server Connection */}
            <div className="space-y-3">
                <label className="text-xs font-semibold text-gray-400 uppercase tracking-wider">Server Details</label>
                <div className="grid grid-cols-4 gap-3">
                <div className="col-span-1">
                    <select
                    name="protocol"
                    value={formData.protocol}
                    onChange={handleChange}
                    disabled={isConnected || isConnecting}
                    className={`w-full h-10 px-2 bg-gray-800 border border-gray-600 rounded-md text-sm text-white focus:border-plex-orange focus:outline-none ${isConnected ? 'opacity-60 cursor-not-allowed' : ''}`}
                    >
                    <option value="http">HTTP</option>
                    <option value="https">HTTPS</option>
                    </select>
                </div>
                <div className="col-span-3">
                    <div className="relative">
                    <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                        <Globe size={14} className="text-gray-500" />
                    </div>
                    <input 
                        type="text" 
                        name="address"
                        required
                        disabled={isConnected || isConnecting}
                        placeholder="IP Address or Domain"
                        value={formData.address}
                        onChange={handleChange}
                        className={`w-full h-10 pl-9 pr-3 bg-gray-800 border border-gray-600 rounded-md text-sm text-white placeholder-gray-500 focus:border-plex-orange focus:outline-none focus:ring-1 focus:ring-plex-orange transition-all ${isConnected ? 'opacity-60 cursor-not-allowed' : ''}`}
                    />
                    </div>
                </div>
                </div>
                
                <div>
                <input 
                    type="text" 
                    name="port"
                    disabled={isConnected || isConnecting}
                    placeholder="Port (e.g. 32400)"
                    value={formData.port}
                    onChange={handleChange}
                    className={`w-full h-10 px-3 bg-gray-800 border border-gray-600 rounded-md text-sm text-white placeholder-gray-500 focus:border-plex-orange focus:outline-none focus:ring-1 focus:ring-plex-orange transition-all ${isConnected ? 'opacity-60 cursor-not-allowed' : ''}`}
                />
                </div>
            </div>

            <div className="h-px bg-gray-800 my-4" />

            {/* Authentication */}
            <div className="space-y-3">
                <label className="text-xs font-semibold text-gray-400 uppercase tracking-wider">Authentication</label>
                
                {/* Token */}
                <div className="relative">
                <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                    <Key size={14} className="text-plex-orange" />
                </div>
                <input 
                    type="text" 
                    name="token"
                    disabled={isConnected || isConnecting}
                    placeholder="X-Plex-Token (Optional)"
                    value={formData.token}
                    onChange={handleChange}
                    className={`w-full h-10 pl-9 pr-3 bg-gray-800 border border-gray-600 rounded-md text-sm text-white placeholder-gray-500 focus:border-plex-orange focus:outline-none focus:ring-1 focus:ring-plex-orange transition-all font-mono ${isConnected ? 'opacity-60 cursor-not-allowed' : ''}`}
                />
                </div>

                {!isConnected && (
                    <>
                        <div className="text-center text-[10px] text-gray-500 uppercase tracking-widest font-semibold py-1">
                        — OR —
                        </div>

                        {/* Username */}
                        <div className="relative">
                        <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                            <User size={14} className={isTokenProvided ? "text-gray-600" : "text-gray-400"} />
                        </div>
                        <input 
                            type="text" 
                            name="username"
                            disabled={isTokenProvided || isConnecting}
                            placeholder="Username / Email"
                            value={formData.username}
                            onChange={handleChange}
                            className={`w-full h-10 pl-9 pr-3 rounded-md text-sm transition-all focus:outline-none ${disabledInputClass}`}
                        />
                        </div>

                        {/* Password */}
                        <div className="relative">
                        <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                            <Lock size={14} className={isTokenProvided ? "text-gray-600" : "text-gray-400"} />
                        </div>
                        <input 
                            type={showPassword ? "text" : "password"} 
                            name="password"
                            disabled={isTokenProvided || isConnecting}
                            placeholder="Password"
                            value={formData.password}
                            onChange={handleChange}
                            className={`w-full h-10 pl-9 pr-10 rounded-md text-sm transition-all focus:outline-none ${disabledInputClass}`}
                        />
                        <button
                            type="button"
                            disabled={isTokenProvided || isConnecting}
                            onClick={() => setShowPassword(!showPassword)}
                            className={`absolute inset-y-0 right-0 pr-3 flex items-center ${isTokenProvided ? 'cursor-not-allowed opacity-50' : 'cursor-pointer text-gray-400 hover:text-white'}`}
                        >
                            {showPassword ? <EyeOff size={14} /> : <Eye size={14} />}
                        </button>
                        </div>
                    </>
                )}
            </div>

            {/* Advanced Options */}
            {!isConnected && (
              <div className="border border-gray-800 rounded-lg overflow-hidden">
                <button
                  type="button"
                  onClick={() => setShowAdvanced(!showAdvanced)}
                  className="w-full flex items-center justify-between px-3 py-2 bg-gray-800/50 hover:bg-gray-800 text-xs font-medium text-gray-400 hover:text-gray-200 transition-colors"
                >
                  <div className="flex items-center gap-2">
                    <Settings size={14} />
                    <span>Advanced Options</span>
                  </div>
                  {showAdvanced ? <ChevronDown size={14} /> : <ChevronRight size={14} />}
                </button>
                
                {showAdvanced && (
                  <div className="p-3 bg-gray-900/50 space-y-3 animate-in slide-in-from-top-2">
                    <div>
                      <label className="text-xs text-gray-500 mb-1 block">Connection Timeout (Seconds)</label>
                      <input 
                        type="number"
                        min="1"
                        max="60"
                        name="timeout"
                        value={formData.timeout || 9}
                        onChange={handleTimeoutChange}
                        disabled={isConnecting}
                        className="w-full h-8 px-2 bg-gray-800 border border-gray-700 rounded-md text-xs text-white focus:border-plex-orange focus:outline-none"
                      />
                    </div>
                  </div>
                )}
              </div>
            )}

            {!isConnected ? (
                <button
                    type="submit"
                    className={`w-full mt-4 py-2.5 rounded-lg text-sm font-bold text-gray-900 transition-all shadow-lg flex items-center justify-center gap-2
                    ${isConnecting 
                        ? 'bg-red-500/80 hover:bg-red-500 text-white animate-pulse' 
                        : 'bg-plex-orange hover:bg-yellow-500 active:scale-[0.98] shadow-plex-orange/20'
                    }`}
                >
                    {isConnecting ? (
                      <>
                        <Loader2 size={16} className="animate-spin" />
                        <span>Connecting... <span className="opacity-75 font-normal ml-1">(Cancel)</span></span>
                      </>
                    ) : 'Connect Server'}
                </button>
            ) : (
                <div className="mt-2 p-2 bg-green-500/10 border border-green-500/20 rounded-lg text-center">
                    <p className="text-green-400 text-sm font-semibold flex items-center justify-center gap-2">
                        <CheckCircle size={16} />
                        Connected Successfully
                    </p>
                </div>
            )}
            </form>

            {/* Library Selection - Appears after connection */}
            {isConnected && libraries.length > 0 && (
                <div className="mt-6 pt-5 border-t border-gray-700 animate-in slide-in-from-top-2 fade-in">
                    <label className="text-xs font-semibold text-gray-400 uppercase tracking-wider block mb-2">Select Library to Sync</label>
                    <div className="relative">
                        <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                            <Library size={14} className="text-plex-orange" />
                        </div>
                        <select
                            value={selectedLibraryId}
                            onChange={handleLibraryChange}
                            className="w-full h-10 pl-9 pr-3 bg-gray-800 border border-gray-600 rounded-md text-sm text-white focus:border-plex-orange focus:outline-none focus:ring-1 focus:ring-plex-orange appearance-none cursor-pointer hover:bg-gray-700/50 transition-colors"
                        >
                            {libraries.map(lib => (
                                <option key={lib.id} value={lib.id}>{lib.title}</option>
                            ))}
                        </select>
                        <div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
                            <ChevronDown size={14} className="text-gray-500" />
                        </div>
                    </div>
                    
                    <div className="mt-6 flex justify-end">
                        <button 
                            onClick={onClose}
                            className="px-6 py-2 bg-gray-700 hover:bg-gray-600 text-white text-sm font-medium rounded-lg transition-colors border border-gray-600 hover:border-gray-500"
                        >
                            Done
                        </button>
                    </div>
                </div>
            )}
        </div>
      </div>
    </div>
  );
};

export default ConnectionModal;
