import React, { useState, useEffect, useRef } from 'react';
import { useLoaderData, useNavigate, useParams } from "@remix-run/react";
import { useSocket } from "../context";
import { L33tADSPLCImpl } from "l33t-lib";
import { loaderPLCById } from '../loaders';

export const loader = loaderPLCById;

export default function PlcDetail() {
  const navigate = useNavigate();
  const { id } = useParams<{ id: string }>();
  const initialPLC = useLoaderData<typeof loader>();
  const socket = useSocket();
  const timeoutRef = useRef<NodeJS.Timeout>();
  
  const [selectedPLC, setSelectedPLC] = useState<L33tADSPLCImpl>(initialPLC);
  const [plcId, setPlcId] = useState<string>(id || '');
  const [ipAddress, setIpAddress] = useState<string>(initialPLC?.ip || '');
  const [boundVariables, setBoundVariables] = useState<string[]>(
    initialPLC ? initialPLC.boundVariables : []
  );

  useEffect(() => {
    if (initialPLC) {
      setSelectedPLC(initialPLC);
      setPlcId(id || '');
      setIpAddress(initialPLC.ip || '');
      setBoundVariables(initialPLC.boundVariables || []);
    }
  }, [id, initialPLC]);

  useEffect(() => {
    if (!socket) return;

    const handlePlcUpdate = (updatedId: string, updatedPlc: L33tADSPLCImpl | null) => {
      if (updatedId === id && updatedPlc) {
        setSelectedPLC(updatedPlc);
        setIpAddress(updatedPlc.ip);
        setBoundVariables(updatedPlc.boundVariables || []);
      }
    };

    socket.on("l33t_plc_update", handlePlcUpdate);
    return () => {
      socket.off("l33t_plc_update", handlePlcUpdate);
    };
  }, [socket, id]);

  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === "Escape") navigate("..");
    };
    document.addEventListener("keydown", handleKeyDown);
    return () => {
      document.removeEventListener("keydown", handleKeyDown);
    };
  }, [navigate]);

  const handleChangeId = (newId: string) => {
    setPlcId(newId);
    
    // Clear any existing timeout
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
    }

    // Set new timeout
    timeoutRef.current = setTimeout(() => {
      if (socket && selectedPLC && newId !== id) {
        socket.emit("l33t_delete_plc", { plcId: id });
        socket.emit("l33t_add_plc", newId, {
          ...selectedPLC,
          ip: ipAddress,
        });
        socket.emit("l33t_db_persist");
        navigate(`/plcs/${newId}`, { replace: true });
      }
    }, 1000);
  };

  const handleChangeIP = (value: string) => {
    setIpAddress(value);
    if (socket && selectedPLC) {
      const updatedPLC: Partial<L33tADSPLCImpl> = {
        ...selectedPLC,
        ip: value
      };
      socket.emit("l33t_plc_update", id, updatedPLC);
      socket.emit("l33t_db_persist");
    }
  };

  // Cleanup timeout on unmount
  useEffect(() => {
    return () => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    };
  }, []);

  if (!id) return <div>Error: No PLC ID provided</div>;
  if (!selectedPLC) return <div>No PLC selected</div>;

  return (
    <div className="fixed top-0 right-0 w-1/3 h-full bg-gray-800 text-white p-5">
      <h2 className="text-xl font-bold mb-6">PLC Details</h2>
      
      <form className="space-y-4">
        <div>
          <label className="block text-sm font-medium mb-1">Key ID</label>
          <input 
            type="text"
            value={plcId}
            onChange={(e) => handleChangeId(e.target.value)}
            placeholder="e.g., carroponte"
            className="w-full bg-gray-700 rounded px-3 py-2"
          />
        </div>

        <div>
          <label className="block text-sm font-medium mb-1">IP Address</label>
          <input 
            type="text"
            value={ipAddress}
            onChange={(e) => handleChangeIP(e.target.value)}
            className="w-full bg-gray-700 rounded px-3 py-2"
          />
        </div>
      </form>

      <div className="mt-4">
        <span className={`inline-block w-3 h-3 rounded-full mr-2 ${selectedPLC.connected ? 'bg-green-500' : 'bg-red-500'}`}></span>
        {selectedPLC.connected ? 'Connected' : 'Disconnected'}
      </div>

      {selectedPLC.description && (
        <div className="mt-4 text-gray-300">
          <p>{selectedPLC.description}</p>
        </div>
      )}

      {boundVariables && boundVariables.length > 0 ? (
        <div className="mt-8">
          <h3 className="text-lg font-medium mb-3">Bound Variables</h3>
          <ul className="space-y-2">
            {boundVariables.map((variable, index) => (
              <li 
                key={index}
                className="bg-gray-700 px-3 py-2 rounded flex justify-between items-center"
              >
                <span>{variable}</span>
                <span className="text-gray-400 text-sm">
                  {selectedPLC.values[variable]?.toString() || 'N/A'}
                </span>
              </li>
            ))}
          </ul>
        </div>
      ) : (
        <p className="mt-8 text-gray-400">No bound variables</p>
      )}
    </div>
  );
}