import { useState, useEffect, useCallback } from 'react';
import { Link, useNavigate, useLocation } from 'react-router-dom';
import * as api from '../api';
import type { Site, Room, Rack } from '../types';

interface TreeRoom extends Room {
  racks: Rack[];
  expanded: boolean;
}
interface TreeSite extends Site {
  rooms: TreeRoom[];
  expanded: boolean;
}

export default function Sidebar() {
  const [tree, setTree] = useState<TreeSite[]>([]);
  const [search, setSearch] = useState('');
  const [searchResults, setSearchResults] = useState<Awaited<ReturnType<typeof api.search>> | null>(null);
  const [loading, setLoading] = useState(true);
  const [addSiteName, setAddSiteName] = useState('');
  const [showAddSite, setShowAddSite] = useState(false);
  const [addSiteErr, setAddSiteErr] = useState<string | null>(null);
  const navigate = useNavigate();
  const location = useLocation();

  const loadTree = useCallback(async () => {
    const sites = await api.getSites();
    setTree(sites.map(s => ({ ...s, rooms: [], expanded: false })));
    setLoading(false);
  }, []);

  useEffect(() => { loadTree(); }, [loadTree]);

  const expandSite = async (siteId: string) => {
    setTree(prev => prev.map(s => {
      if (s.id !== siteId) return s;
      if (s.expanded) return { ...s, expanded: false };
      return { ...s, expanded: true };
    }));
    // Load rooms if not loaded
    setTree(prev => {
      const site = prev.find(s => s.id === siteId);
      if (site && site.rooms.length === 0) {
        api.getSite(siteId).then(full => {
          setTree(p => p.map(s => s.id === siteId
            ? { ...s, rooms: (full.rooms ?? []).map(r => ({ ...r, racks: [], expanded: false })) }
            : s
          ));
        });
      }
      return prev;
    });
  };

  const expandRoom = async (siteId: string, roomId: string) => {
    setTree(prev => prev.map(s => s.id !== siteId ? s : {
      ...s,
      rooms: s.rooms.map(r => {
        if (r.id !== roomId) return r;
        if (r.expanded) return { ...r, expanded: false };
        // Load racks
        if (r.racks.length === 0) {
          api.getRacks(roomId).then(racks => {
            setTree(p => p.map(ss => ss.id !== siteId ? ss : {
              ...ss,
              rooms: ss.rooms.map(rr => rr.id === roomId ? { ...rr, racks } : rr),
            }));
          });
        }
        return { ...r, expanded: true };
      }),
    }));
  };

  const handleAddSite = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!addSiteName.trim()) return;
    setAddSiteErr(null);
    try {
      const site = await api.createSite({ name: addSiteName.trim() });
      setAddSiteName('');
      setShowAddSite(false);
      await loadTree();
      navigate(`/sites/${site.id}`);
    } catch (ex: unknown) {
      setAddSiteErr(ex instanceof Error ? ex.message : String(ex));
    }
  };

  useEffect(() => {
    if (!search.trim()) { setSearchResults(null); return; }
    const t = setTimeout(async () => {
      const r = await api.search(search);
      setSearchResults(r);
    }, 300);
    return () => clearTimeout(t);
  }, [search]);

  const isActive = (path: string) => location.pathname === path;

  return (
    <aside className="sidebar">
      <div className="sidebar-header">
        <Link to="/" className="sidebar-logo">
          <img src={`${import.meta.env.BASE_URL}Icon_networkView.png`} alt="NetworkView" className="logo-icon" />
          <span className="logo-text">NetworkView</span>
        </Link>
      </div>

      <div className="sidebar-search">
        <input
          type="text"
          placeholder="Search..."
          value={search}
          onChange={e => setSearch(e.target.value)}
          className="search-input"
        />
        {searchResults && (
          <div className="search-results">
            {searchResults.sites.map(s => (
              <Link key={s.id} to={`/sites/${s.id}`} className="search-result-item" onClick={() => setSearch('')}>
                <span className="search-result-icon">🏢</span> {s.name}
              </Link>
            ))}
            {searchResults.rooms.map(r => (
              <Link key={r.id} to={`/rooms/${r.id}`} className="search-result-item" onClick={() => setSearch('')}>
                <span className="search-result-icon">🚪</span> {r.name}
              </Link>
            ))}
            {searchResults.racks.map(r => (
              <Link key={r.id} to={`/racks/${r.id}`} className="search-result-item" onClick={() => setSearch('')}>
                <span className="search-result-icon">🗄️</span> {r.name}
              </Link>
            ))}
            {searchResults.components.map(c => (
              <Link key={c.id} to={`/components/${c.id}`} className="search-result-item" onClick={() => setSearch('')}>
                <span className="search-result-icon">🔧</span> {c.name}
                {c.ip_address && <span className="search-result-sub"> — {c.ip_address}</span>}
              </Link>
            ))}
            {!searchResults.sites.length && !searchResults.rooms.length &&
             !searchResults.racks.length && !searchResults.components.length && (
              <div className="search-no-results">No results found</div>
            )}
          </div>
        )}
      </div>

      <nav className="sidebar-nav">
        <div className="sidebar-section-header">
          <span>Sites</span>
          <button className="icon-btn" title="Add site" onClick={() => setShowAddSite(v => !v)}>+</button>
        </div>

        {showAddSite && (
          <>
            <form onSubmit={handleAddSite} className="inline-add-form">
              <input
                autoFocus
                type="text"
                placeholder="Site name..."
                value={addSiteName}
                onChange={e => setAddSiteName(e.target.value)}
                className="inline-input"
              />
              <button type="submit" className="inline-btn">Add</button>
              <button type="button" className="inline-btn secondary" onClick={() => { setShowAddSite(false); setAddSiteErr(null); }}>✕</button>
            </form>
            {addSiteErr && <div className="inline-error">{addSiteErr}</div>}
          </>
        )}

        {loading && <div className="sidebar-loading">Loading...</div>}

        {tree.map(site => (
          <div key={site.id} className="tree-node">
            <div className={`tree-item tree-site ${isActive(`/sites/${site.id}`) ? 'active' : ''}`}>
              <button className="tree-expand" onClick={() => expandSite(site.id)}>
                {site.expanded ? '▾' : '▸'}
              </button>
              <Link to={`/sites/${site.id}`} className="tree-label">
                <span className="tree-icon">🏢</span>
                <span className="tree-name">{site.name}</span>
                {site.room_count != null && (
                  <span className="tree-count">{site.room_count}</span>
                )}
              </Link>
            </div>

            {site.expanded && (
              <div className="tree-children">
                {site.rooms.map(room => (
                  <div key={room.id} className="tree-node">
                    <div className={`tree-item tree-room ${isActive(`/rooms/${room.id}`) ? 'active' : ''}`}>
                      <button className="tree-expand" onClick={() => expandRoom(site.id, room.id)}>
                        {room.expanded ? '▾' : '▸'}
                      </button>
                      <Link to={`/rooms/${room.id}`} className="tree-label">
                        <span className="tree-icon">🚪</span>
                        <span className="tree-name">{room.name}</span>
                      </Link>
                    </div>

                    {room.expanded && (
                      <div className="tree-children">
                        {room.racks.map(rack => (
                          <div key={rack.id} className={`tree-item tree-rack ${isActive(`/racks/${rack.id}`) ? 'active' : ''}`}>
                            <Link to={`/racks/${rack.id}`} className="tree-label">
                              <span className="tree-icon">🗄️</span>
                              <span className="tree-name">{rack.name}</span>
                              <span className="tree-count">{rack.total_units}U</span>
                            </Link>
                          </div>
                        ))}
                      </div>
                    )}
                  </div>
                ))}
                {site.rooms.length === 0 && (
                  <div className="tree-empty">No rooms yet</div>
                )}
              </div>
            )}
          </div>
        ))}

        {!loading && tree.length === 0 && (
          <div className="sidebar-empty">
            <p>No sites yet.</p>
            <button className="btn-primary btn-sm" onClick={() => setShowAddSite(true)}>
              + Add your first site
            </button>
          </div>
        )}
      </nav>

      <div className="sidebar-footer">
        <Link to="/settings" className={`sidebar-footer-link ${isActive('/settings') ? 'active' : ''}`}>
          ⚙ Settings
        </Link>
        <a
          href="/portal-return"
          className="sidebar-footer-link"
          title="Back to Enterprise Portal"
        >
          ⬡ Portal
        </a>
        <button
          className="sidebar-footer-link sidebar-logout-btn"
          onClick={() => { window.location.href = (import.meta.env.VITE_PORTAL_LOGOUT_URL as string | undefined) ?? '/logout'; }}
          title="Log out of NetworkView and the Enterprise Portal"
        >
          ⏻ Logout
        </button>
      </div>
    </aside>
  );
}
