/**
 * FineTuningPanel Component
 * Fine-tuning interface for LLM models (UI only, backend mock)
 * OQI-007: LLM Strategy Agent - SUBTASK-008
 */

import React, { useState, useRef, useMemo } from 'react';
import {
  AcademicCapIcon,
  CloudArrowUpIcon,
  PlayIcon,
  StopIcon,
  CheckCircleIcon,
  XCircleIcon,
  ClockIcon,
  ChartBarIcon,
  ArrowPathIcon,
  DocumentTextIcon,
  TrashIcon,
  InformationCircleIcon,
  ExclamationTriangleIcon,
  ArrowDownTrayIcon,
  EyeIcon,
  ScaleIcon,
} from '@heroicons/react/24/outline';

// ============================================================================
// Types
// ============================================================================

export interface BaseModel {
  id: string;
  name: string;
  provider: string;
  description: string;
  contextWindow: number;
  costPerMToken: number;
  supportsFinetuning: boolean;
}

export interface TrainingDataset {
  id: string;
  name: string;
  fileName: string;
  sampleCount: number;
  sizeKB: number;
  format: 'jsonl' | 'csv' | 'json';
  uploadedAt: string;
  validationStatus: 'pending' | 'valid' | 'invalid';
  validationErrors?: string[];
}

export interface FineTunedModel {
  id: string;
  name: string;
  baseModelId: string;
  baseModelName: string;
  status: 'training' | 'completed' | 'failed' | 'cancelled';
  progress: number;
  createdAt: string;
  completedAt?: string;
  trainingLoss?: number;
  validationLoss?: number;
  epochs: number;
  trainingSamples: number;
  estimatedCost: number;
  metrics?: {
    accuracy?: number;
    f1Score?: number;
    perplexity?: number;
  };
}

export interface TrainingConfig {
  epochs: number;
  batchSize: number;
  learningRate: number;
  warmupSteps: number;
  validationSplit: number;
}

interface FineTuningPanelProps {
  baseModels: BaseModel[];
  datasets: TrainingDataset[];
  fineTunedModels: FineTunedModel[];
  onUploadDataset?: (file: File) => void;
  onDeleteDataset?: (datasetId: string) => void;
  onStartTraining?: (config: {
    baseModelId: string;
    datasetId: string;
    name: string;
    config: TrainingConfig;
  }) => void;
  onCancelTraining?: (modelId: string) => void;
  onDownloadModel?: (modelId: string) => void;
  onDeleteModel?: (modelId: string) => void;
  isLoading?: boolean;
}

// ============================================================================
// Constants
// ============================================================================

const DEFAULT_TRAINING_CONFIG: TrainingConfig = {
  epochs: 3,
  batchSize: 4,
  learningRate: 0.0001,
  warmupSteps: 100,
  validationSplit: 0.1,
};

// ============================================================================
// Sub-Components
// ============================================================================

interface DatasetCardProps {
  dataset: TrainingDataset;
  onDelete?: () => void;
  isSelected?: boolean;
  onSelect?: () => void;
}

const DatasetCard: React.FC<DatasetCardProps> = ({ dataset, onDelete, isSelected, onSelect }) => {
  const statusColors = {
    pending: 'text-yellow-500 bg-yellow-500/10',
    valid: 'text-emerald-500 bg-emerald-500/10',
    invalid: 'text-red-500 bg-red-500/10',
  };

  const StatusIcon = {
    pending: ClockIcon,
    valid: CheckCircleIcon,
    invalid: XCircleIcon,
  }[dataset.validationStatus];

  return (
    <div
      onClick={onSelect}
      className={`p-3 rounded-lg border-2 cursor-pointer transition-all ${
        isSelected
          ? 'border-primary-500 bg-primary-50 dark:bg-primary-900/20'
          : 'border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600'
      }`}
    >
      <div className="flex items-start gap-3">
        <div className={`p-2 rounded-lg ${statusColors[dataset.validationStatus]}`}>
          <DocumentTextIcon className="w-4 h-4" />
        </div>
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2">
            <h4 className="font-medium text-gray-900 dark:text-white text-sm truncate">{dataset.name}</h4>
            <span className={`px-1.5 py-0.5 text-xs rounded flex items-center gap-1 ${statusColors[dataset.validationStatus]}`}>
              <StatusIcon className="w-3 h-3" />
              {dataset.validationStatus}
            </span>
          </div>
          <p className="text-xs text-gray-500 mt-0.5">{dataset.fileName}</p>
          <div className="flex items-center gap-3 mt-1 text-xs text-gray-400">
            <span>{dataset.sampleCount.toLocaleString()} samples</span>
            <span>{(dataset.sizeKB / 1024).toFixed(2)} MB</span>
            <span>{dataset.format.toUpperCase()}</span>
          </div>
          {dataset.validationErrors && dataset.validationErrors.length > 0 && (
            <div className="mt-2 p-2 bg-red-50 dark:bg-red-900/20 rounded text-xs text-red-600 dark:text-red-400">
              {dataset.validationErrors[0]}
              {dataset.validationErrors.length > 1 && ` (+${dataset.validationErrors.length - 1} more)`}
            </div>
          )}
        </div>
        {onDelete && (
          <button
            onClick={(e) => { e.stopPropagation(); onDelete(); }}
            className="p-1.5 text-gray-400 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg"
          >
            <TrashIcon className="w-4 h-4" />
          </button>
        )}
      </div>
    </div>
  );
};

interface ModelComparisonCardProps {
  model: FineTunedModel;
  onCancel?: () => void;
  onDownload?: () => void;
  onDelete?: () => void;
}

const ModelComparisonCard: React.FC<ModelComparisonCardProps> = ({ model, onCancel, onDownload, onDelete }) => {
  const statusColors = {
    training: 'text-blue-500 bg-blue-500/10 border-blue-500/30',
    completed: 'text-emerald-500 bg-emerald-500/10 border-emerald-500/30',
    failed: 'text-red-500 bg-red-500/10 border-red-500/30',
    cancelled: 'text-gray-500 bg-gray-500/10 border-gray-500/30',
  };

  const StatusIcon = {
    training: ArrowPathIcon,
    completed: CheckCircleIcon,
    failed: XCircleIcon,
    cancelled: StopIcon,
  }[model.status];

  return (
    <div className={`rounded-xl border ${statusColors[model.status]} overflow-hidden`}>
      {/* Header */}
      <div className="p-4 border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800">
        <div className="flex items-start justify-between">
          <div>
            <h4 className="font-semibold text-gray-900 dark:text-white">{model.name}</h4>
            <p className="text-xs text-gray-500 mt-0.5">Base: {model.baseModelName}</p>
          </div>
          <div className={`px-2 py-1 rounded-lg flex items-center gap-1.5 text-xs ${statusColors[model.status]}`}>
            <StatusIcon className={`w-3.5 h-3.5 ${model.status === 'training' ? 'animate-spin' : ''}`} />
            {model.status}
          </div>
        </div>

        {/* Progress Bar (if training) */}
        {model.status === 'training' && (
          <div className="mt-3">
            <div className="flex items-center justify-between text-xs text-gray-500 mb-1">
              <span>Training Progress</span>
              <span>{model.progress}%</span>
            </div>
            <div className="h-2 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden">
              <div
                className="h-full bg-blue-500 transition-all"
                style={{ width: `${model.progress}%` }}
              />
            </div>
          </div>
        )}
      </div>

      {/* Metrics */}
      <div className="p-4 grid grid-cols-2 gap-3 bg-gray-50 dark:bg-gray-900">
        <div>
          <div className="text-xs text-gray-500 mb-1">Training Loss</div>
          <div className="text-lg font-bold text-gray-900 dark:text-white">
            {model.trainingLoss?.toFixed(4) || '-'}
          </div>
        </div>
        <div>
          <div className="text-xs text-gray-500 mb-1">Validation Loss</div>
          <div className="text-lg font-bold text-gray-900 dark:text-white">
            {model.validationLoss?.toFixed(4) || '-'}
          </div>
        </div>
        {model.metrics?.accuracy !== undefined && (
          <div>
            <div className="text-xs text-gray-500 mb-1">Accuracy</div>
            <div className="text-lg font-bold text-emerald-500">
              {(model.metrics.accuracy * 100).toFixed(1)}%
            </div>
          </div>
        )}
        {model.metrics?.f1Score !== undefined && (
          <div>
            <div className="text-xs text-gray-500 mb-1">F1 Score</div>
            <div className="text-lg font-bold text-blue-500">
              {model.metrics.f1Score.toFixed(3)}
            </div>
          </div>
        )}
        <div>
          <div className="text-xs text-gray-500 mb-1">Epochs</div>
          <div className="text-lg font-bold text-gray-900 dark:text-white">{model.epochs}</div>
        </div>
        <div>
          <div className="text-xs text-gray-500 mb-1">Samples</div>
          <div className="text-lg font-bold text-gray-900 dark:text-white">
            {model.trainingSamples.toLocaleString()}
          </div>
        </div>
      </div>

      {/* Footer */}
      <div className="p-3 border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 flex items-center justify-between">
        <div className="text-xs text-gray-500">
          Cost: <span className="font-medium text-gray-900 dark:text-white">${model.estimatedCost.toFixed(2)}</span>
        </div>
        <div className="flex items-center gap-1">
          {model.status === 'training' && onCancel && (
            <button
              onClick={onCancel}
              className="px-2 py-1 text-xs text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded"
            >
              Cancel
            </button>
          )}
          {model.status === 'completed' && onDownload && (
            <button
              onClick={onDownload}
              className="p-1.5 text-gray-400 hover:text-primary-500 hover:bg-primary-50 dark:hover:bg-primary-900/20 rounded-lg"
            >
              <ArrowDownTrayIcon className="w-4 h-4" />
            </button>
          )}
          {(model.status === 'completed' || model.status === 'failed' || model.status === 'cancelled') && onDelete && (
            <button
              onClick={onDelete}
              className="p-1.5 text-gray-400 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg"
            >
              <TrashIcon className="w-4 h-4" />
            </button>
          )}
        </div>
      </div>
    </div>
  );
};

// ============================================================================
// Main Component
// ============================================================================

export const FineTuningPanel: React.FC<FineTuningPanelProps> = ({
  baseModels,
  datasets,
  fineTunedModels,
  onUploadDataset,
  onDeleteDataset,
  onStartTraining,
  onCancelTraining,
  onDownloadModel,
  onDeleteModel,
  isLoading = false,
}) => {
  const [activeTab, setActiveTab] = useState<'create' | 'models'>('create');
  const [selectedBaseModel, setSelectedBaseModel] = useState<string>('');
  const [selectedDataset, setSelectedDataset] = useState<string>('');
  const [modelName, setModelName] = useState('');
  const [trainingConfig, setTrainingConfig] = useState<TrainingConfig>(DEFAULT_TRAINING_CONFIG);
  const [showAdvanced, setShowAdvanced] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const supportedModels = baseModels.filter((m) => m.supportsFinetuning);
  const validDatasets = datasets.filter((d) => d.validationStatus === 'valid');
  const trainingModels = fineTunedModels.filter((m) => m.status === 'training');

  const canStartTraining = selectedBaseModel && selectedDataset && modelName.trim() && !isLoading;

  const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file && onUploadDataset) {
      onUploadDataset(file);
    }
    if (fileInputRef.current) {
      fileInputRef.current.value = '';
    }
  };

  const handleStartTraining = () => {
    if (!canStartTraining || !onStartTraining) return;
    onStartTraining({
      baseModelId: selectedBaseModel,
      datasetId: selectedDataset,
      name: modelName.trim(),
      config: trainingConfig,
    });
    setModelName('');
    setSelectedDataset('');
  };

  const estimatedCost = useMemo(() => {
    if (!selectedBaseModel || !selectedDataset) return 0;
    const model = baseModels.find((m) => m.id === selectedBaseModel);
    const dataset = datasets.find((d) => d.id === selectedDataset);
    if (!model || !dataset) return 0;
    const tokensPerSample = 500;
    const totalTokens = dataset.sampleCount * tokensPerSample * trainingConfig.epochs;
    return (totalTokens / 1000000) * model.costPerMToken * 10;
  }, [selectedBaseModel, selectedDataset, trainingConfig.epochs, baseModels, datasets]);

  return (
    <div className="bg-white dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden">
      {/* Header */}
      <div className="p-4 border-b border-gray-200 dark:border-gray-700">
        <div className="flex items-center justify-between mb-3">
          <div className="flex items-center gap-2">
            <AcademicCapIcon className="w-5 h-5 text-primary-500" />
            <h3 className="font-semibold text-gray-900 dark:text-white">Fine-Tuning</h3>
          </div>
          {trainingModels.length > 0 && (
            <span className="px-2 py-1 text-xs bg-blue-500/10 text-blue-500 rounded-full flex items-center gap-1">
              <ArrowPathIcon className="w-3 h-3 animate-spin" />
              {trainingModels.length} training
            </span>
          )}
        </div>

        {/* Stats */}
        <div className="grid grid-cols-3 gap-3">
          <div className="p-3 bg-gray-50 dark:bg-gray-800 rounded-lg text-center">
            <div className="text-xl font-bold text-gray-900 dark:text-white">{datasets.length}</div>
            <div className="text-xs text-gray-500">Datasets</div>
          </div>
          <div className="p-3 bg-gray-50 dark:bg-gray-800 rounded-lg text-center">
            <div className="text-xl font-bold text-gray-900 dark:text-white">{fineTunedModels.length}</div>
            <div className="text-xs text-gray-500">Models</div>
          </div>
          <div className="p-3 bg-gray-50 dark:bg-gray-800 rounded-lg text-center">
            <div className="text-xl font-bold text-emerald-500">
              {fineTunedModels.filter((m) => m.status === 'completed').length}
            </div>
            <div className="text-xs text-gray-500">Ready</div>
          </div>
        </div>
      </div>

      {/* Tabs */}
      <div className="flex border-b border-gray-200 dark:border-gray-700">
        <button
          onClick={() => setActiveTab('create')}
          className={`flex-1 flex items-center justify-center gap-2 py-3 text-sm font-medium border-b-2 transition-colors ${
            activeTab === 'create'
              ? 'border-primary-500 text-primary-500'
              : 'border-transparent text-gray-500'
          }`}
        >
          <PlayIcon className="w-4 h-4" />
          New Training
        </button>
        <button
          onClick={() => setActiveTab('models')}
          className={`flex-1 flex items-center justify-center gap-2 py-3 text-sm font-medium border-b-2 transition-colors ${
            activeTab === 'models'
              ? 'border-primary-500 text-primary-500'
              : 'border-transparent text-gray-500'
          }`}
        >
          <ScaleIcon className="w-4 h-4" />
          Compare Models ({fineTunedModels.length})
        </button>
      </div>

      {/* Create Training Tab */}
      {activeTab === 'create' && (
        <div className="p-4 space-y-4">
          {/* Model Selection */}
          <div>
            <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
              Base Model
            </label>
            <select
              value={selectedBaseModel}
              onChange={(e) => setSelectedBaseModel(e.target.value)}
              className="w-full px-3 py-2.5 bg-gray-100 dark:bg-gray-800 border-0 rounded-lg text-gray-900 dark:text-white focus:ring-2 focus:ring-primary-500"
            >
              <option value="">Select a model...</option>
              {supportedModels.map((model) => (
                <option key={model.id} value={model.id}>
                  {model.name} ({model.provider}) - ${model.costPerMToken}/MTok
                </option>
              ))}
            </select>
            {selectedBaseModel && (
              <p className="mt-1 text-xs text-gray-500">
                {baseModels.find((m) => m.id === selectedBaseModel)?.description}
              </p>
            )}
          </div>

          {/* Dataset Upload & Selection */}
          <div>
            <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
              Training Dataset
            </label>
            <input
              type="file"
              ref={fileInputRef}
              onChange={handleFileUpload}
              accept=".jsonl,.csv,.json"
              className="hidden"
            />
            <button
              onClick={() => fileInputRef.current?.click()}
              disabled={!onUploadDataset}
              className="w-full mb-2 p-4 border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-lg flex items-center justify-center gap-2 text-gray-500 hover:border-primary-500 hover:text-primary-500 transition-colors disabled:opacity-50"
            >
              <CloudArrowUpIcon className="w-5 h-5" />
              <span className="text-sm">Upload dataset (JSONL, CSV, JSON)</span>
            </button>
            {datasets.length > 0 && (
              <div className="space-y-2 max-h-48 overflow-y-auto">
                {datasets.map((dataset) => (
                  <DatasetCard
                    key={dataset.id}
                    dataset={dataset}
                    isSelected={selectedDataset === dataset.id}
                    onSelect={() => setSelectedDataset(dataset.id)}
                    onDelete={onDeleteDataset ? () => onDeleteDataset(dataset.id) : undefined}
                  />
                ))}
              </div>
            )}
          </div>

          {/* Model Name */}
          <div>
            <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
              Fine-tuned Model Name
            </label>
            <input
              type="text"
              value={modelName}
              onChange={(e) => setModelName(e.target.value)}
              placeholder="e.g., trading-signals-v1"
              className="w-full px-3 py-2.5 bg-gray-100 dark:bg-gray-800 border-0 rounded-lg text-gray-900 dark:text-white focus:ring-2 focus:ring-primary-500"
            />
          </div>

          {/* Advanced Config */}
          <div>
            <button
              onClick={() => setShowAdvanced(!showAdvanced)}
              className="flex items-center gap-2 text-sm text-gray-500 hover:text-gray-700 dark:hover:text-gray-300"
            >
              {showAdvanced ? 'Hide' : 'Show'} Advanced Settings
              {showAdvanced ? <ChevronUpIcon className="w-4 h-4" /> : <ChevronDownIcon className="w-4 h-4" />}
            </button>
            {showAdvanced && (
              <div className="mt-3 p-4 bg-gray-50 dark:bg-gray-800 rounded-lg space-y-4">
                <div className="grid grid-cols-2 gap-4">
                  <div>
                    <label className="block text-xs text-gray-500 mb-1">Epochs</label>
                    <input
                      type="number"
                      min="1"
                      max="10"
                      value={trainingConfig.epochs}
                      onChange={(e) => setTrainingConfig({ ...trainingConfig, epochs: parseInt(e.target.value) || 1 })}
                      className="w-full px-3 py-2 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-sm"
                    />
                  </div>
                  <div>
                    <label className="block text-xs text-gray-500 mb-1">Batch Size</label>
                    <input
                      type="number"
                      min="1"
                      max="32"
                      value={trainingConfig.batchSize}
                      onChange={(e) => setTrainingConfig({ ...trainingConfig, batchSize: parseInt(e.target.value) || 1 })}
                      className="w-full px-3 py-2 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-sm"
                    />
                  </div>
                  <div>
                    <label className="block text-xs text-gray-500 mb-1">Learning Rate</label>
                    <input
                      type="number"
                      step="0.00001"
                      min="0.00001"
                      max="0.01"
                      value={trainingConfig.learningRate}
                      onChange={(e) => setTrainingConfig({ ...trainingConfig, learningRate: parseFloat(e.target.value) || 0.0001 })}
                      className="w-full px-3 py-2 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-sm"
                    />
                  </div>
                  <div>
                    <label className="block text-xs text-gray-500 mb-1">Validation Split</label>
                    <input
                      type="number"
                      step="0.05"
                      min="0.05"
                      max="0.3"
                      value={trainingConfig.validationSplit}
                      onChange={(e) => setTrainingConfig({ ...trainingConfig, validationSplit: parseFloat(e.target.value) || 0.1 })}
                      className="w-full px-3 py-2 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-sm"
                    />
                  </div>
                </div>
              </div>
            )}
          </div>

          {/* Estimated Cost */}
          {estimatedCost > 0 && (
            <div className="p-3 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg flex items-center justify-between">
              <div className="flex items-center gap-2 text-sm text-yellow-600 dark:text-yellow-400">
                <ExclamationTriangleIcon className="w-4 h-4" />
                <span>Estimated training cost</span>
              </div>
              <span className="font-bold text-yellow-600 dark:text-yellow-400">
                ~${estimatedCost.toFixed(2)}
              </span>
            </div>
          )}

          {/* Start Training Button */}
          <button
            onClick={handleStartTraining}
            disabled={!canStartTraining}
            className="w-full flex items-center justify-center gap-2 px-4 py-3 bg-primary-600 hover:bg-primary-700 text-white rounded-lg font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <PlayIcon className="w-5 h-5" />
            Start Fine-Tuning
          </button>

          {/* Info */}
          <div className="p-3 bg-blue-50 dark:bg-blue-900/20 rounded-lg flex items-start gap-2">
            <InformationCircleIcon className="w-4 h-4 text-blue-500 mt-0.5 flex-shrink-0" />
            <p className="text-xs text-blue-600 dark:text-blue-400">
              Fine-tuning customizes a base model on your trading data. This improves accuracy for
              your specific use case but may take hours to complete. Training costs are estimates.
            </p>
          </div>
        </div>
      )}

      {/* Models Comparison Tab */}
      {activeTab === 'models' && (
        <div className="p-4">
          {fineTunedModels.length === 0 ? (
            <div className="py-12 text-center">
              <AcademicCapIcon className="w-12 h-12 mx-auto text-gray-300 dark:text-gray-600 mb-3" />
              <p className="text-gray-500 text-sm">No fine-tuned models yet</p>
              <p className="text-gray-400 text-xs mt-1">Start training to create your first model</p>
            </div>
          ) : (
            <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
              {fineTunedModels.map((model) => (
                <ModelComparisonCard
                  key={model.id}
                  model={model}
                  onCancel={onCancelTraining ? () => onCancelTraining(model.id) : undefined}
                  onDownload={onDownloadModel ? () => onDownloadModel(model.id) : undefined}
                  onDelete={onDeleteModel ? () => onDeleteModel(model.id) : undefined}
                />
              ))}
            </div>
          )}
        </div>
      )}
    </div>
  );
};

// Missing import fix
const ChevronUpIcon = ({ className }: { className?: string }) => (
  <svg className={className} fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor">
    <path strokeLinecap="round" strokeLinejoin="round" d="m4.5 15.75 7.5-7.5 7.5 7.5" />
  </svg>
);

const ChevronDownIcon = ({ className }: { className?: string }) => (
  <svg className={className} fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor">
    <path strokeLinecap="round" strokeLinejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
  </svg>
);

export default FineTuningPanel;
