import React, { useState, useEffect } from 'react';
import { GateEvent, Settings, GateStatus } from './types';
import * as api from './api';
import { SettingsDialog } from './components/SettingsDialog';
import { Cog6ToothIcon } from '@heroicons/react/24/outline';

function App() {
  const [events, setEvents] = useState<GateEvent[]>([]);
  const [hasMoreEvents, setHasMoreEvents] = useState(false);
  const [totalEvents, setTotalEvents] = useState(0);
  const [settings, setSettings] = useState<Settings>({ 
    maxOpenTimeSeconds: 300,
    triggerDuration: 500,
    mqtt: {
      broker: 'localhost',
      port: '1883',
      username: '',
      password: '',
      clientId: 'gatekeeper',
      enabled: false
    },
    gpio: {
      gatePin: 17,
      statusPin: 27
    },
    logging: {
      level: 'WARNING',
      maxBytes: 10 * 1024 * 1024,  // 10MB
      backupCount: 5
    }
  });
  const [gateStatus, setGateStatus] = useState<GateStatus>({ isOpen: false, lastChanged: new Date().toISOString() });
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [isSettingsOpen, setIsSettingsOpen] = useState(false);

  const formatDate = (isoString: string) => {
    const date = new Date(isoString);
    return date.toLocaleString();
  };

  useEffect(() => {
    const loadData = async () => {
      try {
        const [eventsData, settingsData, statusData] = await Promise.all([
          api.getEvents(),
          api.getSettings(),
          api.getGateStatus()
        ]);
        setEvents(eventsData.events);
        setHasMoreEvents(eventsData.hasMore);
        setTotalEvents(eventsData.total);
        setSettings(settingsData);
        setGateStatus(statusData);
      } catch (err) {
        setError('Failed to load data');
        console.error(err);
      }
    };

    const interval = setInterval(async () => {
      try {
        // Only update status and most recent events
        const [statusData, eventsData] = await Promise.all([
          api.getGateStatus(),
          api.getEvents(10, 0)
        ]);
        setGateStatus(statusData);
        
        // Update only if we're on the first page and don't have more events loaded
        if (events.length <= 10 && !hasMoreEvents) {
          setEvents(eventsData.events);
          setHasMoreEvents(eventsData.hasMore);
          setTotalEvents(eventsData.total);
        } else {
          // If we have more events loaded, just prepend any new events
          const newEvents = eventsData.events.filter(
            newEvent => !events.some(
              existingEvent => 
                existingEvent.timestamp === newEvent.timestamp && 
                existingEvent.action === newEvent.action
            )
          );
          if (newEvents.length > 0) {
            setEvents(prev => [...newEvents, ...prev]);
            setTotalEvents(prev => prev + newEvents.length);
          }
        }
      } catch (err) {
        console.error('Failed to update status:', err);
      }
    }, 1000);

    loadData();

    return () => clearInterval(interval);
  }, []);

  const handleGateControl = async () => {
    setLoading(true);
    setError(null);
    try {
      const result = await api.triggerGate();
      if (result.success) {
        const newEvents = await api.getEvents();
        setEvents(newEvents.events);
        setGateStatus(prev => ({ ...prev, isOpen: result.isOpen }));
      }
    } catch (err) {
      setError('Failed to trigger gate');
      console.error(err);
    } finally {
      setLoading(false);
    }
  };

  const handleSettingsSave = async () => {
    setLoading(true);
    setError(null);
    try {
      await api.updateSettings(settings);
      setIsSettingsOpen(false);
    } catch (err) {
      setError('Failed to update settings');
      console.error(err);
    } finally {
      setLoading(false);
    }
  };

  const handleLoadMore = async () => {
    try {
      const moreEvents = await api.getEvents(10, events.length);
      if (moreEvents.events.length > 0) {
        setEvents(prev => [...prev, ...moreEvents.events]);
        setHasMoreEvents(moreEvents.hasMore);
        setTotalEvents(moreEvents.total);
      }
    } catch (err) {
      setError('Failed to load more events');
      console.error(err);
    }
  };

  return (
    <div className="min-h-screen bg-gray-100 py-2 flex flex-col justify-center">
      <div className="relative sm:max-w-xl sm:mx-auto">
        <div className="relative px-4 py-6 bg-white shadow-lg sm:rounded-3xl sm:p-12">
          <div className="max-w-md mx-auto">
            <div className="divide-y divide-gray-200">
              <div className="py-4 text-base leading-6 space-y-4 text-gray-700 sm:text-lg sm:leading-7">
                <div className="flex justify-between items-center mb-4">
                  <h1 className="text-2xl font-bold text-gray-900">Gate Control</h1>
                  <button
                    onClick={() => setIsSettingsOpen(true)}
                    className="p-2 text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
                  >
                    <Cog6ToothIcon className="h-6 w-6" />
                  </button>
                </div>

                {/* Gate Status */}
                <div className="mb-4">
                  <p className="text-lg font-semibold">
                    Status: <span className={gateStatus.isOpen ? "text-green-600" : "text-red-600"}>
                      {gateStatus.isOpen ? "Open" : "Closed"}
                    </span>
                  </p>
                  <p className="text-sm text-gray-500">
                    Last changed: {formatDate(gateStatus.lastChanged)}
                  </p>
                </div>

                {/* Gate Control Button */}
                <div className="mt-4">
                  <button
                    onClick={handleGateControl}
                    disabled={loading}
                    className={`w-full py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white 
                      ${loading ? 'bg-gray-400' : 'bg-blue-600 hover:bg-blue-700'} 
                      focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500`}
                  >
                    {loading ? 'Processing...' : 'Trigger Gate'}
                  </button>
                </div>

                {/* Error Display */}
                {error && (
                  <div className="mt-4 p-4 bg-red-100 text-red-700 rounded-md">
                    {error}
                  </div>
                )}

                {/* Recent Events */}
                <div className="mt-6">
                  <h2 className="text-lg font-semibold mb-2">Recent Events</h2>
                  <div className="border rounded-lg divide-y divide-gray-200 max-h-96 overflow-y-auto">
                    {events.map((event, index) => (
                      <div key={index} className="px-3 py-2 hover:bg-gray-50 flex items-center justify-between text-sm">
                        <div className="flex-1">
                          <div className="flex items-center gap-2">
                            <span className="font-medium">{event.action}</span>
                            <span className="text-xs text-gray-500">({event.source})</span>
                          </div>
                          <div className="text-xs text-gray-500">{formatDate(event.timestamp)}</div>
                        </div>
                        <div className={`w-2 h-2 rounded-full ${event.success ? 'bg-green-500' : 'bg-red-500'}`} />
                      </div>
                    ))}
                  </div>
                  {hasMoreEvents && (
                    <button
                      onClick={handleLoadMore}
                      className="mt-2 w-full text-sm text-gray-600 hover:text-gray-900 py-1 border rounded-md hover:bg-gray-50"
                    >
                      Show More ({events.length} of {totalEvents})
                    </button>
                  )}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      {/* Settings Dialog */}
      <SettingsDialog
        isOpen={isSettingsOpen}
        onClose={() => {
          setIsSettingsOpen(false);
          // loadSettings(); // Refresh settings after dialog closes
        }}
      />
    </div>
  );
}

export default App;
