import React, { useState, useEffect, useCallback } from 'react';
import Editor from './components/Editor';
import FileList from './components/FileList';
import { useTheme } from './hooks/useTheme';
import { API_URL } from './lib/api';

type File = {
  name: string;
};

function App() {
  const [files, setFiles] = useState<File[]>([]);
  const [currentFile, setCurrentFile] = useState<File | null>(null);
  const [content, setContent] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const { theme, toggleTheme } = useTheme();

  // Fetch files list
  const fetchFiles = useCallback(async () => {
    try {
      setLoading(true);
      const response = await fetch(`${API_URL}/api/files`);
      if (!response.ok) throw new Error('Failed to fetch files');
      const data = await response.json();
      setFiles(data);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to fetch files');
    } finally {
      setLoading(false);
    }
  }, []);

  // Load file content
  const loadFile = useCallback(async (filename: string) => {
    try {
      setLoading(true);
      setError(null);
      const response = await fetch(`${API_URL}/api/files/${filename}`);
      if (!response.ok) throw new Error('Failed to load file');
      const data = await response.json();
      setContent(data);
      setCurrentFile({ name: filename });
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load file');
    } finally {
      setLoading(false);
    }
  }, []);

  // Create new file
  const createFile = async (filename: string, initialContent: string = '') => {
    try {
      setLoading(true);
      setError(null);
      const response = await fetch(`${API_URL}/api/files`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: filename, content: initialContent }),
      });
      if (!response.ok) throw new Error('Failed to create file');
      await fetchFiles();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to create file');
    } finally {
      setLoading(false);
    }
  };

  // Update file content
  const updateFile = async () => {
    if (!currentFile) return;
    try {
      setLoading(true);
      setError(null);
      const response = await fetch(`${API_URL}/api/files/${currentFile.name}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ content }),
      });
      if (!response.ok) throw new Error('Failed to update file');
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to update file');
    } finally {
      setLoading(false);
    }
  };

  // Delete file
  const deleteFile = async (filename: string) => {
    try {
      setLoading(true);
      setError(null);
      const response = await fetch(`${API_URL}/api/files/${filename}`, {
        method: 'DELETE',
      });
      if (!response.ok) throw new Error('Failed to delete file');
      if (currentFile?.name === filename) {
        setCurrentFile(null);
        setContent('');
      }
      await fetchFiles();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to delete file');
    } finally {
      setLoading(false);
    }
  };

  // Sync editor content with server
  useEffect(() => {
    const timeoutId = setTimeout(() => {
      if (currentFile && content) {
        updateFile();
      }
    }, 500);
    return () => clearTimeout(timeoutId);
  }, [content, currentFile, updateFile]);

  // Initial file fetch
  useEffect(() => {
    fetchFiles();
  }, [fetchFiles]);

  return (
    <div className={`min-h-screen bg-primary text-primary ${theme}`}>
      <header className="bg-secondary border-b border-custom p-4">
        <div className="container mx-auto flex items-center justify-between">
          <h1 className="text-2xl font-bold">Markdown Editor</h1>
          <button
            onClick={toggleTheme}
            className="px-4 py-2 rounded-lg bg-primary border border-custom hover:bg-opacity-80 transition"
          >
            {theme === 'dark' ? '☀️ Light' : theme === 'light' ? '🌙 Dark' : '🌗 System'}
          </button>
        </div>
      </header>

      <div className="container mx-auto p-4 flex h-[calc(100vh-73px)]">
        {/* Sidebar - File List */}
        <aside className="w-64 bg-secondary border-r border-custom p-4 overflow-y-auto">
          <div className="flex items-center justify-between mb-4">
            <h2 className="text-lg font-semibold">Files</h2>
            <button
              onClick={() => {
                const filename = prompt('Enter filename (must end with .md):');
                if (filename && filename.endsWith('.md')) {
                  createFile(filename);
                }
              }}
              className="px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600 transition text-sm"
            >
              + New
            </button>
          </div>
          {loading && files.length === 0 ? (
            <p className="text-secondary">Loading...</p>
          ) : (
            <ul className="space-y-2">
              {files.map((file) => (
                <li
                  key={file.name}
                  className={`p-2 rounded cursor-pointer transition ${
                    currentFile?.name === file.name
                      ? 'bg-blue-500 text-white'
                      : 'hover:bg-opacity-80'
                  }`}
                  onClick={() => loadFile(file.name)}
                >
                  <span className="truncate block">{file.name}</span>
                </li>
              ))}
            </ul>
          )}
          {error && (
            <div className="mt-4 p-2 bg-red-100 text-red-600 rounded text-sm">
              {error}
            </div>
          )}
        </aside>

        {/* Main Content - Editor & Preview */}
        <main className="flex-1 overflow-hidden">
          <div className="h-full flex flex-col">
            {/* Editor */}
            <Editor
              content={content}
              onChange={setContent}
              disabled={!currentFile || loading}
            />

            {/* Preview */}
            {currentFile && (
              <div className="flex-1 overflow-y-auto border-t border-custom">
                <div className="bg-primary p-4">
                  <h2 className="text-lg font-semibold mb-4">Preview</h2>
                  <div className="prose max-w-none">
                    <div
                      className="markdown-preview"
                      dangerouslySetInnerHTML={{ __html: content }}
                    />
                  </div>
                </div>
              </div>
            )}
          </div>
        </main>
      </div>
    </div>
  );
}

export default App;
