'use client';

import { useState, useCallback, useRef, useEffect } from 'react';
import { Copy, Check, Download, ChevronDown } from 'lucide-react';
import { StructuredLog } from './index';
import {
  ExportFormat,
  copyToClipboard,
  formatLogsForExport,
  downloadAsFile,
  getExportFileInfo,
} from '@/lib/copy-utils';

export interface CopyToolbarProps {
  logs: StructuredLog[];
  selectedIndices?: Set<number>;
  onCopySuccess?: () => void;
}

const FORMAT_OPTIONS: { value: ExportFormat; label: string }[] = [
  { value: 'text', label: 'Text' },
  { value: 'json', label: 'JSON' },
  { value: 'csv', label: 'CSV' },
];

/**
 * Toast notification component for copy success feedback
 */
function Toast({
  message,
  isVisible,
  onClose,
}: {
  message: string;
  isVisible: boolean;
  onClose: () => void;
}) {
  useEffect(() => {
    if (isVisible) {
      const timer = setTimeout(onClose, 2500);
      return () => clearTimeout(timer);
    }
  }, [isVisible, onClose]);

  if (!isVisible) return null;

  return (
    <div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 z-50 animate-fade-in">
      <div className="flex items-center gap-2 px-3 py-2 bg-green-600 text-white text-sm font-medium rounded-lg shadow-lg whitespace-nowrap">
        <Check className="w-4 h-4" />
        {message}
      </div>
    </div>
  );
}

/**
 * Format dropdown component
 */
function FormatDropdown({
  value,
  onChange,
  disabled,
}: {
  value: ExportFormat;
  onChange: (format: ExportFormat) => void;
  disabled?: boolean;
}) {
  const [isOpen, setIsOpen] = useState(false);
  const dropdownRef = useRef<HTMLDivElement>(null);

  // Close dropdown when clicking outside
  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    }

    if (isOpen) {
      document.addEventListener('mousedown', handleClickOutside);
      return () => document.removeEventListener('mousedown', handleClickOutside);
    }
  }, [isOpen]);

  const selectedOption = FORMAT_OPTIONS.find((opt) => opt.value === value);

  return (
    <div ref={dropdownRef} className="relative">
      <button
        onClick={() => !disabled && setIsOpen(!isOpen)}
        disabled={disabled}
        className={`flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium rounded-md border transition-colors ${
          disabled
            ? 'bg-gray-800 text-gray-500 border-gray-700 cursor-not-allowed'
            : 'bg-gray-700 text-gray-300 border-gray-600 hover:bg-gray-600 hover:text-gray-200'
        }`}
      >
        <span>{selectedOption?.label || 'Text'}</span>
        <ChevronDown className={`w-3.5 h-3.5 transition-transform ${isOpen ? 'rotate-180' : ''}`} />
      </button>

      {isOpen && (
        <div className="absolute top-full left-0 mt-1 z-20 bg-gray-800 border border-gray-600 rounded-lg shadow-lg py-1 min-w-[80px]">
          {FORMAT_OPTIONS.map((option) => (
            <button
              key={option.value}
              onClick={() => {
                onChange(option.value);
                setIsOpen(false);
              }}
              className={`w-full px-3 py-1.5 text-xs text-left transition-colors ${
                value === option.value
                  ? 'bg-blue-600 text-white'
                  : 'text-gray-300 hover:bg-gray-700'
              }`}
            >
              {option.label}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

/**
 * CopyToolbar - Toolbar for copying and exporting logs
 *
 * Features:
 * - Copy All button to copy all logs
 * - Copy Selected button to copy only selected logs
 * - Format dropdown to choose Text, JSON, or CSV
 * - Download button for exporting as file
 * - Toast notification on copy success
 */
export default function CopyToolbar({
  logs,
  selectedIndices = new Set(),
  onCopySuccess,
}: CopyToolbarProps) {
  const [format, setFormat] = useState<ExportFormat>('text');
  const [toastMessage, setToastMessage] = useState<string>('');
  const [showToast, setShowToast] = useState(false);
  const [copyingAll, setCopyingAll] = useState(false);
  const [copyingSelected, setCopyingSelected] = useState(false);

  const hasSelection = selectedIndices.size > 0;
  const hasLogs = logs.length > 0;

  // Get selected logs from indices
  const getSelectedLogs = useCallback((): StructuredLog[] => {
    return logs.filter((_, index) => selectedIndices.has(index));
  }, [logs, selectedIndices]);

  // Show toast notification
  const showToastMessage = useCallback((message: string) => {
    setToastMessage(message);
    setShowToast(true);
  }, []);

  // Handle copy all logs
  const handleCopyAll = useCallback(async () => {
    if (!hasLogs) return;

    setCopyingAll(true);
    try {
      const content = formatLogsForExport(logs, format);
      const success = await copyToClipboard(content);

      if (success) {
        showToastMessage(`Copied ${logs.length} log${logs.length !== 1 ? 's' : ''}`);
        onCopySuccess?.();
      } else {
        showToastMessage('Failed to copy');
      }
    } finally {
      setCopyingAll(false);
    }
  }, [logs, format, hasLogs, showToastMessage, onCopySuccess]);

  // Handle copy selected logs
  const handleCopySelected = useCallback(async () => {
    if (!hasSelection) return;

    setCopyingSelected(true);
    try {
      const selectedLogs = getSelectedLogs();
      const content = formatLogsForExport(selectedLogs, format);
      const success = await copyToClipboard(content);

      if (success) {
        showToastMessage(`Copied ${selectedLogs.length} log${selectedLogs.length !== 1 ? 's' : ''}`);
        onCopySuccess?.();
      } else {
        showToastMessage('Failed to copy');
      }
    } finally {
      setCopyingSelected(false);
    }
  }, [getSelectedLogs, format, hasSelection, showToastMessage, onCopySuccess]);

  // Handle download
  const handleDownload = useCallback(() => {
    const logsToExport = hasSelection ? getSelectedLogs() : logs;
    if (logsToExport.length === 0) return;

    const content = formatLogsForExport(logsToExport, format);
    const { extension, mimeType } = getExportFileInfo(format);
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
    const filename = `logs-${timestamp}.${extension}`;

    downloadAsFile(content, filename, mimeType);
    showToastMessage(`Downloaded ${logsToExport.length} log${logsToExport.length !== 1 ? 's' : ''}`);
  }, [logs, format, hasSelection, getSelectedLogs, showToastMessage]);

  return (
    <div className="relative flex items-center gap-2 px-3 py-2 bg-gray-800 border-b border-gray-700">
      {/* Toast notification */}
      <Toast
        message={toastMessage}
        isVisible={showToast}
        onClose={() => setShowToast(false)}
      />

      {/* Copy All button */}
      <button
        onClick={handleCopyAll}
        disabled={!hasLogs || copyingAll}
        className={`flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium rounded-md transition-colors ${
          hasLogs && !copyingAll
            ? 'bg-blue-600 text-white hover:bg-blue-500'
            : 'bg-gray-700 text-gray-500 cursor-not-allowed'
        }`}
        title="Copy all logs to clipboard"
      >
        {copyingAll ? (
          <span className="w-3.5 h-3.5 border-2 border-white border-t-transparent rounded-full animate-spin" />
        ) : (
          <Copy className="w-3.5 h-3.5" />
        )}
        <span>Copy All</span>
        {hasLogs && (
          <span className="px-1.5 py-0.5 bg-blue-700 rounded text-[10px]">{logs.length}</span>
        )}
      </button>

      {/* Copy Selected button */}
      <button
        onClick={handleCopySelected}
        disabled={!hasSelection || copyingSelected}
        className={`flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium rounded-md transition-colors ${
          hasSelection && !copyingSelected
            ? 'bg-green-600 text-white hover:bg-green-500'
            : 'bg-gray-700 text-gray-500 cursor-not-allowed'
        }`}
        title={hasSelection ? 'Copy selected logs to clipboard' : 'Select logs to copy'}
      >
        {copyingSelected ? (
          <span className="w-3.5 h-3.5 border-2 border-white border-t-transparent rounded-full animate-spin" />
        ) : (
          <Copy className="w-3.5 h-3.5" />
        )}
        <span>Copy Selected</span>
        {hasSelection && (
          <span className="px-1.5 py-0.5 bg-green-700 rounded text-[10px]">
            {selectedIndices.size}
          </span>
        )}
      </button>

      {/* Separator */}
      <div className="w-px h-5 bg-gray-600" />

      {/* Format dropdown */}
      <div className="flex items-center gap-1.5">
        <span className="text-xs text-gray-400">Format:</span>
        <FormatDropdown value={format} onChange={setFormat} disabled={!hasLogs} />
      </div>

      {/* Separator */}
      <div className="w-px h-5 bg-gray-600" />

      {/* Download button */}
      <button
        onClick={handleDownload}
        disabled={!hasLogs && !hasSelection}
        className={`flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium rounded-md transition-colors ${
          hasLogs || hasSelection
            ? 'bg-gray-700 text-gray-300 border border-gray-600 hover:bg-gray-600 hover:text-gray-200'
            : 'bg-gray-800 text-gray-500 border border-gray-700 cursor-not-allowed'
        }`}
        title={hasSelection ? 'Download selected logs as file' : 'Download all logs as file'}
      >
        <Download className="w-3.5 h-3.5" />
        <span>Download</span>
      </button>

      {/* Selection info */}
      {hasSelection && (
        <span className="ml-auto text-xs text-gray-400">
          {selectedIndices.size} of {logs.length} selected
        </span>
      )}
    </div>
  );
}
