import React, { useState, useEffect } from 'react';
import { AgentDashboard } from './components/AgentDashboard';
import { ClientPortal } from './components/ClientPortal';
import { AuthScreen } from './components/AuthScreen';
import { ToastContainer, ToastMessage, ToastType } from './components/Toast';
import { INITIAL_SETTINGS } from './constants';
import { Agent, AppSettings, AppState, ClientUser, KBArticle, Ticket, TicketStatus, SurveyResult, TicketQueue, ChatMessage, AgentRole } from './types';

const App: React.FC = () => {
  const [state, setState] = useState<AppState>({
    tickets: [],
    articles: [],
    agents: [],
    queues: [],
    surveys: [],
    clientUsers: [],
    settings: INITIAL_SETTINGS,
    currentUser: null,
    userRole: 'guest'
  });

  const [toasts, setToasts] = useState<ToastMessage[]>([]);
  const [loading, setLoading] = useState(false);

  // --- API HELPER ---
  const apiFetch = async (endpoint: string, options: RequestInit = {}) => {
    try {
      const res = await fetch(`/api${endpoint}`, {
        headers: { 'Content-Type': 'application/json' },
        ...options
      });
      if (!res.ok) throw new Error(`API Error: ${res.statusText}`);
      return await res.json();
    } catch (error) {
      console.error(error);
      throw error;
    }
  };

  const loadData = async () => {
    try {
      setLoading(true);
      // Load initial config data
      const data = await apiFetch('/initial-data');
      
      // Load tickets
      const tickets = await apiFetch('/tickets');

      setState(prev => ({
        ...prev,
        agents: data.agents,
        clientUsers: data.clientUsers,
        queues: data.queues,
        articles: data.articles,
        surveys: data.surveys,
        tickets: tickets,
        settings: data.settings || prev.settings
      }));
    } catch (e) {
      showToast("Errore caricamento dati dal server", 'error');
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    // Carica dati al caricamento se l'utente è loggato
    if (state.currentUser) {
        loadData();
    }
  }, [state.currentUser]);

  // Effect to refresh tickets periodically if logged in
  useEffect(() => {
    if (state.currentUser) {
      const interval = setInterval(loadData, 10000); // Poll every 10s
      return () => clearInterval(interval);
    }
  }, [state.currentUser]);


  const showToast = (message: string, type: ToastType = 'info') => {
    const id = Date.now().toString();
    setToasts(prev => [...prev, { id, message, type }]);
  };

  const removeToast = (id: string) => {
    setToasts(prev => prev.filter(t => t.id !== id));
  };

  // --- Auth Management ---
  const handleLogin = async (email: string, pass: string, isAgent: boolean) => {
    try {
      const res = await apiFetch('/auth/login', {
        method: 'POST',
        body: JSON.stringify({ email, password: pass })
      });

      if (res.user) {
        setState(prev => ({ ...prev, currentUser: res.user, userRole: res.role }));
        showToast(`Benvenuto ${res.user.name}`, 'success');
        return true;
      }
      return false;
    } catch (e) {
      return false;
    }
  };

  const handleClientRegister = async (name: string, email: string, pass: string, company: string) => {
    try {
      const res = await apiFetch('/auth/register', {
        method: 'POST',
        body: JSON.stringify({ name, email, password: pass, company })
      });
      
      if (res.success) {
        setState(prev => ({ 
          ...prev, 
          clientUsers: [...prev.clientUsers, res.user],
          currentUser: res.user,
          userRole: 'client'
        }));
        showToast("Registrazione completata!", 'success');
      }
    } catch (e) {
      showToast("Errore registrazione", 'error');
    }
  };

  const handleLogout = () => {
    setState(prev => ({ ...prev, currentUser: null, userRole: 'guest', tickets: [] }));
    showToast("Logout effettuato", 'info');
  };

  // --- Ticket Management ---
  const createTicket = async (ticketData: Omit<Ticket, 'id' | 'createdAt' | 'messages' | 'status'>) => {
    try {
      const newTicket = await apiFetch('/tickets', {
        method: 'POST',
        body: JSON.stringify(ticketData)
      });
      setState(prev => ({ ...prev, tickets: [newTicket, ...prev.tickets] }));
      showToast("Ticket creato correttamente", 'success');
    } catch (e) {
      showToast("Errore creazione ticket", 'error');
    }
  };

  const replyToTicket = async (ticketId: string, message: string) => {
    const role = state.userRole === 'client' ? 'user' : 'assistant';
    try {
      const newMsg = await apiFetch(`/tickets/${ticketId}/messages`, {
        method: 'POST',
        body: JSON.stringify({ role, content: message })
      });

      setState(prev => ({
        ...prev,
        tickets: prev.tickets.map(t => {
            if (t.id !== ticketId) return t;
            const shouldReopen = role === 'user' && t.status === TicketStatus.RESOLVED;
            return { 
                ...t, 
                messages: [...(t.messages || []), newMsg], // FIX: Ensure array fallback
                status: shouldReopen ? TicketStatus.OPEN : t.status
            };
        })
      }));
    } catch (e) {
      showToast("Errore invio messaggio", 'error');
    }
  };

  const updateTicketStatus = async (id: string, status: TicketStatus) => {
    try {
      await apiFetch(`/tickets/${id}`, {
        method: 'PATCH',
        body: JSON.stringify({ status })
      });
      setState(prev => ({
        ...prev,
        tickets: prev.tickets.map(t => t.id === id ? { ...t, status } : t)
      }));
      showToast(`Stato aggiornato a ${status}`, 'info');
    } catch (e) {
       showToast("Errore aggiornamento stato", 'error');
    }
  };

  const updateTicketAgent = async (id: string, agentId: string) => {
    try {
      await apiFetch(`/tickets/${id}`, {
        method: 'PATCH',
        body: JSON.stringify({ assignedAgentId: agentId })
      });
      setState(prev => ({
        ...prev,
        tickets: prev.tickets.map(t => t.id === id ? { ...t, assignedAgentId: agentId } : t)
      }));
      showToast("Agente assegnato", 'success');
    } catch (e) {
       showToast("Errore assegnazione agente", 'error');
    }
  };
  
  const markTicketsAsAnalyzed = async (ticketIds: string[]) => {
      try {
          await apiFetch('/tickets/mark-analyzed', {
              method: 'POST',
              body: JSON.stringify({ ticketIds })
          });
          // Optimistically update
          setState(prev => ({
              ...prev,
              tickets: prev.tickets.map(t => ticketIds.includes(t.id) ? { ...t, hasBeenAnalyzed: true } : t)
          }));
      } catch (e) {
          console.error("Failed to mark tickets analyzed", e);
      }
  };

  // --- KB Management ---
  const addArticle = async (article: KBArticle) => {
    try {
        const res = await apiFetch('/articles', {
            method: 'POST',
            body: JSON.stringify(article)
        });
        setState(prev => ({
            ...prev,
            articles: [{...article, id: res.id, lastUpdated: res.lastUpdated}, ...prev.articles]
        }));
        showToast("Articolo salvato", 'success');
    } catch (e) {
        showToast("Errore salvataggio articolo", 'error');
    }
  };

  const updateArticle = async (updatedArticle: KBArticle) => {
    try {
        await apiFetch(`/articles/${updatedArticle.id}`, {
            method: 'PATCH',
            body: JSON.stringify(updatedArticle)
        });
        setState(prev => ({
            ...prev,
            articles: prev.articles.map(a => a.id === updatedArticle.id ? updatedArticle : a)
        }));
        showToast("Articolo aggiornato", 'success');
    } catch (e) {
        showToast("Errore aggiornamento articolo", 'error');
    }
  };
  
  const deleteArticle = async (id: string) => {
      try {
          await apiFetch(`/articles/${id}`, { method: 'DELETE' });
          setState(prev => ({
              ...prev,
              articles: prev.articles.filter(a => a.id !== id)
          }));
          showToast("Articolo eliminato", 'info');
      } catch(e) {
          showToast("Errore eliminazione articolo", 'error');
      }
  };

  // --- Survey Management ---
  const submitSurvey = async (surveyData: Omit<SurveyResult, 'id' | 'timestamp'>) => {
    try {
        const res = await apiFetch('/surveys', {
            method: 'POST',
            body: JSON.stringify(surveyData)
        });
        const newSurvey = { ...surveyData, id: res.id, timestamp: new Date().toISOString() };
        setState(prev => ({ ...prev, surveys: [...prev.surveys, newSurvey] }));
        showToast("Feedback inviato", 'success');
    } catch (e) {
        showToast("Errore invio feedback", 'error');
    }
  };

  // --- Settings & Management (Now with Persistence) ---

  const addAgent = async (agent: Agent) => { 
    try {
        await apiFetch('/agents', { method: 'POST', body: JSON.stringify(agent) });
        setState(prev => ({ ...prev, agents: [...prev.agents, agent] }));
        showToast("Agente creato", 'success');
    } catch(e) { showToast("Errore creazione agente", 'error'); }
  };

  const updateAgent = async (agent: Agent) => { 
    try {
        await apiFetch(`/agents/${agent.id}`, { method: 'PUT', body: JSON.stringify(agent) });
        setState(prev => ({ ...prev, agents: prev.agents.map(a => a.id === agent.id ? agent : a) }));
        showToast("Agente aggiornato", 'success');
    } catch(e) { showToast("Errore aggiornamento agente", 'error'); }
  };

  const removeAgent = async (id: string) => { 
    try {
        await apiFetch(`/agents/${id}`, { method: 'DELETE' });
        setState(prev => ({ ...prev, agents: prev.agents.filter(a => a.id !== id) }));
        showToast("Agente rimosso", 'info');
    } catch(e) { showToast("Errore rimozione agente", 'error'); }
  };

  const addClientUser = async (user: ClientUser) => { 
     // Reuses auth/register usually, but for admin adding user:
     try {
        await apiFetch('/auth/register', { method: 'POST', body: JSON.stringify(user) });
        setState(prev => ({ ...prev, clientUsers: [...prev.clientUsers, user] }));
        showToast("Utente aggiunto", 'success');
     } catch(e) { showToast("Errore aggiunta utente", 'error'); }
  };

  const updateClientUser = async (user: ClientUser) => { 
     try {
        await apiFetch(`/client_users/${user.id}`, { method: 'PUT', body: JSON.stringify(user) });
        setState(prev => ({ ...prev, clientUsers: prev.clientUsers.map(u => u.id === user.id ? user : u) }));
        showToast("Utente aggiornato", 'success');
     } catch(e) { showToast("Errore aggiornamento utente", 'error'); }
  };

  const removeClientUser = async (id: string) => { 
     try {
        await apiFetch(`/client_users/${id}`, { method: 'DELETE' });
        setState(prev => ({ ...prev, clientUsers: prev.clientUsers.filter(u => u.id !== id) }));
        showToast("Utente rimosso", 'info');
     } catch(e) { showToast("Errore rimozione utente", 'error'); }
  };

  const updateSettings = async (newSettings: AppSettings) => { 
    try {
        await apiFetch('/settings', { method: 'PUT', body: JSON.stringify(newSettings) });
        setState(prev => ({ ...prev, settings: newSettings }));
        // Note: Real-time update of theme might require reload or context update, but setState handles it for current session
    } catch(e) { showToast("Errore salvataggio impostazioni", 'error'); }
  };

  const addQueue = async (queue: TicketQueue) => { 
    try {
        await apiFetch('/queues', { method: 'POST', body: JSON.stringify(queue) });
        setState(prev => ({ ...prev, queues: [...prev.queues, queue] }));
        showToast("Coda aggiunta", 'success');
    } catch(e) { showToast("Errore aggiunta coda", 'error'); }
  };

  const removeQueue = async (id: string) => { 
    try {
        await apiFetch(`/queues/${id}`, { method: 'DELETE' });
        setState(prev => ({ ...prev, queues: prev.queues.filter(q => q.id !== id) }));
        showToast("Coda rimossa", 'info');
    } catch(e) { showToast("Errore rimozione coda", 'error'); }
  };


  // Render Logic
  if (!state.currentUser) {
    return (
      <>
        <AuthScreen 
          settings={state.settings} 
          onClientLogin={(e, p) => handleLogin(e, p, false)}
          onAgentLogin={(e, p) => handleLogin(e, p, true)}
          onClientRegister={handleClientRegister}
        />
        <ToastContainer toasts={toasts} removeToast={removeToast} />
      </>
    );
  }

  // Filter Tickets
  const isAgentOrSupervisor = state.userRole === 'agent' || state.userRole === 'supervisor';
  const agentTickets = isAgentOrSupervisor
    ? state.tickets.filter(t => (state.currentUser as Agent).queues?.includes(t.queue))
    : state.tickets; 

  return (
    <div className="min-h-screen bg-gray-50 text-gray-900 font-sans" style={{ '--brand-color': state.settings.branding.primaryColor } as React.CSSProperties}>
      
      {state.userRole === 'client' ? (
        <ClientPortal 
          currentUser={state.currentUser as ClientUser}
          articles={state.settings.features.kbEnabled ? state.articles : []} 
          tickets={state.tickets.filter(t => t.customerName === state.currentUser?.name)}
          queues={state.queues}
          settings={state.settings}
          onCreateTicket={createTicket} 
          onReplyTicket={replyToTicket}
          onSubmitSurvey={submitSurvey}
          onLogout={handleLogout}
          showToast={showToast}
        />
      ) : (
        <AgentDashboard 
          currentUser={state.currentUser as Agent}
          tickets={agentTickets}
          articles={state.settings.features.kbEnabled ? state.articles : []}
          agents={state.agents}
          queues={state.queues}
          surveys={state.surveys}
          clientUsers={state.clientUsers}
          settings={state.settings}
          updateTicketStatus={updateTicketStatus}
          updateTicketAgent={updateTicketAgent}
          onReplyTicket={replyToTicket} 
          addArticle={addArticle}
          updateArticle={updateArticle}
          deleteArticle={deleteArticle} // New Prop
          markTicketsAsAnalyzed={markTicketsAsAnalyzed} // New Prop
          addAgent={addAgent}
          updateAgent={updateAgent}
          removeAgent={removeAgent}
          addClientUser={addClientUser}
          updateClientUser={updateClientUser}
          removeClientUser={removeClientUser}
          updateSettings={updateSettings}
          addQueue={addQueue}
          removeQueue={removeQueue}
          onLogout={handleLogout}
          showToast={showToast}
        />
      )}
      <ToastContainer toasts={toasts} removeToast={removeToast} />
    </div>
  );
};

export default App;
