import { useEffect, useState, useRef } from 'react';
import {
  MDXEditor,
  headingsPlugin,
  listsPlugin,
  quotePlugin,
  thematicBreakPlugin,
  markdownShortcutPlugin,
  linkPlugin,
  linkDialogPlugin,
  imagePlugin,
  tablePlugin,
  codeBlockPlugin,
  codeMirrorPlugin,
  diffSourcePlugin,
  toolbarPlugin,
  UndoRedo,
  BoldItalicUnderlineToggles,
  CodeToggle,
  ListsToggle,
  BlockTypeSelect,
  CreateLink,
  InsertImage,
  InsertTable,
  InsertThematicBreak,
  DiffSourceToggleWrapper,
  type MDXEditorMethods
} from '@mdxeditor/editor';
import '@mdxeditor/editor/style.css';
import '@/styles/mdx-editor-theme.css';
import { useTheme } from '@/components/theme/ThemeProvider';
import { supabase } from '@/integrations/supabase/client';
import { invokeWithTracking } from '@/lib/edgeFunctionTracking';
import { getCloudflareImageUrl } from '@/lib/cloudflareImageUtils';
import { useAutoSave } from '@/hooks/useAutoSave';
import { CheckCircle2, Loader2, AlertCircle } from 'lucide-react';
import { cn } from '@/lib/utils';
import { getErrorMessage } from '@/lib/errorHandler';
import { logger } from '@/lib/logger';

interface MarkdownEditorProps {
  value: string;
  onChange: (value: string) => void;
  onSave?: (value: string) => Promise<void>;
  autoSave?: boolean;
  height?: number;
  placeholder?: string;
}

export function MarkdownEditor({
  value,
  onChange,
  onSave,
  autoSave = false,
  height = 600,
  placeholder = 'Write your content in markdown...'
}: MarkdownEditorProps): React.JSX.Element {
  const { theme } = useTheme();
  const [mounted, setMounted] = useState(false);
  const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>('light');
  const editorRef = useRef<MDXEditorMethods>(null);

  // Resolve "system" theme to actual theme based on OS preference
  useEffect(() => {
    if (theme === 'system') {
      const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
      setResolvedTheme(isDark ? 'dark' : 'light');
    } else {
      setResolvedTheme(theme);
    }
  }, [theme]);

  // Listen for OS theme changes when in system mode
  useEffect(() => {
    if (theme !== 'system') return;

    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    const handler = (e: MediaQueryListEvent): void => {
      setResolvedTheme(e.matches ? 'dark' : 'light');
    };

    mediaQuery.addEventListener('change', handler);
    return () => mediaQuery.removeEventListener('change', handler);
  }, [theme]);

  // Auto-save integration
  const { isSaving, lastSaved, error } = useAutoSave({
    data: value,
    onSave: onSave || (async () => {}),
    debounceMs: 3000,
    enabled: autoSave && !!onSave,
    isValid: value.length > 0
  });

  useEffect(() => {
    setMounted(true);
  }, []);

  // Prevent hydration mismatch
  if (!mounted) {
    return (
      <div 
        className="border border-input rounded-lg bg-muted/50 flex items-center justify-center"
        style={{ height }}
      >
        <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
      </div>
    );
  }

  const getLastSavedText = (): string | null => {
    if (!lastSaved) return null;
    const seconds = Math.floor((Date.now() - lastSaved.getTime()) / 1000);
    if (seconds < 60) return `Saved ${seconds}s ago`;
    const minutes = Math.floor(seconds / 60);
    return `Saved ${minutes}m ago`;
  };

  return (
    <div className="space-y-2">
      <div 
        className="border border-input rounded-lg overflow-hidden"
        style={{ minHeight: height }}
      >
        <MDXEditor
          ref={editorRef}
          className={cn('mdxeditor', resolvedTheme === 'dark' && 'dark-theme')}
          markdown={value}
          onChange={onChange}
          placeholder={placeholder}
          contentEditableClassName="prose dark:prose-invert max-w-none p-4 min-h-[500px] mdx-content-area"
          plugins={[
            headingsPlugin(),
            listsPlugin(),
            quotePlugin(),
            thematicBreakPlugin(),
            markdownShortcutPlugin(),
            linkPlugin(),
            linkDialogPlugin(),
            imagePlugin({
              imageUploadHandler: async (file: File): Promise<string> => {
                try {
                  const formData = new FormData();
                  formData.append('file', file);
                  
                  const { data, error } = await invokeWithTracking(
                    'upload-image',
                    formData,
                    undefined
                  );
                  
                  if (error) throw error;
                  
                  // Return Cloudflare CDN URL
                  const imageUrl = getCloudflareImageUrl((data as { id: string }).id, 'public');
                  if (!imageUrl) throw new Error('Failed to generate image URL');
                  
                  return imageUrl;
                } catch (error: unknown) {
                  logger.error('Image upload failed', { error: getErrorMessage(error) });
                  throw new Error(error instanceof Error ? error.message : 'Failed to upload image');
                }
              }
            }),
            tablePlugin(),
            codeBlockPlugin({ defaultCodeBlockLanguage: 'js' }),
            codeMirrorPlugin({ 
              codeBlockLanguages: { 
                js: 'JavaScript', 
                ts: 'TypeScript', 
                tsx: 'TypeScript (React)',
                jsx: 'JavaScript (React)',
                css: 'CSS', 
                html: 'HTML', 
                python: 'Python',
                bash: 'Bash',
                json: 'JSON',
                sql: 'SQL'
              } 
            }),
            diffSourcePlugin({ viewMode: 'rich-text', diffMarkdown: '' }),
            toolbarPlugin({
              toolbarContents: () => (
                <>
                  <UndoRedo />
                  <BoldItalicUnderlineToggles />
                  <CodeToggle />
                  <BlockTypeSelect />
                  <ListsToggle />
                  <CreateLink />
                  <InsertImage />
                  <InsertTable />
                  <InsertThematicBreak />
                  <DiffSourceToggleWrapper>
                    <span className="text-sm">Source</span>
                  </DiffSourceToggleWrapper>
                </>
              )
            })
          ]}
        />
      </div>
      
      {/* Auto-save status indicator */}
      {autoSave && onSave && (
        <div className="flex items-center gap-2 text-xs text-muted-foreground">
          {isSaving && (
            <>
              <Loader2 className="h-3 w-3 animate-spin" />
              <span>Saving...</span>
            </>
          )}
          {!isSaving && lastSaved && !error && (
            <>
              <CheckCircle2 className="h-3 w-3 text-green-600 dark:text-green-400" />
              <span>{getLastSavedText()}</span>
            </>
          )}
          {error && (
            <>
              <AlertCircle className="h-3 w-3 text-destructive" />
              <span className="text-destructive">Failed to save: {error}</span>
            </>
          )}
        </div>
      )}
      
      {/* Word and character count */}
      <div className="flex justify-between text-xs text-muted-foreground">
        <span>Supports markdown formatting with live preview</span>
        <span>
          {value.split(/\s+/).filter(Boolean).length} words · {value.length} characters
        </span>
      </div>
    </div>
  );
}
