'use client';

import { useState, useRef, useEffect } from 'react';
import { 
  X, Paperclip, ChevronDown, ChevronUp, SendHorizontal, Loader2
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Card, CardContent, CardHeader, CardTitle, CardFooter } from '@/components/ui/card';
import DOMPurify from 'isomorphic-dompurify';
import { Label } from '@/components/ui/label';

// Import ONLY from the centralized formatter
import { 
  formatForwardedEmail, 
  formatReplyEmail,
  formatEmailForReplyOrForward,
  EmailMessage as FormatterEmailMessage,
  sanitizeHtml
} from '@/lib/utils/email-formatter';

/**
 * CENTRAL EMAIL COMPOSER COMPONENT
 * 
 * This is the unified, centralized email composer component used throughout the application.
 * It handles new emails, replies, and forwards with proper text direction.
 * 
 * All code that needs to compose emails should import this component from:
 * @/components/email/ComposeEmail
 * 
 * It uses the centralized email formatter from @/lib/utils/email-formatter.ts
 * for consistent handling of email content and text direction.
 */

// Define EmailMessage interface locally instead of importing from server-only file
interface EmailAddress {
  name: string;
  address: string;
}

interface EmailMessage {
  id: string;
  messageId?: string;
  subject: string;
  from: EmailAddress[];
  to: EmailAddress[];
  cc?: EmailAddress[];
  bcc?: EmailAddress[];
  date: Date | string;
  flags?: {
    seen: boolean;
    flagged: boolean;
    answered: boolean;
    deleted: boolean;
    draft: boolean;
  };
  preview?: string;
  content?: string;
  html?: string;
  text?: string;
  hasAttachments?: boolean;
  attachments?: any[];
  folder?: string;
  size?: number;
  contentFetched?: boolean;
}

// Legacy interface for backward compatibility with old ComposeEmail component
interface LegacyComposeEmailProps {
  showCompose: boolean;
  setShowCompose: (show: boolean) => void;
  composeTo: string;
  setComposeTo: (to: string) => void;
  composeCc: string;
  setComposeCc: (cc: string) => void;
  composeBcc: string;
  setComposeBcc: (bcc: string) => void;
  composeSubject: string;
  setComposeSubject: (subject: string) => void;
  composeBody: string;
  setComposeBody: (body: string) => void;
  showCc: boolean;
  setShowCc: (show: boolean) => void;
  showBcc: boolean;
  setShowBcc: (show: boolean) => void;
  attachments: any[];
  setAttachments: (attachments: any[]) => void;
  handleSend: () => Promise<void>;
  originalEmail?: {
    content: string;
    type: 'reply' | 'reply-all' | 'forward';
  };
  onSend: (email: any) => Promise<void>;
  onCancel: () => void;
  replyTo?: any | null;
  forwardFrom?: any | null;
}

// New interface for the modern ComposeEmail component
interface ComposeEmailProps {
  initialEmail?: EmailMessage | null;
  type?: 'new' | 'reply' | 'reply-all' | 'forward';
  onClose: () => void;
  onSend: (emailData: {
    to: string;
    cc?: string;
    bcc?: string;
    subject: string;
    body: string;
    attachments?: Array<{
      name: string;
      content: string;
      type: string;
    }>;
  }) => Promise<void>;
}

// Union type to handle both new and legacy props
type ComposeEmailAllProps = ComposeEmailProps | LegacyComposeEmailProps;

// Type guard to check if props are legacy
function isLegacyProps(props: ComposeEmailAllProps): props is LegacyComposeEmailProps {
  return 'showCompose' in props && 'setShowCompose' in props;
}

export default function ComposeEmail(props: ComposeEmailAllProps) {
  // Handle legacy props by adapting them to new component
  if (isLegacyProps(props)) {
    return <LegacyAdapter {...props} />;
  }
  
  // Continue with modern implementation for new props
  const { initialEmail, type = 'new', onClose, onSend } = props;
  
  // Email form state
  const [to, setTo] = useState<string>('');
  const [cc, setCc] = useState<string>('');
  const [bcc, setBcc] = useState<string>('');
  const [subject, setSubject] = useState<string>('');
  const [emailContent, setEmailContent] = useState<string>('');
  const [showCc, setShowCc] = useState<boolean>(false);
  const [showBcc, setShowBcc] = useState<boolean>(false);
  const [sending, setSending] = useState<boolean>(false);
  const [attachments, setAttachments] = useState<Array<{
    name: string;
    content: string;
    type: string;
  }>>([]);
  
  // Refs
  const editorRef = useRef<HTMLDivElement>(null);
  const attachmentInputRef = useRef<HTMLInputElement>(null);
  
  // Initialize the form when replying to or forwarding an email
  useEffect(() => {
    if (initialEmail && type !== 'new') {
      try {
        const formatterEmail: FormatterEmailMessage = {
          id: initialEmail.id,
          messageId: initialEmail.messageId,
          subject: initialEmail.subject,
          from: initialEmail.from || [],
          to: initialEmail.to || [],
          cc: initialEmail.cc || [],
          bcc: initialEmail.bcc || [],
          date: initialEmail.date,
          content: initialEmail.content,
          html: initialEmail.html,
          text: initialEmail.text,
          hasAttachments: initialEmail.hasAttachments || false
        };

        if (type === 'forward') {
          // For forwarding, use the dedicated formatter
          const { subject, content } = formatForwardedEmail(formatterEmail);
          setSubject(subject);
          setEmailContent(content);
        } else {
          // For reply/reply-all, use the reply formatter
          const { to, cc, subject, content } = formatReplyEmail(formatterEmail, type as 'reply' | 'reply-all');
          setTo(to);
          if (cc) {
            setCc(cc);
            setShowCc(true);
          }
          setSubject(subject);
          setEmailContent(content);
        }
        
        // For type safety
        const isReplyType = (t: 'new' | 'reply' | 'reply-all' | 'forward'): t is 'reply' | 'reply-all' | 'forward' => 
          t === 'reply' || t === 'reply-all' || t === 'forward';
          
        // Focus editor after initializing content
        setTimeout(() => {
          if (isReplyType(type) && editorRef.current) {
            // For replies/forwards, focus contentEditable
            editorRef.current.focus();
            
            try {
              // Place cursor at the beginning
              const selection = window.getSelection();
              if (selection) {
                const range = document.createRange();
                
                if (editorRef.current.firstChild) {
                  range.setStart(editorRef.current.firstChild, 0);
                  range.collapse(true);
                  
                  selection.removeAllRanges();
                  selection.addRange(range);
                }
              }
            } catch (e) {
              console.error('Error positioning cursor:', e);
            }
          } else {
            // For new emails, focus the textarea
            const textarea = document.querySelector('textarea');
            textarea?.focus();
          }
        }, 100);
      } catch (error) {
        console.error('Error formatting email:', error);
      }
    }
  }, [initialEmail, type]);

  // Handle attachment selection
  const handleAttachmentClick = () => {
    attachmentInputRef.current?.click();
  };

  // Process selected files
  const handleFileSelection = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (!files || files.length === 0) return;

    // Read files as data URLs
    for (const file of files) {
      const reader = new FileReader();
      
      reader.onload = (event) => {
        const content = event.target?.result as string;
        
        setAttachments(current => [
          ...current,
          {
            name: file.name,
            content: content.split(',')[1], // Remove data:mime/type;base64, prefix
            type: file.type
          }
        ]);
      };
      
      reader.readAsDataURL(file);
    }
    
    // Reset file input
    if (e.target) {
      e.target.value = '';
    }
  };

  // Remove attachment
  const removeAttachment = (index: number) => {
    setAttachments(current => current.filter((_, i) => i !== index));
  };

  // Handle editor input
  const handleEditorInput = () => {
    if (!editorRef.current) return;
    
    // Store the current selection/cursor position
    const selection = window.getSelection();
    const range = selection?.getRangeAt(0);
    const offset = range?.startOffset || 0;
    const container = range?.startContainer;
    
    // Capture the content
    setEmailContent(editorRef.current.innerHTML);
    
    // Try to restore the cursor position after React updates
    setTimeout(() => {
      if (!selection || !range || !container || !editorRef.current) return;
      
      try {
        if (editorRef.current.contains(container)) {
          const newRange = document.createRange();
          newRange.setStart(container, offset);
          newRange.collapse(true);
          selection.removeAllRanges();
          selection.addRange(newRange);
        }
      } catch (e) {
        console.error('Error restoring cursor position:', e);
      }
    }, 0);
  };

  // Add a handler for textarea changes
  const handleTextareaChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    setEmailContent(e.target.value);
  };

  // Send email
  const handleSend = async () => {
    if (!to) {
      alert('Please specify at least one recipient');
      return;
    }

    try {
      setSending(true);
      
      // For new emails, emailContent is already set via onChange
      // For replies/forwards, we need to get content from editorRef
      const finalContent = type === 'new' 
        ? emailContent 
        : editorRef.current?.innerHTML || emailContent;
      
      await onSend({
        to,
        cc: cc || undefined,
        bcc: bcc || undefined,
        subject,
        body: finalContent,
        attachments
      });
      
      onClose();
    } catch (error) {
      console.error('Error sending email:', error);
      alert('Failed to send email. Please try again.');
    } finally {
      setSending(false);
    }
  };

  return (
    <Card className="w-full max-w-4xl mx-auto">
      <CardHeader>
        <CardTitle className="flex items-center justify-between">
          <span>{type === 'new' ? 'New Message' : type === 'forward' ? 'Forward Email' : 'Reply to Email'}</span>
          <Button variant="ghost" size="icon" onClick={onClose}>
            <X className="h-5 w-5" />
          </Button>
        </CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        {/* Recipients, Subject fields */}
        <div className="p-3 border-b space-y-2">
          <div className="flex items-center">
            <span className="w-16 text-sm font-medium">To:</span>
            <Input 
              value={to} 
              onChange={(e) => setTo(e.target.value)} 
              className="flex-1 border-0 shadow-none h-8 focus-visible:ring-0"
              placeholder="recipient@example.com"
            />
          </div>
          
          {showCc && (
            <div className="flex items-center">
              <span className="w-16 text-sm font-medium">Cc:</span>
              <Input 
                value={cc} 
                onChange={(e) => setCc(e.target.value)} 
                className="flex-1 border-0 shadow-none h-8 focus-visible:ring-0"
                placeholder="cc@example.com"
              />
            </div>
          )}
          
          {showBcc && (
            <div className="flex items-center">
              <span className="w-16 text-sm font-medium">Bcc:</span>
              <Input 
                value={bcc} 
                onChange={(e) => setBcc(e.target.value)} 
                className="flex-1 border-0 shadow-none h-8 focus-visible:ring-0"
                placeholder="bcc@example.com"
              />
            </div>
          )}
          
          {/* CC/BCC controls */}
          <div className="flex items-center text-xs">
            <button 
              className="text-primary hover:underline mr-3 flex items-center"
              onClick={() => setShowCc(!showCc)}
            >
              {showCc ? (
                <>
                  <ChevronUp className="h-3 w-3 mr-0.5" />
                  Hide Cc
                </>
              ) : (
                <>
                  <ChevronDown className="h-3 w-3 mr-0.5" />
                  Show Cc
                </>
              )}
            </button>
            
            <button 
              className="text-primary hover:underline flex items-center"
              onClick={() => setShowBcc(!showBcc)}
            >
              {showBcc ? (
                <>
                  <ChevronUp className="h-3 w-3 mr-0.5" />
                  Hide Bcc
                </>
              ) : (
                <>
                  <ChevronDown className="h-3 w-3 mr-0.5" />
                  Show Bcc
                </>
              )}
            </button>
          </div>
          
          <div className="flex items-center">
            <span className="w-16 text-sm font-medium">Subject:</span>
            <Input 
              value={subject} 
              onChange={(e) => setSubject(e.target.value)} 
              className="flex-1 border-0 shadow-none h-8 focus-visible:ring-0"
              placeholder="Subject"
            />
          </div>
        </div>
        
        {/* Email Body Editor - different approach based on type */}
        <div className="space-y-2">
          <div className="flex items-center justify-between">
            <label htmlFor="body" className="text-sm font-medium">Message</label>
          </div>
          
          {/* For new emails, use textarea for better text direction */}
          {type === 'new' ? (
            <div className="border rounded-md overflow-hidden">
              <textarea
                value={emailContent}
                onChange={handleTextareaChange}
                className="w-full p-4 min-h-[300px] focus:outline-none resize-none"
                placeholder="Write your message here..."
                disabled={sending}
              />
            </div>
          ) : (
            /* For replies and forwards, use contentEditable to preserve formatting */
            <div className="border rounded-md overflow-hidden">
              <div
                ref={editorRef}
                contentEditable={!sending}
                className="w-full p-4 min-h-[300px] focus:outline-none"
                onInput={handleEditorInput}
                dangerouslySetInnerHTML={{ __html: emailContent }}
                dir="rtl"
                style={{ 
                  textAlign: 'right',
                }}
              />
            </div>
          )}
        </div>
        
        {/* Attachments section */}
        {attachments.length > 0 && (
          <div className="border-t p-2">
            <div className="text-sm font-medium mb-1">Attachments:</div>
            <div className="flex flex-wrap gap-2">
              {attachments.map((attachment, index) => (
                <div key={index} className="flex items-center gap-1 text-sm bg-muted px-2 py-1 rounded">
                  <Paperclip className="h-3 w-3" />
                  <span>{attachment.name}</span>
                  <button 
                    onClick={() => removeAttachment(index)}
                    className="ml-1 text-muted-foreground hover:text-destructive"
                  >
                    <X className="h-3 w-3" />
                  </button>
                </div>
              ))}
            </div>
          </div>
        )}
      </CardContent>
      
      <CardFooter className="border-t p-3 flex justify-between">
        <div>
          <input
            type="file"
            ref={attachmentInputRef}
            className="hidden"
            onChange={handleFileSelection}
            multiple
          />
          <Button
            variant="outline"
            size="sm"
            onClick={handleAttachmentClick}
          >
            <Paperclip className="h-4 w-4 mr-1" />
            Attach
          </Button>
        </div>
        
        <Button 
          size="sm" 
          onClick={handleSend}
          disabled={sending}
        >
          {sending ? (
            <>
              <Loader2 className="h-4 w-4 mr-1 animate-spin" />
              Sending...
            </>
          ) : (
            <>
              <SendHorizontal className="h-4 w-4 mr-1" />
              Send
            </>
          )}
        </Button>
      </CardFooter>
    </Card>
  );
}

// Adapter component for legacy props
function LegacyAdapter({
  showCompose,
  setShowCompose,
  composeTo,
  setComposeTo,
  composeCc,
  setComposeCc,
  composeBcc,
  setComposeBcc,
  composeSubject,
  setComposeSubject,
  composeBody,
  setComposeBody,
  showCc,
  setShowCc,
  showBcc,
  setShowBcc,
  attachments,
  setAttachments,
  handleSend,
  originalEmail,
  onSend,
  onCancel,
  replyTo,
  forwardFrom
}: LegacyComposeEmailProps) {
  // Create a ref for the contentEditable div
  const composeBodyRef = useRef<HTMLDivElement>(null);
  
  // Set the content of the contentEditable div on mount
  useEffect(() => {
    if (composeBodyRef.current && composeBody) {
      composeBodyRef.current.innerHTML = composeBody;
    }
  }, [composeBody, showCompose]);
  
  // Handle clicking the content editable area
  const handleComposeAreaClick = () => {
    composeBodyRef.current?.focus();
  };
  
  // Handle input events on the contentEditable div
  const handleInput = () => {
    if (composeBodyRef.current) {
      setComposeBody(composeBodyRef.current.innerHTML);
    }
  };
  
  // Handle file attachment
  const handleFileAttachment = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (!e.target.files || e.target.files.length === 0) return;
    
    // Here you would normally process the files and add them to attachments
    console.log('Files selected:', e.target.files);
    
    // Just a placeholder - in a real implementation you'd convert files to the format needed
    const newAttachments = Array.from(e.target.files).map(file => ({
      name: file.name,
      type: file.type,
      size: file.size,
      // In a real implementation you'd use FileReader to read the file content
    }));
    
    // Add to existing attachments
    setAttachments([...attachments, ...newAttachments]);
  };
  
  // Handle send email action
  const handleSendEmail = async () => {
    // Call the provided onSend handler with the email data
    await onSend({
      to: composeTo,
      cc: composeCc,
      bcc: composeBcc,
      subject: composeSubject,
      body: composeBody,
      attachments
    });
  };
  
  if (!showCompose) return null;
  
  return (
    <div className="fixed inset-0 bg-gray-600/30 backdrop-blur-sm z-50 flex items-center justify-center">
      <div className="w-full max-w-2xl h-[90vh] bg-white rounded-xl shadow-xl flex flex-col mx-4">
        {/* Modal Header */}
        <div className="flex-none flex items-center justify-between px-6 py-3 border-b border-gray-200">
          <h3 className="text-lg font-semibold text-gray-900">
            {replyTo ? 'Reply' : forwardFrom ? 'Forward' : 'New Message'}
          </h3>
          <Button
            variant="ghost"
            size="icon"
            className="hover:bg-gray-100 rounded-full"
            onClick={onCancel}
          >
            <X className="h-5 w-5 text-gray-500" />
          </Button>
        </div>

        {/* Modal Body */}
        <div className="flex-1 overflow-hidden">
          <div className="h-full flex flex-col p-6 space-y-4 overflow-y-auto">
            {/* To Field */}
            <div className="flex-none">
              <Label htmlFor="to" className="block text-sm font-medium text-gray-700">To</Label>
              <Input
                id="to"
                value={composeTo}
                onChange={(e) => setComposeTo(e.target.value)}
                placeholder="recipient@example.com"
                className="w-full mt-1 bg-white border-gray-300 text-gray-900"
              />
            </div>

            {/* CC/BCC Toggle Buttons */}
            <div className="flex-none flex items-center gap-4">
              <button
                type="button"
                className="text-blue-600 hover:text-blue-700 text-sm font-medium"
                onClick={() => setShowCc(!showCc)}
              >
                {showCc ? 'Hide Cc' : 'Add Cc'}
              </button>
              <button
                type="button"
                className="text-blue-600 hover:text-blue-700 text-sm font-medium"
                onClick={() => setShowBcc(!showBcc)}
              >
                {showBcc ? 'Hide Bcc' : 'Add Bcc'}
              </button>
            </div>

            {/* CC Field */}
            {showCc && (
              <div className="flex-none">
                <Label htmlFor="cc" className="block text-sm font-medium text-gray-700">Cc</Label>
                <Input
                  id="cc"
                  value={composeCc}
                  onChange={(e) => setComposeCc(e.target.value)}
                  placeholder="cc@example.com"
                  className="w-full mt-1 bg-white border-gray-300 text-gray-900"
                />
              </div>
            )}

            {/* BCC Field */}
            {showBcc && (
              <div className="flex-none">
                <Label htmlFor="bcc" className="block text-sm font-medium text-gray-700">Bcc</Label>
                <Input
                  id="bcc"
                  value={composeBcc}
                  onChange={(e) => setComposeBcc(e.target.value)}
                  placeholder="bcc@example.com"
                  className="w-full mt-1 bg-white border-gray-300 text-gray-900"
                />
              </div>
            )}

            {/* Subject Field */}
            <div className="flex-none">
              <Label htmlFor="subject" className="block text-sm font-medium text-gray-700">Subject</Label>
              <Input
                id="subject"
                value={composeSubject}
                onChange={(e) => setComposeSubject(e.target.value)}
                placeholder="Enter subject"
                className="w-full mt-1 bg-white border-gray-300 text-gray-900"
              />
            </div>

            {/* Message Body */}
            <div className="flex-1 min-h-[200px] flex flex-col">
              <Label htmlFor="message" className="flex-none block text-sm font-medium text-gray-700 mb-2">Message</Label>
              <div
                ref={composeBodyRef}
                contentEditable="true"
                onInput={handleInput}
                onClick={handleComposeAreaClick}
                className="flex-1 w-full bg-white border border-gray-300 rounded-md p-4 text-black overflow-y-auto focus:outline-none focus:ring-1 focus:ring-blue-500"
                style={{ 
                  direction: 'ltr',
                  maxHeight: 'calc(100vh - 400px)',
                  minHeight: '200px',
                  overflowY: 'auto',
                  scrollbarWidth: 'thin',
                  scrollbarColor: '#cbd5e0 #f3f4f6',
                  cursor: 'text'
                }}
                dir="ltr"
                spellCheck="true"
                role="textbox"
                aria-multiline="true"
                tabIndex={0}
                suppressContentEditableWarning={true}
              />
            </div>
          </div>
        </div>

        {/* Modal Footer */}
        <div className="flex-none flex items-center justify-between px-6 py-3 border-t border-gray-200 bg-white">
          <div className="flex items-center gap-2">
            {/* File Input for Attachments */}
            <input
              type="file"
              id="file-attachment"
              className="hidden"
              multiple
              onChange={handleFileAttachment}
            />
            <label htmlFor="file-attachment">
              <Button 
                variant="outline" 
                size="icon"
                className="rounded-full bg-white hover:bg-gray-100 border-gray-300"
                onClick={(e) => {
                  e.preventDefault();
                  document.getElementById('file-attachment')?.click();
                }}
              >
                <Paperclip className="h-4 w-4 text-gray-600" />
              </Button>
            </label>
          </div>
          <div className="flex items-center gap-3">
            <Button 
              variant="ghost"
              className="text-gray-600 hover:text-gray-700 hover:bg-gray-100"
              onClick={onCancel}
            >
              Cancel
            </Button>
            <Button
              className="bg-blue-600 text-white hover:bg-blue-700"
              onClick={handleSendEmail}
            >
              Send
            </Button>
          </div>
        </div>
      </div>
    </div>
  );
} 