/**
 * WorkspaceEditorPage -- Diff editor for reviewing AI agent file edit proposals.
 *
 * Full-page layout with:
 *   - Header:  back-to-dashboard, accept-all / reject-all
 *   - Tab bar: one tab per pending edit
 *   - Center:  Monaco DiffEditor (original vs. modified)
 *   - Footer:  status bar with counts and file metadata
 */

import React, { useMemo, useState, useEffect, useRef } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { DiffEditor } from '@monaco-editor/react';
import type { editor as monacoEditor } from 'monaco-editor';
import { useInstanceId } from '../../../hooks/useCurrentInstance';
import { useWorkspaceEditor, type EditorFileEdit } from './useWorkspaceEditor';
import { FaArrowLeft, FaCheck, FaTimes, FaCheckDouble, FaBan, FaSync } from 'react-icons/fa';

function _getMonacoLanguage(fileName: string): string {
  const ext = fileName.split('.').pop()?.toLowerCase() || '';
  const langMap: Record<string, string> = {
    js: 'javascript', jsx: 'javascript', ts: 'typescript', tsx: 'typescript',
    py: 'python', json: 'json', html: 'html', css: 'css', md: 'markdown',
    xml: 'xml', yaml: 'yaml', yml: 'yaml', sh: 'shell', sql: 'sql',
    txt: 'plaintext', csv: 'plaintext', log: 'plaintext',
  };
  return langMap[ext] || 'plaintext';
}

function _formatBytes(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}

export const WorkspaceEditorPage: React.FC = () => {
  const instanceId = useInstanceId() || '';
  const navigate = useNavigate();
  const { mandateId, featureCode, instanceId: routeInstanceId } = useParams<{
    mandateId: string; featureCode: string; instanceId: string;
  }>();
  const editor = useWorkspaceEditor(instanceId);

  const activeEdit = useMemo(
    () => editor.edits.find(e => e.id === editor.activeEditId) || null,
    [editor.edits, editor.activeEditId],
  );

  const pendingEdits = useMemo(
    () => editor.edits.filter(e => e.status === 'pending'),
    [editor.edits],
  );

  const _goBack = () => navigate(`/mandates/${mandateId}/${featureCode}/${routeInstanceId}/dashboard`);

  if (!instanceId) {
    return (
      <div style={{ padding: 32, textAlign: 'center', color: '#999' }}>
        Keine Workspace-Instanz ausgewaehlt.
      </div>
    );
  }

  return (
    <div style={{
      display: 'flex', flexDirection: 'column', height: '100%',
      background: 'var(--bg-primary, #fff)',
    }}>
      {/* Header */}
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: '8px 16px', borderBottom: '1px solid var(--border-color, #e0e0e0)',
        background: 'var(--bg-secondary, #f8f9fa)', flexShrink: 0,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <button onClick={_goBack} style={_btnStyle} title="Zurueck zum Dashboard">
            <FaArrowLeft size={14} />
          </button>
          <span style={{ fontWeight: 600, fontSize: 15 }}>
            File Edit Review
          </span>
          <span style={{ fontSize: 13, color: '#888' }}>
            {editor.pendingCount} pending
          </span>
          <button onClick={editor.refresh} style={_btnStyle} title="Aktualisieren">
            <FaSync size={12} />
          </button>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <button
            onClick={editor.acceptAll}
            disabled={editor.pendingCount === 0}
            style={{ ..._actionBtnStyle, background: 'var(--success-color, #4caf50)', color: '#fff' }}
          >
            <FaCheckDouble size={12} /> Accept All
          </button>
          <button
            onClick={editor.rejectAll}
            disabled={editor.pendingCount === 0}
            style={{ ..._actionBtnStyle, background: 'transparent', border: '1px solid var(--border-color, #ccc)' }}
          >
            <FaBan size={12} /> Reject All
          </button>
        </div>
      </div>

      {/* Tab bar */}
      {pendingEdits.length > 0 && (
        <div style={{
          display: 'flex', overflowX: 'auto', flexShrink: 0,
          borderBottom: '1px solid var(--border-color, #e0e0e0)',
          background: 'var(--bg-secondary, #f8f9fa)',
        }}>
          {pendingEdits.map(edit => (
            <_EditorTab
              key={edit.id}
              edit={edit}
              isActive={edit.id === editor.activeEditId}
              onClick={() => editor.setActiveEditId(edit.id)}
            />
          ))}
        </div>
      )}

      {/* Main content */}
      <div style={{ flex: 1, minHeight: 0, position: 'relative' }}>
        {editor.isLoading ? (
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: '#888' }}>
            Lade Aenderungsvorschlaege...
          </div>
        ) : pendingEdits.length === 0 ? (
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', color: '#888', gap: 12 }}>
            <span style={{ fontSize: 48, opacity: 0.3 }}>✓</span>
            <span style={{ fontSize: 16 }}>Keine offenen Aenderungsvorschlaege</span>
            <button onClick={_goBack} style={{ ..._actionBtnStyle, marginTop: 8 }}>
              Zurueck zum Dashboard
            </button>
          </div>
        ) : activeEdit ? (
          <_SafeDiffEditor
            key={activeEdit.id}
            original={activeEdit.oldContent}
            modified={activeEdit.newContent}
            language={_getMonacoLanguage(activeEdit.fileName)}
          />
        ) : null}
      </div>

      {/* Footer / action bar for active edit */}
      {activeEdit && activeEdit.status === 'pending' && (
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '8px 16px', borderTop: '1px solid var(--border-color, #e0e0e0)',
          background: 'var(--bg-secondary, #f8f9fa)', flexShrink: 0,
        }}>
          <div style={{ fontSize: 12, color: '#888', display: 'flex', gap: 16 }}>
            <span>{activeEdit.fileName}</span>
            <span>Original: {_formatBytes(activeEdit.oldContent.length)}</span>
            <span>Geaendert: {_formatBytes(activeEdit.newContent.length)}</span>
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            <button
              onClick={() => editor.acceptEdit(activeEdit.id)}
              style={{ ..._actionBtnStyle, background: 'var(--success-color, #4caf50)', color: '#fff' }}
            >
              <FaCheck size={12} /> Accept
            </button>
            <button
              onClick={() => editor.rejectEdit(activeEdit.id)}
              style={{ ..._actionBtnStyle, border: '1px solid var(--error-color, #f44336)', color: 'var(--error-color, #f44336)' }}
            >
              <FaTimes size={12} /> Reject
            </button>
          </div>
        </div>
      )}
    </div>
  );
};

// ---------------------------------------------------------------------------
// Safe DiffEditor wrapper -- prevents "TextModel got disposed" errors
// by tracking the editor ref and skipping disposal when already torn down.
// ---------------------------------------------------------------------------

const _SafeDiffEditor: React.FC<{
  original: string;
  modified: string;
  language: string;
}> = ({ original, modified, language }) => {
  const editorRef = useRef<monacoEditor.IDiffEditor | null>(null);
  const [ready, setReady] = useState(false);

  useEffect(() => {
    setReady(true);
    return () => {
      if (editorRef.current) {
        try {
          editorRef.current.dispose();
        } catch { /* already disposed */ }
        editorRef.current = null;
      }
    };
  }, []);

  if (!ready) return null;

  return (
    <DiffEditor
      original={original}
      modified={modified}
      language={language}
      theme="vs-dark"
      onMount={(diffEditor) => { editorRef.current = diffEditor; }}
      options={{
        readOnly: true,
        renderSideBySide: true,
        minimap: { enabled: false },
        fontSize: 13,
        lineNumbers: 'on',
        scrollBeyondLastLine: false,
        wordWrap: 'on',
        originalEditable: false,
      }}
    />
  );
};

// ---------------------------------------------------------------------------
// Sub-components
// ---------------------------------------------------------------------------

const _EditorTab: React.FC<{
  edit: EditorFileEdit;
  isActive: boolean;
  onClick: () => void;
}> = ({ edit, isActive, onClick }) => (
  <button
    onClick={onClick}
    style={{
      padding: '6px 16px',
      fontSize: 13,
      border: 'none',
      borderBottom: isActive ? '2px solid var(--primary-color, #1976d2)' : '2px solid transparent',
      background: isActive ? 'var(--bg-primary, #fff)' : 'transparent',
      cursor: 'pointer',
      whiteSpace: 'nowrap',
      color: isActive ? 'var(--text-primary, #333)' : 'var(--text-secondary, #888)',
      fontWeight: isActive ? 600 : 400,
      display: 'flex', alignItems: 'center', gap: 6,
    }}
  >
    <span style={{
      width: 8, height: 8, borderRadius: '50%',
      background: edit.status === 'pending' ? '#ff9800'
        : edit.status === 'accepted' ? '#4caf50' : '#f44336',
      flexShrink: 0,
    }} />
    {edit.fileName}
  </button>
);

// ---------------------------------------------------------------------------
// Shared styles
// ---------------------------------------------------------------------------

const _btnStyle: React.CSSProperties = {
  padding: '6px 8px', borderRadius: 4, border: '1px solid var(--border-color, #ddd)',
  background: 'transparent', cursor: 'pointer', display: 'flex', alignItems: 'center',
};

const _actionBtnStyle: React.CSSProperties = {
  padding: '5px 14px', borderRadius: 4, border: 'none',
  cursor: 'pointer', fontSize: 12, fontWeight: 600,
  display: 'flex', alignItems: 'center', gap: 6,
};

export default WorkspaceEditorPage;
