// web/src/App.tsx
import React, { useState, useEffect } from 'react';
import { Header } from './components/Header';
import { LeftSidebar } from './components/LeftSidebar';
import { ChatArea } from './components/ChatArea';
import { RightPanel } from './components/RightPanel';
import { FloatingActionButtons } from './components/FloatingActionButtons';
import { LoginScreen } from './components/LoginScreen';
import { ProfileEditor } from './components/ProfileEditor';
import { X } from 'lucide-react';
import { Button } from './components/ui/button';
import { Toaster } from './components/ui/sonner';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { toast } from 'sonner';

import {
  apiLogin,
  apiChat,
  apiUpload,
  apiExport,
  apiSummary,
  type LearningMode,
  type Language,
  type FileType,
  type User as ApiUser,
} from './lib/api';

export interface Message {
  id: string;
  role: 'user' | 'assistant';
  content: string;
  timestamp: Date;
  references?: string[];
  sender?: GroupMember; // For group chat
}

export interface User {
  name: string;
  email: string;
}

export interface GroupMember {
  id: string;
  name: string;
  email: string;
  avatar?: string;
  isAI?: boolean;
}

export type SpaceType = 'individual' | 'group';

export interface Workspace {
  id: string;
  name: string;
  type: SpaceType;
  avatar: string;
  members?: GroupMember[];
}

export interface UploadedFile {
  file: File;
  type: FileType;
}

function App() {
  const [isDarkMode, setIsDarkMode] = useState(() => {
    const saved = localStorage.getItem('theme');
    return saved === 'dark' || (!saved && window.matchMedia('(prefers-color-scheme: dark)').matches);
  });

  const [user, setUser] = useState<User | null>(null);

  const [messages, setMessages] = useState<Message[]>([
    {
      id: '1',
      role: 'assistant',
      content:
        "👋 Hi! I'm Clare, your AI teaching assistant. I'm here to help you learn through personalized tutoring. Feel free to ask me anything about the course materials, or upload your documents to get started!",
      timestamp: new Date(),
    },
  ]);

  const [learningMode, setLearningMode] = useState<LearningMode>('concept');
  const [language, setLanguage] = useState<Language>('auto');
  const [uploadedFiles, setUploadedFiles] = useState<UploadedFile[]>([]);

  // You can later wire this to /api/memoryline
  const [memoryProgress] = useState(36);

  const [leftSidebarOpen, setLeftSidebarOpen] = useState(false);
  const [leftPanelVisible, setLeftPanelVisible] = useState(true);

  const [rightPanelOpen, setRightPanelOpen] = useState(false);
  const [rightPanelVisible, setRightPanelVisible] = useState(true);

  const [showProfileEditor, setShowProfileEditor] = useState(false);

  const [exportResult, setExportResult] = useState('');
  const [resultType, setResultType] = useState<'export' | 'quiz' | 'summary' | null>(null);

  // Mock group members (still fine; AI responder uses backend now)
  const [groupMembers] = useState<GroupMember[]>([
    { id: 'clare', name: 'Clare AI', email: 'clare@ai.assistant', isAI: true },
    { id: '1', name: 'Sarah Johnson', email: 'sarah.j@university.edu' },
    { id: '2', name: 'Michael Chen', email: 'michael.c@university.edu' },
    { id: '3', name: 'Emma Williams', email: 'emma.w@university.edu' },
  ]);

  const [workspaces, setWorkspaces] = useState<Workspace[]>([]);
  const [currentWorkspaceId, setCurrentWorkspaceId] = useState<string>('individual');

  useEffect(() => {
    if (user) {
      const userAvatar = `https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(user.email)}`;
      setWorkspaces([
        {
          id: 'individual',
          name: 'My Space',
          type: 'individual',
          avatar: userAvatar,
        },
        {
          id: 'group-1',
          name: 'CS 101 Study Group',
          type: 'group',
          avatar: 'https://api.dicebear.com/7.x/shapes/svg?seed=cs101group',
          members: groupMembers,
        },
        {
          id: 'group-2',
          name: 'AI Ethics Team',
          type: 'group',
          avatar: 'https://api.dicebear.com/7.x/shapes/svg?seed=aiethicsteam',
          members: groupMembers,
        },
      ]);
    }
  }, [user, groupMembers]);

  const currentWorkspace = workspaces.find((w) => w.id === currentWorkspaceId) || workspaces[0];
  const spaceType: SpaceType = currentWorkspace?.type || 'individual';

  useEffect(() => {
    document.documentElement.classList.toggle('dark', isDarkMode);
    localStorage.setItem('theme', isDarkMode ? 'dark' : 'light');
  }, [isDarkMode]);

  const asApiUser = (u: User): ApiUser => ({ name: u.name, email: u.email });

  const handleSendMessage = async (content: string) => {
    if (!content.trim() || !user) return;

    const sender: GroupMember | undefined =
      spaceType === 'group'
        ? { id: user.email, name: user.name, email: user.email }
        : undefined;

    const userMessage: Message = {
      id: crypto.randomUUID(),
      role: 'user',
      content,
      timestamp: new Date(),
      sender,
    };

    setMessages((prev) => [...prev, userMessage]);

    const shouldAIRespond = spaceType === 'individual' || content.toLowerCase().includes('@clare');
    if (!shouldAIRespond) return;

    const assistantId = crypto.randomUUID();
    const assistantPlaceholder: Message = {
      id: assistantId,
      role: 'assistant',
      content: 'Thinking...',
      timestamp: new Date(),
      sender: spaceType === 'group' ? groupMembers.find((m) => m.isAI) : undefined,
    };
    setMessages((prev) => [...prev, assistantPlaceholder]);

    try {
      const data = await apiChat({
        user: asApiUser(user),
        message: content,
        learningMode,
        language,
        docType: 'Syllabus',
      });

      const references =
        (data.refs || [])
          .map((r) => [r.source_file, r.section].filter(Boolean).join(' — '))
          .filter(Boolean);

      setMessages((prev) =>
        prev.map((m) =>
          m.id === assistantId
            ? {
                ...m,
                content: data.reply || '',
                references: references.length ? references : undefined,
              }
            : m
        )
      );
    } catch (err: any) {
      setMessages((prev) =>
        prev.map((m) =>
          m.id === assistantId
            ? { ...m, content: `Sorry — request failed.\n${err?.message ?? String(err)}` }
            : m
        )
      );
    }
  };

  const handleFileUpload = async (files: File[]) => {
    if (!user) return;

    const newFiles: UploadedFile[] = files.map((file) => ({
      file,
      type: 'other',
    }));

    setUploadedFiles((prev) => [...prev, ...newFiles]);

    for (const f of files) {
      try {
        const r = await apiUpload({ user: asApiUser(user), file: f, fileType: 'other' });
        toast.success(r.status_md || `Uploaded: ${f.name}`);
      } catch (e: any) {
        toast.error(e?.message ?? `Upload failed: ${f.name}`);
      }
    }
  };

  const handleRemoveFile = (index: number) => {
    setUploadedFiles((prev) => prev.filter((_, i) => i !== index));
  };

  const handleFileTypeChange = async (index: number, type: FileType) => {
    setUploadedFiles((prev) => prev.map((f, i) => (i === index ? { ...f, type } : f)));

    if (!user) return;
    const target = uploadedFiles[index];
    if (!target) return;

    try {
      const r = await apiUpload({
        user: asApiUser(user),
        file: target.file,
        fileType: type,
      });
      toast.success(r.status_md || `Updated type: ${target.file.name}`);
    } catch (e: any) {
      toast.error(e?.message ?? `Failed to update type: ${target.file.name}`);
    }
  };

  const handleClearConversation = () => {
    setMessages([
      {
        id: '1',
        role: 'assistant',
        content:
          "👋 Hi! I'm Clare, your AI teaching assistant. I'm here to help you learn through personalized tutoring. Feel free to ask me anything about the course materials, or upload your documents to get started!",
        timestamp: new Date(),
      },
    ]);
    toast.success('Conversation cleared');
  };

  const handleExport = async () => {
    if (!user) return;
    try {
      const r = await apiExport({ user: asApiUser(user), learningMode });
      setExportResult(r.markdown || '');
      setResultType('export');
      toast.success('Conversation exported!');
    } catch (e: any) {
      toast.error(e?.message ?? 'Export failed');
    }
  };

  const handleSummary = async () => {
    if (!user) return;
    try {
      const r = await apiSummary({ user: asApiUser(user), learningMode, language });
      setExportResult(r.markdown || '');
      setResultType('summary');
      toast.success('Summary generated!');
    } catch (e: any) {
      toast.error(e?.message ?? 'Summary failed');
    }
  };

  if (!user) {
    return (
      <LoginScreen
        onLogin={async (u) => {
          setUser(u);
          try {
            await apiLogin(asApiUser(u));
          } catch (e: any) {
            toast.error(e?.message ?? 'Login sync failed');
          }
        }}
      />
    );
  }

  return (
    <div className="min-h-screen bg-background flex flex-col">
      <Toaster />
      <Header
        user={user}
        onMenuClick={() => setLeftSidebarOpen(!leftSidebarOpen)}
        onUserClick={() => setRightPanelOpen(!rightPanelOpen)}
        isDarkMode={isDarkMode}
        onToggleDarkMode={() => setIsDarkMode(!isDarkMode)}
        language={language}
        onLanguageChange={setLanguage}
        workspaces={workspaces}
        currentWorkspace={currentWorkspace}
        onWorkspaceChange={setCurrentWorkspaceId}
      />

      {showProfileEditor && user && (
        <ProfileEditor user={user} onSave={setUser} onClose={() => setShowProfileEditor(false)} />
      )}

      <div
        className="flex-1 flex overflow-hidden"
        onWheel={(e) => e.stopPropagation()}
        style={{ overscrollBehavior: 'none' }}
      >
        {/* Mobile Sidebar Toggle - Left */}
        {leftSidebarOpen && (
          <div
            className="fixed inset-0 bg-black/50 z-40 lg:hidden"
            onClick={() => setLeftSidebarOpen(false)}
          />
        )}

        {/* Left Sidebar */}
        {leftPanelVisible ? (
          <aside className="hidden lg:flex w-80 bg-card border-r border-border flex-col h-full min-h-0 relative">
            <Button
              variant="secondary"
              size="icon"
              onClick={() => setLeftPanelVisible(false)}
              className="absolute top-4 z-[70] h-8 w-5 shadow-lg rounded-full bg-card border border-border"
              style={{ right: '-10px' }}
              title="Close panel"
            >
              <ChevronLeft className="h-3 w-3" />
            </Button>
            <LeftSidebar
              learningMode={learningMode}
              language={language}
              onLearningModeChange={setLearningMode}
              onLanguageChange={setLanguage}
              spaceType={spaceType}
              groupMembers={groupMembers}
              user={user}
              onLogin={setUser}
              onLogout={() => setUser(null)}
              isLoggedIn={!!user}
              onEditProfile={() => setShowProfileEditor(true)}
            />
          </aside>
        ) : (
          <Button
            variant="secondary"
            size="icon"
            onClick={() => setLeftPanelVisible(true)}
            className="hidden lg:flex fixed top-20 left-0 z-[70] h-8 w-5 shadow-lg rounded-full bg-card border border-border"
            title="Open panel"
          >
            <ChevronRight className="h-3 w-3" />
          </Button>
        )}

        {/* Left Sidebar - Mobile */}
        <aside
          className={`
            fixed lg:hidden inset-y-0 left-0 z-50
            w-80 bg-card border-r border-border
            transform transition-transform duration-300 ease-in-out
            ${leftSidebarOpen ? 'translate-x-0' : '-translate-x-full'}
            flex flex-col
            mt-16
            h-[calc(100vh-4rem)]
            min-h-0
          `}
        >
          <div className="p-4 border-b border-border flex justify-between items-center">
            <h3>Settings & Guide</h3>
            <Button variant="ghost" size="icon" onClick={() => setLeftSidebarOpen(false)}>
              <X className="h-5 w-5" />
            </Button>
          </div>
          <LeftSidebar
            learningMode={learningMode}
            language={language}
            onLearningModeChange={setLearningMode}
            onLanguageChange={setLanguage}
            spaceType={spaceType}
            groupMembers={groupMembers}
            user={user}
            onLogin={setUser}
            onLogout={() => setUser(null)}
            isLoggedIn={!!user}
            onEditProfile={() => setShowProfileEditor(true)}
          />
        </aside>

        {/* Main Chat Area */}
        <main className="flex-1 flex flex-col min-w-0 min-h-0 h-full">
          <ChatArea
            // ✅ NEW: pass ApiUser down so Message can submit feedback
            user={asApiUser(user)}
            messages={messages}
            onSendMessage={handleSendMessage}
            uploadedFiles={uploadedFiles}
            onFileUpload={handleFileUpload}
            onRemoveFile={handleRemoveFile}
            onFileTypeChange={handleFileTypeChange}
            memoryProgress={memoryProgress}
            isLoggedIn={!!user}
            learningMode={learningMode}
            onClearConversation={handleClearConversation}
            onLearningModeChange={setLearningMode}
            spaceType={spaceType}
          />
        </main>

        {/* Mobile Sidebar Toggle - Right */}
        {rightPanelOpen && (
          <div className="fixed inset-0 bg-black/50 z-40 lg:hidden" onClick={() => setRightPanelOpen(false)} />
        )}

        {/* Right Panel */}
        {rightPanelVisible ? (
          <aside className="hidden lg:flex w-80 bg-card border-l border-border flex-col min-h-0 relative" style={{ height: 'calc(100vh - 4rem)' }}>
            <Button
              variant="secondary"
              size="icon"
              onClick={() => setRightPanelVisible(false)}
              className="absolute top-4 z-[70] h-8 w-5 shadow-lg rounded-full bg-card border border-border"
              style={{ left: '-10px' }}
              title="Close panel"
            >
              <ChevronRight className="h-3 w-3" />
            </Button>
            <RightPanel
              user={user}
              onLogin={setUser}
              onLogout={() => setUser(null)}
              isLoggedIn={!!user}
              onClose={() => setRightPanelVisible(false)}
              exportResult={exportResult}
              setExportResult={setExportResult}
              resultType={resultType}
              setResultType={setResultType}
              onExport={handleExport}
              onSummary={handleSummary}
            />
          </aside>
        ) : (
          <Button
            variant="secondary"
            size="icon"
            onClick={() => setRightPanelVisible(true)}
            className="hidden lg:flex fixed top-20 right-0 z-[70] h-8 w-5 shadow-lg rounded-full bg-card border border-border"
            title="Open panel"
          >
            <ChevronLeft className="h-3 w-3" />
          </Button>
        )}

        {/* Right Panel - Mobile */}
        <aside
          className={`
            fixed lg:hidden inset-y-0 right-0 z-50
            w-80 bg-card border-l border-border
            transform transition-transform duration-300 ease-in-out
            ${rightPanelOpen ? 'translate-x-0' : 'translate-x-full'}
            flex flex-col
            mt-16
            h-[calc(100vh-4rem)]
            min-h-0
          `}
        >
          <div className="p-4 border-b border-border flex justify-between items-center">
            <h3>Account & Actions</h3>
            <Button variant="ghost" size="icon" onClick={() => setRightPanelOpen(false)}>
              <X className="h-5 w-5" />
            </Button>
          </div>
          <RightPanel
            user={user}
            onLogin={setUser}
            onLogout={() => setUser(null)}
            isLoggedIn={!!user}
            onClose={() => setRightPanelVisible(false)}
            exportResult={exportResult}
            setExportResult={setExportResult}
            resultType={resultType}
            setResultType={setResultType}
            onExport={handleExport}
            onSummary={handleSummary}
          />
        </aside>

        {/* Floating Action Buttons - Desktop only, when panel is closed */}
        {!rightPanelVisible && (
          <FloatingActionButtons
            user={user}
            isLoggedIn={!!user}
            onOpenPanel={() => setRightPanelVisible(true)}
            onExport={handleExport}
            onSummary={handleSummary}
          />
        )}
      </div>
    </div>
  );
}

export default App;
