/**
 * CodeEditorPage
 * 
 * Main page for the CodeEditor feature.
 * Three-panel layout: FileList (left) | Chat (center) | DiffPreview (right)
 * Files are dragged from FileList into the prompt textarea as @fileName references.
 */

import React, { useState, useRef, useCallback } from 'react';
import { useCurrentInstance } from '../../../hooks/useCurrentInstance';
import { useCodeEditor } from './useCodeEditor';
import { FileListPanel } from './FileListPanel';
import { DiffPreviewPanel } from './DiffPreviewPanel';
import { useResizablePanels } from '../../../hooks/useResizablePanels';
import { Messages } from '../../../components/UiComponents';
import { FaPaperPlane, FaStop, FaRobot, FaEdit } from 'react-icons/fa';
import styles from './CodeEditor.module.css';

export const CodeEditorPage: React.FC = () => {
  const { instance } = useCurrentInstance();
  const instanceId = instance?.id || '';
  const inputRef = useRef<HTMLTextAreaElement>(null);
  const [inputValue, setInputValue] = useState('');
  const [mode, setMode] = useState<'simple' | 'agent'>('simple');
  const [isDragOver, setIsDragOver] = useState(false);

  const {
    messages,
    pendingEdits,
    acceptEdit,
    rejectEdit,
    isProcessing,
    sendMessage,
    stopProcessing,
    files,
    agentProgress,
  } = useCodeEditor(instanceId);

  const {
    leftWidth: fileListWidth,
    handleMouseDown: fileListMouseDown,
    containerRef: outerContainerRef,
    isDragging: isDraggingLeft,
  } = useResizablePanels({
    storageKey: 'codeeditor-filelist-width',
    defaultLeftWidth: 20,
    minLeftWidth: 10,
    maxLeftWidth: 40,
  });

  const {
    leftWidth: chatWidth,
    handleMouseDown: chatMouseDown,
    containerRef: innerContainerRef,
    isDragging: isDraggingRight,
  } = useResizablePanels({
    storageKey: 'codeeditor-chat-width',
    defaultLeftWidth: 60,
    minLeftWidth: 30,
    maxLeftWidth: 80,
  });

  const handleSubmit = useCallback(() => {
    const trimmed = inputValue.trim();
    if (!trimmed || isProcessing) return;
    sendMessage(trimmed, mode);
    setInputValue('');
  }, [inputValue, isProcessing, sendMessage, mode]);

  const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSubmit();
    }
  }, [handleSubmit]);

  const handleDragOver = useCallback((e: React.DragEvent) => {
    if (e.dataTransfer.types.includes('application/x-codeeditor-file')) {
      e.preventDefault();
      e.dataTransfer.dropEffect = 'copy';
      setIsDragOver(true);
    }
  }, []);

  const handleDragLeave = useCallback(() => {
    setIsDragOver(false);
  }, []);

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragOver(false);

    const fileDataStr = e.dataTransfer.getData('application/x-codeeditor-file');
    if (!fileDataStr) return;

    try {
      const fileData = JSON.parse(fileDataStr);
      const tag = `@${fileData.fileName}`;
      const textarea = inputRef.current;
      if (textarea) {
        const pos = textarea.selectionStart || inputValue.length;
        const before = inputValue.slice(0, pos);
        const after = inputValue.slice(pos);
        const spaceBefore = before.length > 0 && !before.endsWith(' ') && !before.endsWith('\n') ? ' ' : '';
        const spaceAfter = after.length > 0 && !after.startsWith(' ') && !after.startsWith('\n') ? ' ' : '';
        const newValue = `${before}${spaceBefore}${tag}${spaceAfter}${after}`;
        setInputValue(newValue);
        requestAnimationFrame(() => {
          const newPos = pos + spaceBefore.length + tag.length + spaceAfter.length;
          textarea.focus();
          textarea.setSelectionRange(newPos, newPos);
        });
      } else {
        setInputValue(prev => prev + (prev && !prev.endsWith(' ') ? ' ' : '') + tag + ' ');
      }
    } catch {
      // ignore malformed drop data
    }
  }, [inputValue]);

  return (
    <div className={styles.container}>
      <div
        className={`${styles.panels} ${isDraggingLeft || isDraggingRight ? styles.dragging : ''}`}
        ref={outerContainerRef}
      >
        {/* Left: File List */}
        <div className={styles.filePanel} style={{ width: `${fileListWidth}%` }}>
          <FileListPanel files={files} />
        </div>

        <div className={styles.divider} onMouseDown={fileListMouseDown} />

        {/* Center + Right */}
        <div className={styles.mainArea} style={{ width: `${100 - fileListWidth}%` }} ref={innerContainerRef}>
          {/* Center: Chat */}
          <div className={styles.chatPanel} style={{ width: `${chatWidth}%` }}>
            <div className={styles.messagesArea}>
              <Messages messages={messages} />

              {agentProgress && isProcessing && (
                <div className={styles.agentProgress}>
                  <FaRobot />
                  <span>
                    Round {agentProgress.round} | {agentProgress.totalToolCalls} tools |{' '}
                    {agentProgress.costCHF.toFixed(4)} CHF
                  </span>
                </div>
              )}
            </div>

            <div className={styles.inputArea}>
              <div className={styles.modeToggle}>
                <button
                  className={`${styles.modeButton} ${mode === 'simple' ? styles.modeActive : ''}`}
                  onClick={() => setMode('simple')}
                  disabled={isProcessing}
                  title="Single AI call -- drag files into prompt as @references"
                >
                  <FaEdit /> Simple
                </button>
                <button
                  className={`${styles.modeButton} ${mode === 'agent' ? styles.modeActive : ''}`}
                  onClick={() => setMode('agent')}
                  disabled={isProcessing}
                  title="AI agent with tools (reads files autonomously, multi-step)"
                >
                  <FaRobot /> Agent
                </button>
              </div>

              <textarea
                ref={inputRef}
                className={`${styles.input} ${isDragOver ? styles.inputDropTarget : ''}`}
                value={inputValue}
                onChange={(e) => setInputValue(e.target.value)}
                onKeyDown={handleKeyDown}
                onDragOver={handleDragOver}
                onDragLeave={handleDragLeave}
                onDrop={handleDrop}
                placeholder={mode === 'agent'
                  ? "Describe a complex task (e.g. 'Document all Python files')..."
                  : "Drag files here and describe changes (e.g. 'In @config.yaml change the port to 8080')..."
                }
                rows={3}
                disabled={isProcessing}
              />
              <div className={styles.inputActions}>
                <span className={styles.fileCount}>
                  {mode === 'simple'
                    ? `Drag files from the list into your prompt`
                    : `Agent mode: AI reads files autonomously`
                  }
                </span>
                {isProcessing ? (
                  <button className={styles.stopButton} onClick={stopProcessing}>
                    <FaStop /> Stop
                  </button>
                ) : (
                  <button
                    className={styles.sendButton}
                    onClick={handleSubmit}
                    disabled={!inputValue.trim()}
                  >
                    <FaPaperPlane /> Send
                  </button>
                )}
              </div>
            </div>
          </div>

          <div className={styles.divider} onMouseDown={chatMouseDown} />

          {/* Right: Diff Preview */}
          <div className={styles.diffPanel} style={{ width: `${100 - chatWidth}%` }}>
            <DiffPreviewPanel
              edits={pendingEdits}
              onAccept={acceptEdit}
              onReject={rejectEdit}
            />
          </div>
        </div>
      </div>
    </div>
  );
};
