import { useState, useEffect, useCallback } from 'react';
import { invoke } from '@tauri-apps/api/core';
import { Settings as SettingsIcon } from "lucide-react";
import Settings, { SmtpConfig, AzureConfig } from "./components/Settings";
import Recorder from "./components/Recorder";

import TranscriptionView from "./components/TranscriptionView";
import Tabs from "./components/Tabs";
import MeetingsView from "./components/MeetingsView";
import HistoryView from "./components/HistoryView";
import Import from "./components/Import";
import ToastContainer, { ToastMessage, ToastType } from "./components/ui/Toast";

export interface PromptTemplate {
  id: string;
  name: string;
  content: string;
  keywords?: string[];
}

export interface EmailTemplate {
  id: string;
  name: string;
  subject: string;
  body: string;
}

function App() {
  const [view, setView] = useState<'recorder' | 'settings' | 'transcription' | 'meetings' | 'history' | 'import'>('recorder');
  const [lastTab, setLastTab] = useState<'recorder' | 'transcription' | 'meetings' | 'history' | 'import'>('recorder');


  // Auto-start recording state to handle "Join & Record" transition
  const [autoStartRecording, setAutoStartRecording] = useState(false);
  const [recordingSubject, setRecordingSubject] = useState<string>('');

  // Toast State
  const [toasts, setToasts] = useState<ToastMessage[]>([]);

  const addToast = (message: string, type: ToastType = 'info', duration = 3000) => {
    const id = Date.now().toString() + Math.random().toString();
    setToasts(prev => [...prev, { id, message, type, duration }]);
  };

  const removeToast = (id: string) => {
    setToasts(prev => prev.filter(t => t.id !== id));
  };
  const [apiKey, setApiKey] = useState(localStorage.getItem('infomaniak_api_key') || '');
  const [productId, setProductId] = useState(localStorage.getItem('infomaniak_product_id') || '');
  const [savePath, setSavePath] = useState(localStorage.getItem('infomaniak_save_path') || '');
  const [smtpConfig, setSmtpConfig] = useState<SmtpConfig>(() => {
    const saved = localStorage.getItem('hearbit_smtp_config');
    return saved ? JSON.parse(saved) : { host: '', port: '587', user: '', pass: '', sender: '', senderName: '' };
  });
  const [azureConfig, setAzureConfig] = useState<AzureConfig>(() => {
    const saved = localStorage.getItem('hearbit_azure_config');
    return saved ? JSON.parse(saved) : { clientId: '', tenantId: '' };
  });

  const [selectedModel, setSelectedModel] = useState<string>(() => {
    return localStorage.getItem('hearbit_selected_model') || 'mixtral';
  });

  // Daily Backup State
  const [dailyBackupEnabled, setDailyBackupEnabled] = useState(() => localStorage.getItem('hearbit_daily_backup_enabled') === 'true');
  const [dailyBackupPath, setDailyBackupPath] = useState(() => localStorage.getItem('hearbit_daily_backup_path') || '');
  const [lastBackupDate, setLastBackupDate] = useState(() => localStorage.getItem('hearbit_last_backup_date') || '');
  const [blockedApps, setBlockedApps] = useState<string[]>(() => {
    const saved = localStorage.getItem('hearbit_blocked_apps');
    return saved ? JSON.parse(saved) : [];
  });

  const handleModelChange = (model: string) => {
    setSelectedModel(model);
    localStorage.setItem('hearbit_selected_model', model);
  };

  // Default prompts if none exist
  /* eslint-disable no-useless-escape */ // Escape quotes in prompts
  const defaultPrompts: PromptTemplate[] = [
    {
      id: '1',
      name: 'Meeting Protokoll (General)',
      content: `Rolle: Du bist ein hochprofessioneller, effizienter Protokollführer und persönlicher Assistent. Deine Aufgabe ist es, aus dem untenstehenden Roh-Transkript (oder den Notizen) ein strukturiertes, leicht lesbares und handlungsorientiertes Ergebnisprotokoll zu erstellen.

Anweisungen:
- Filterung: Ignoriere Smalltalk, Füllwörter, Begrüßungen und irrelevante Abschweifungen. Konzentriere dich auf Fakten, Entscheidungen und Aufgaben.
- Tonalität: Schreibe sachlich, objektiv und präzise (Business German).
- Klarheit: Formuliere vage Aussagen in klare Sätze um, ohne den Sinn zu verändern.
- Zuordnung: Ordne Aufgaben immer einer Person zu (wenn im Text genannt).

Gewünschte Struktur des Outputs:

# Meeting Protokoll: [Thema des Meetings]

Datum: [Datum einfügen, falls bekannt, sonst "N/A"]
Anwesende: [Liste der Namen]

## 1. Management Summary
Eine kurze Zusammenfassung der wichtigsten Punkte in 3-5 Sätzen. Worum ging es im Kern?

## 2. Wichtige Entscheidungen
[Entscheidung 1]
[Entscheidung 2]
(Liste hier nur Dinge auf, die explizit beschlossen wurden)

## 3. Offene Fragen / Diskussionspunkte
Kurze Stichpunkte zu Themen, die besprochen, aber noch nicht final geklärt wurden.

## 4. Action Items (To-Dos)
| Was ist zu tun? | Wer ist verantwortlich? | Bis wann? (falls genannt) |
| :--- | :--- | :--- |
| [Aufgabe 1] | [Name] | [Datum] |
| [Aufgabe 2] | [Name] | [Datum] |

## 5. Nächste Schritte / Nächstes Meeting
Kurze Info zum weiteren Vorgehen.`,
      keywords: ['protokoll', 'meeting', 'team', 'daily', 'weekly']
    },
    {
      id: '2',
      name: '1:1 Gespräch / Jour Fixe',
      content: `Rolle: Du bist ein diskreter und empathischer Executive Assistant. Deine Aufgabe ist es, ein 1:1 Gespräch zwischen einem Mitarbeiter und seinem Vorgesetzten zusammenzufassen. Das Gespräch beinhaltet sowohl geschäftliche als auch private/persönliche Themen.

Wichtige Anweisungen:
- Kategorisierung: Trenne strikt zwischen "Persönlichem/Atmosphäre" und "Operativem Business".
- Tonalität bei Privatem: Fasse private Themen (Wochenende, Hobbys, Familie, Wohlbefinden) als fließenden Text zusammen. Sei hier warmherzig, aber diskret. Vermeide Stichpunkte, das wirkt bei Privatem zu mechanisch.
- Tonalität bei Business: Sei hier gewohnt präzise, faktenbasiert und nutze Bulletpoints.
- Sensibilität: Wenn über Feedback, Karriereentwicklung oder Kritik gesprochen wurde, fasse dies in einem separaten Abschnitt neutral und konstruktiv zusammen.

Gewünschte Struktur des Outputs:

# 1:1 Gesprächszusammenfassung

Datum: [Datum]
Teilnehmer: [Namen]

## 1. Persönlicher Check-in & Atmosphäre
[Hier bitte einen kurzen Fließtext schreiben: Wie geht es den Teilnehmern? Was wurde an privaten Updates geteilt (z.B. Urlaub, Familie, Hobbys)? Wie war die Grundstimmung des Gesprächs?]

## 2. Operative Themen (Business Updates)
Thema A: [Kurze Zusammenfassung]
Thema B: [Kurze Zusammenfassung]
(Führe hier die konkreten Arbeitsthemen auf)

## 3. Feedback & Entwicklung
[Hier notieren, falls über Karriereziele, Gehalt, Weiterbildung oder gegenseitiges Feedback gesprochen wurde. Falls nicht besprochen: "Keine Themen in diesem Meeting".]

## 4. Vereinbarungen & Action Items
| Wer? | Was ist zu tun / zu beachten? | Bis wann? |
| :--- | :--- | :--- |
| [Name] | [Aufgabe] | [Datum] |
| [Name] | [Aufgabe] | [Datum] |`,
      keywords: ['personal', 'privat', 'vertraulich', 'entwicklungsgespräch', 'feedback', 'unter vier augen']
    },
    {
      id: '3',
      name: 'Kundenmeeting (Official)',
      content: `Rolle: Du bist ein professioneller Account Manager und Business Analyst. Erstelle ein Protokoll für ein Kundenmeeting. Deine Tonalität ist höflich, verbindlich und extrem präzise. Das Ergebnis soll so formuliert sein, dass es theoretisch direkt an den Kunden gesendet werden kann.

Wichtige Anweisungen:
- Fokus auf Vereinbarungen: Was wurde genau beschlossen? Wenn der Kunde eine Anforderung geändert hat, notiere das explizit.
- Verantwortlichkeiten trennen: Trenne bei den To-Dos strikt zwischen "Aufgaben für uns (Auftragnehmer)" und "Aufgaben für den Kunden" (z.B. Material liefern, Freigaben).
- Klarheit vor Länge: Vermeide interne Fachsprache, wenn möglich. Schreibe so, dass der Kunde es versteht.
- Diplomatie: Falls es Konflikte gab, formuliere diese lösungsorientiert und neutral (z.B. statt "Kunde hat sich beschwert" schreibe "Es wurde Feedback zu X besprochen, Lösungsweg ist Y").

Gewünschte Struktur des Outputs:

# Ergebnisprotokoll: [Projektname / Thema]

Datum: [Datum]
Teilnehmer: [Namen Kunden] & [Namen Intern]

## 1. Zusammenfassung (Executive Summary)
2-3 Sätze zum Ziel des Termins und dem aktuellen Status (z.B. "Wir haben den aktuellen Design-Sprint besprochen und die Anforderungen für Phase 2 finalisiert.")

## 2. Besprochene Punkte & Projektstatus
[Thema 1]: Kurze Zusammenfassung der Diskussion.
[Thema 2]: Kurze Zusammenfassung der Diskussion.

## 3. Wichtige Entscheidungen & Genehmigungen
(Dies ist der wichtigste Teil für die Absicherung!)
✅ Beschluss: [Was wurde final entschieden/freigegeben?]
🔄 Änderung: [Wurde der Projektumfang geändert? Neue Anforderungen?]

## 4. Action Items (Wer macht was?)

👉 Aufgaben für uns (Intern):
[ ] [Aufgabe] (bis [Datum])
[ ] [Aufgabe] (bis [Datum])

👉 Aufgaben für den Kunden (To-Dos / Lieferungen):
[ ] [Aufgabe, z.B. Zugangdaten senden, Design freigeben] (bis [Datum])

## 5. Nächster Termin / Timeline
Wann findet das nächste Meeting statt oder was ist der nächste Meilenstein?`,
      keywords: ['beratung', 'kunde', 'client', 'angebot', 'projekt', 'extern']
    }
  ];

  // Default Email Templates
  const defaultEmailTemplates: EmailTemplate[] = [
    {
      id: '1',
      name: 'Meeting Summary (Standard)',
      subject: 'Meeting Summary: {{subject}}',
      body: `Hi everyone,

Here is the summary of our meeting "{{subject}}" from {{date}}.

{{summary}}

Best regards,
Hearbit Assistant`
    },
    {
      id: '2',
      name: 'Action Items Only',
      subject: 'Action Items: {{subject}}',
      body: `Hi Team,

Please find below the action items from our call on {{date}}:

{{summary}}

Thanks!`
    }
  ];

  const [prompts, setPrompts] = useState<PromptTemplate[]>(() => {
    const saved = localStorage.getItem('infomaniak_prompts');
    return saved ? JSON.parse(saved) : defaultPrompts;
  });

  const [emailTemplates, setEmailTemplates] = useState<EmailTemplate[]>(() => {
    const saved = localStorage.getItem('hearbit_email_templates');
    return saved ? JSON.parse(saved) : defaultEmailTemplates;
  });

  const handleSaveSettings = (
    newApiKey: string,
    newProductId: string,
    newPrompts: PromptTemplate[],
    newSavePath: string,
    newSmtp: SmtpConfig,
    newAzure: AzureConfig,
    newEmailTemplates: EmailTemplate[],
    newDailyBackupEnabled: boolean,
    newDailyBackupPath: string,
    newBlockedApps: string[]
  ) => {
    setApiKey(newApiKey);
    setProductId(newProductId);
    setPrompts(newPrompts);
    setSavePath(newSavePath);
    setSmtpConfig(newSmtp);
    setAzureConfig(newAzure);
    setEmailTemplates(newEmailTemplates);

    setDailyBackupEnabled(newDailyBackupEnabled);
    setDailyBackupPath(newDailyBackupPath);
    setBlockedApps(newBlockedApps);

    localStorage.setItem('hearbit_api_key', newApiKey);
    localStorage.setItem('hearbit_product_id', newProductId);
    localStorage.setItem('hearbit_prompts', JSON.stringify(newPrompts));
    localStorage.setItem('hearbit_save_path', newSavePath);
    localStorage.setItem('hearbit_smtp_config', JSON.stringify(newSmtp));
    localStorage.setItem('hearbit_azure_config', JSON.stringify(newAzure));
    localStorage.setItem('hearbit_email_templates', JSON.stringify(newEmailTemplates));

    localStorage.setItem('hearbit_daily_backup_enabled', String(newDailyBackupEnabled));
    localStorage.setItem('hearbit_daily_backup_path', newDailyBackupPath);
    localStorage.setItem('hearbit_blocked_apps', JSON.stringify(newBlockedApps));

    setView(lastTab);
  };

  // State for Recorder (lifted to persist across view changes)
  const [transcription, setTranscription] = useState('');
  const [summary, setSummary] = useState('');

  interface HistoryItem {
    id: string;
    date: string;
    transcription: string;
    summary: string;
    subject?: string;
    filename?: string;
  }

  const [history, setHistory] = useState<HistoryItem[]>(() => {
    const saved = localStorage.getItem('infomaniak_history');
    return saved ? JSON.parse(saved) : [];
  });

  const handleSaveToHistory = (t?: string, s?: string) => {
    const transToSave = t !== undefined ? t : transcription;
    const sumToSave = s !== undefined ? s : summary;

    // Sanitize subject for filename
    const safeSubject = recordingSubject
      ? recordingSubject.replace(/[^a-zA-Z0-9_-]/g, '_')
      : `Meeting_${Date.now()}`;
    const filename = `${safeSubject}.md`;

    if (!transToSave && !sumToSave) return;

    const newItem: HistoryItem = {
      id: Date.now().toString(),
      date: new Date().toLocaleString(),
      transcription: transToSave,
      summary: sumToSave,
      subject: recordingSubject || "Untitled Recording",
      filename: filename
    };
    const newHistory = [newItem, ...history];
    setHistory(newHistory);
    localStorage.setItem('infomaniak_history', JSON.stringify(newHistory));

    // Persist to Disk (Markdown)
    const content = `# ${newItem.subject}\nDate: ${newItem.date}\n\n## Summary\n${sumToSave}\n\n## Transcription\n${transToSave}`;
    // If savePath is set, we use it. If not, backend defaults to temp. Here we want to save text.
    // Let's assume savePath is set or we default to Documents/Hearbit (if we could).
    // For now, if savePath is set, use it.
    if (savePath) {
      // We need invoke to save text
      import("@tauri-apps/api/core").then(({ invoke }) => {
        invoke('save_text_file', { path: `${savePath}/${filename}`, content })
          .then(() => addToast('Transcript saved to file', 'success'))
          .catch(e => addToast(`Failed to save file: ${e}`, 'error'));
      });
    }
  };

  const handleRenameHistory = (id: string, newSubject: string) => {
    const newHistory = history.map(item =>
      item.id === id ? { ...item, subject: newSubject } : item
    );
    setHistory(newHistory);
    localStorage.setItem('infomaniak_history', JSON.stringify(newHistory));
  };

  const handleDeleteHistory = (id: string) => {
    const newHistory = history.filter(item => item.id !== id);
    setHistory(newHistory);
    localStorage.setItem('infomaniak_history', JSON.stringify(newHistory));
  };

  const handleLoadHistory = (item: HistoryItem) => {
    setTranscription(item.transcription);
    setSummary(item.summary);
    setView('transcription'); // Switch to Transcription view to see content
  };

  const performBackup = useCallback(async (isAuto = false) => {
    try {
      if (isAuto && !dailyBackupEnabled) return;

      const dataToBackup = {
        apiKey,
        productId,
        prompts,
        savePath,
        smtp: smtpConfig,
        azure: azureConfig,
        emailTemplates,
        history, // Including history!
        // Also include daily backup settings so they persist on restore
        dailyBackup: {
          enabled: dailyBackupEnabled,
          path: dailyBackupPath,
        }
      };

      // Always save as JSON (no encryption)
      const content = JSON.stringify(dataToBackup, null, 2);

      const dateStr = new Date().toISOString().slice(0, 10);
      const fileName = `hearbit_backup_${isAuto ? 'auto_' : ''}${dateStr}.json`;

      // Determine path: use specific daily backup path, or general savePath
      const targetDir = (isAuto ? dailyBackupPath : savePath) || savePath;

      if (!targetDir) {
        if (!isAuto) addToast('No backup path configured.', 'error');
        return;
      }

      const fullPath = `${targetDir}/${fileName}`;

      await invoke('save_text_file', { path: fullPath, content });

      if (isAuto) {
        const now = new Date().toISOString();
        setLastBackupDate(now);
        localStorage.setItem('hearbit_last_backup_date', now);
        console.log("Auto-backup completed:", fullPath);
      } else {
        addToast(`Backup saved to ${fullPath}`, 'success');
      }

    } catch (e) {
      console.error("Backup failed:", e);
      if (!isAuto) addToast(`Backup failed: ${e}`, 'error');
    }
  }, [apiKey, productId, prompts, savePath, smtpConfig, azureConfig, emailTemplates, history, dailyBackupEnabled, dailyBackupPath]);

  // Check for Daily Backup on Mount / State Change
  useEffect(() => {
    if (!dailyBackupEnabled) return;

    const check = async () => {
      const today = new Date().toISOString().slice(0, 10);
      const last = lastBackupDate ? lastBackupDate.slice(0, 10) : '';

      if (last !== today) {
        // Perform backup
        await performBackup(true);
      }
    };

    const timer = setTimeout(() => {
      check();
    }, 5000); // Check 5s after load to allow state to settle

    return () => clearTimeout(timer);
  }, [dailyBackupEnabled, lastBackupDate, performBackup]);



  return (
    <div className="min-h-screen bg-background text-foreground flex flex-col select-none overflow-hidden">
      {/* Top Navigation Bar */}
      {view !== 'settings' && (
        <div className="w-full flex justify-center items-center pt-4 pb-2 z-20 relative bg-background/95 backdrop-blur">
          <div className="absolute right-4 top-4">
            <button
              onClick={() => {
                setLastTab(view === 'history' ? view : 'recorder');
                setView('settings');
              }}
              className="p-2 text-muted-foreground hover:text-foreground hover:bg-secondary rounded-full transition-colors"
            >
              <SettingsIcon size={20} />
            </button>
          </div>

          <Tabs
            currentTab={view as 'recorder' | 'transcription' | 'meetings' | 'history' | 'import'}
            onTabChange={(t) => setView(t)}
          />
        </div>
      )}

      <div className="flex-1 flex h-full overflow-hidden relative">
        <div className="flex-1 flex flex-col h-full overflow-hidden relative">
          {/* Recorder - Persistent (Hidden via CSS to keep recording alive) */}
          <div className="flex-1 flex flex-col h-full overflow-hidden" style={{ display: view === 'recorder' ? 'flex' : 'none' }}>
            <Recorder
              apiKey={apiKey}
              productId={productId}
              prompts={prompts}
              onOpenSettings={() => {
                setLastTab('recorder');
                setView('settings');
              }}
              transcription={transcription}
              setTranscription={setTranscription}
              summary={summary}
              setSummary={setSummary}
              history={history}
              onSaveToHistory={handleSaveToHistory}
              onDeleteHistory={handleDeleteHistory}
              onLoadHistory={handleLoadHistory}
              savePath={savePath}

              onRecordingComplete={() => setView('transcription')}
              autoStart={autoStartRecording}
              recordingSubject={recordingSubject}
              onAutoStartHandled={() => setAutoStartRecording(false)}
              addToast={addToast}
              selectedModel={selectedModel}
              onModelChange={handleModelChange}
              isVisible={view === 'recorder'}
              blockedApps={blockedApps}
            />
          </div>

          {view === 'transcription' && (
            <TranscriptionView
              transcription={transcription}
              summary={summary}
              smtpConfig={smtpConfig}
              apiKey={apiKey}
              productId={productId}
              prompts={prompts}
              emailTemplates={emailTemplates}
              onUpdateSummary={(newSummary) => {
                setSummary(newSummary); // Update view
                // Also update history item if it exists
                // We identify by transcription content match (simple heuristic) or we should track currentId
                const histIdx = history.findIndex(h => h.transcription === transcription);
                if (histIdx >= 0) {
                  const newHist = [...history];
                  newHist[histIdx] = { ...newHist[histIdx], summary: newSummary };
                  setHistory(newHist);
                  localStorage.setItem('infomaniak_history', JSON.stringify(newHist));
                }
              }}
              addToast={addToast}
            />
          )}

          {view === 'history' && (
            <HistoryView
              history={history}
              onLoad={handleLoadHistory}
              onDelete={handleDeleteHistory}
              onRename={handleRenameHistory}
              smtpConfig={smtpConfig}
              emailTemplates={emailTemplates}
              addToast={addToast}
            />
          )}

          {view === 'meetings' && (

            <MeetingsView
              azureClientId={azureConfig.clientId}
              onStartRecording={(subject) => {
                setView('recorder');
                setRecordingSubject(subject || '');
                setAutoStartRecording(true);
              }}
              apiKey={apiKey}
              productId={productId}
              selectedModel={selectedModel}
              onModelChange={handleModelChange}
            />
          )}

          {view === 'import' && (
            <Import
              apiKey={apiKey}
              productId={productId}
              prompts={prompts}
              selectedModel={selectedModel}
              onSaveToHistory={handleSaveToHistory}
              onComplete={() => setView('transcription')}
              addToast={addToast}
              setTranscription={setTranscription}
              setSummary={setSummary}
            />
          )}






          {view === 'settings' && (
            <Settings
              onSave={handleSaveSettings}
              onClose={() => setView(lastTab)}
              apiKey={apiKey}
              productId={productId}
              prompts={prompts}
              savePath={savePath}
              smtpConfig={smtpConfig}
              azureConfig={azureConfig}
              emailTemplates={emailTemplates}

              // Pass new backup props
              dailyBackupEnabled={dailyBackupEnabled}
              dailyBackupPath={dailyBackupPath}
              lastBackupDate={lastBackupDate}

              // Pass history and update callback
              history={history}
              onHistoryUpdate={(newHistory) => {
                setHistory(newHistory);
                localStorage.setItem('infomaniak_history', JSON.stringify(newHistory));
              }}
              blockedApps={blockedApps}
            />
          )}
        </div>
        <ToastContainer toasts={toasts} removeToast={removeToast} />
      </div>
    </div>
  );
}

export default App;
