/**
 * EnsemblePanel Component
 * Configuration panel for ensemble model weights and voting mechanism
 * OQI-006: Senales ML
 */

import React, { useState, useMemo, useCallback } from 'react';
import {
  Sparkles,
  Sliders,
  RotateCcw,
  Save,
  AlertTriangle,
  CheckCircle,
  Info,
  Lock,
  Unlock,
  TrendingUp,
  BarChart3,
  Percent,
} from 'lucide-react';

export interface ModelWeight {
  modelId: string;
  modelName: string;
  weight: number;
  accuracy: number;
  locked?: boolean;
}

export interface EnsembleConfig {
  votingMethod: 'weighted' | 'majority' | 'unanimous';
  minimumAgreement: number;
  confidenceThreshold: number;
  weights: ModelWeight[];
}

export interface EnsemblePanelProps {
  config: EnsembleConfig;
  onConfigChange: (config: EnsembleConfig) => void;
  onSave?: () => void;
  onReset?: () => void;
  isLoading?: boolean;
  readOnly?: boolean;
}

const EnsemblePanel: React.FC<EnsemblePanelProps> = ({
  config,
  onConfigChange,
  onSave,
  onReset,
  isLoading = false,
  readOnly = false,
}) => {
  const [hasChanges, setHasChanges] = useState(false);

  const totalWeight = useMemo(
    () => config.weights.reduce((sum, w) => sum + w.weight, 0),
    [config.weights]
  );

  const isValidConfig = useMemo(() => {
    return Math.abs(totalWeight - 100) < 0.1 && config.minimumAgreement >= 1;
  }, [totalWeight, config.minimumAgreement]);

  const updateWeight = useCallback(
    (modelId: string, newWeight: number) => {
      if (readOnly) return;

      const updatedWeights = config.weights.map((w) =>
        w.modelId === modelId ? { ...w, weight: Math.max(0, Math.min(100, newWeight)) } : w
      );

      onConfigChange({ ...config, weights: updatedWeights });
      setHasChanges(true);
    },
    [config, onConfigChange, readOnly]
  );

  const toggleLock = useCallback(
    (modelId: string) => {
      if (readOnly) return;

      const updatedWeights = config.weights.map((w) =>
        w.modelId === modelId ? { ...w, locked: !w.locked } : w
      );

      onConfigChange({ ...config, weights: updatedWeights });
      setHasChanges(true);
    },
    [config, onConfigChange, readOnly]
  );

  const normalizeWeights = useCallback(() => {
    if (readOnly || totalWeight === 0) return;

    const unlockedModels = config.weights.filter((w) => !w.locked);
    const lockedTotal = config.weights
      .filter((w) => w.locked)
      .reduce((sum, w) => sum + w.weight, 0);

    const remainingWeight = 100 - lockedTotal;
    const unlockedTotal = unlockedModels.reduce((sum, w) => sum + w.weight, 0);

    const updatedWeights = config.weights.map((w) => {
      if (w.locked) return w;
      return {
        ...w,
        weight: unlockedTotal > 0 ? (w.weight / unlockedTotal) * remainingWeight : remainingWeight / unlockedModels.length,
      };
    });

    onConfigChange({ ...config, weights: updatedWeights });
    setHasChanges(true);
  }, [config, onConfigChange, readOnly, totalWeight]);

  const autoWeightByAccuracy = useCallback(() => {
    if (readOnly) return;

    const totalAccuracy = config.weights.reduce((sum, w) => sum + w.accuracy, 0);
    const updatedWeights = config.weights.map((w) => ({
      ...w,
      weight: (w.accuracy / totalAccuracy) * 100,
      locked: false,
    }));

    onConfigChange({ ...config, weights: updatedWeights });
    setHasChanges(true);
  }, [config, onConfigChange, readOnly]);

  const getWeightColor = (weight: number) => {
    if (weight >= 30) return 'bg-green-500';
    if (weight >= 15) return 'bg-blue-500';
    if (weight >= 5) return 'bg-yellow-500';
    return 'bg-gray-500';
  };

  const handleSave = () => {
    if (onSave && isValidConfig) {
      onSave();
      setHasChanges(false);
    }
  };

  const handleReset = () => {
    if (onReset) {
      onReset();
      setHasChanges(false);
    }
  };

  return (
    <div className="bg-gray-800/50 rounded-xl border border-gray-700 p-4">
      {/* Header */}
      <div className="flex items-center justify-between mb-6">
        <div className="flex items-center gap-3">
          <div className="p-2 bg-purple-500/20 text-purple-400 rounded-lg">
            <Sparkles className="w-5 h-5" />
          </div>
          <div>
            <h3 className="font-semibold text-white">Ensemble Configuration</h3>
            <p className="text-xs text-gray-400">Configure model weights and voting</p>
          </div>
        </div>

        {!readOnly && (
          <div className="flex items-center gap-2">
            <button
              onClick={handleReset}
              disabled={isLoading || !hasChanges}
              className="flex items-center gap-1 px-3 py-1.5 text-sm text-gray-400 hover:text-white transition-colors disabled:opacity-50"
            >
              <RotateCcw className="w-4 h-4" />
              Reset
            </button>
            <button
              onClick={handleSave}
              disabled={isLoading || !hasChanges || !isValidConfig}
              className="flex items-center gap-1 px-3 py-1.5 text-sm bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
            >
              <Save className="w-4 h-4" />
              Save
            </button>
          </div>
        )}
      </div>

      {/* Voting Method */}
      <div className="mb-6">
        <label className="block text-sm text-gray-400 mb-2">Voting Method</label>
        <div className="grid grid-cols-3 gap-2">
          {(['weighted', 'majority', 'unanimous'] as const).map((method) => (
            <button
              key={method}
              onClick={() => !readOnly && onConfigChange({ ...config, votingMethod: method })}
              disabled={readOnly}
              className={`p-3 rounded-lg border transition-all ${
                config.votingMethod === method
                  ? 'bg-purple-500/20 border-purple-500 text-purple-400'
                  : 'bg-gray-900/50 border-gray-700 text-gray-400 hover:border-gray-600'
              } ${readOnly ? 'cursor-not-allowed' : ''}`}
            >
              <div className="text-sm font-medium capitalize">{method}</div>
              <div className="text-xs mt-1 text-gray-500">
                {method === 'weighted' && 'Use weight distribution'}
                {method === 'majority' && '>50% agreement'}
                {method === 'unanimous' && 'All models agree'}
              </div>
            </button>
          ))}
        </div>
      </div>

      {/* Thresholds */}
      <div className="grid grid-cols-2 gap-4 mb-6">
        <div>
          <label className="flex items-center gap-2 text-sm text-gray-400 mb-2">
            <BarChart3 className="w-4 h-4" />
            Minimum Agreement
          </label>
          <div className="flex items-center gap-2">
            <input
              type="range"
              min="1"
              max={config.weights.length}
              value={config.minimumAgreement}
              onChange={(e) => !readOnly && onConfigChange({ ...config, minimumAgreement: Number(e.target.value) })}
              disabled={readOnly}
              className="flex-1 h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer accent-purple-500"
            />
            <span className="text-white font-medium w-12 text-center">
              {config.minimumAgreement}/{config.weights.length}
            </span>
          </div>
        </div>

        <div>
          <label className="flex items-center gap-2 text-sm text-gray-400 mb-2">
            <Percent className="w-4 h-4" />
            Confidence Threshold
          </label>
          <div className="flex items-center gap-2">
            <input
              type="range"
              min="0"
              max="100"
              value={config.confidenceThreshold}
              onChange={(e) => !readOnly && onConfigChange({ ...config, confidenceThreshold: Number(e.target.value) })}
              disabled={readOnly}
              className="flex-1 h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer accent-purple-500"
            />
            <span className="text-white font-medium w-12 text-center">{config.confidenceThreshold}%</span>
          </div>
        </div>
      </div>

      {/* Model Weights */}
      <div className="mb-4">
        <div className="flex items-center justify-between mb-3">
          <label className="flex items-center gap-2 text-sm text-gray-400">
            <Sliders className="w-4 h-4" />
            Model Weights
          </label>
          {!readOnly && (
            <div className="flex items-center gap-2">
              <button
                onClick={normalizeWeights}
                className="text-xs text-blue-400 hover:text-blue-300 transition-colors"
              >
                Normalize to 100%
              </button>
              <span className="text-gray-600">|</span>
              <button
                onClick={autoWeightByAccuracy}
                className="text-xs text-purple-400 hover:text-purple-300 transition-colors"
              >
                Auto (by accuracy)
              </button>
            </div>
          )}
        </div>

        {/* Weight validation */}
        <div
          className={`mb-3 px-3 py-2 rounded-lg flex items-center gap-2 text-sm ${
            isValidConfig
              ? 'bg-green-500/10 text-green-400 border border-green-500/30'
              : 'bg-red-500/10 text-red-400 border border-red-500/30'
          }`}
        >
          {isValidConfig ? (
            <>
              <CheckCircle className="w-4 h-4" />
              <span>Total: {totalWeight.toFixed(1)}% - Configuration valid</span>
            </>
          ) : (
            <>
              <AlertTriangle className="w-4 h-4" />
              <span>Total: {totalWeight.toFixed(1)}% - Must equal 100%</span>
            </>
          )}
        </div>

        {/* Weight sliders */}
        <div className="space-y-3">
          {config.weights.map((model) => (
            <div key={model.modelId} className="p-3 bg-gray-900/50 rounded-lg">
              <div className="flex items-center justify-between mb-2">
                <div className="flex items-center gap-2">
                  <button
                    onClick={() => toggleLock(model.modelId)}
                    disabled={readOnly}
                    className={`p-1 rounded transition-colors ${
                      model.locked ? 'text-yellow-400 bg-yellow-500/20' : 'text-gray-500 hover:text-gray-300'
                    }`}
                  >
                    {model.locked ? <Lock className="w-3 h-3" /> : <Unlock className="w-3 h-3" />}
                  </button>
                  <span className="font-medium text-white">{model.modelName}</span>
                  <span className="text-xs text-gray-500">({model.accuracy}% acc)</span>
                </div>
                <div className="flex items-center gap-2">
                  <input
                    type="number"
                    min="0"
                    max="100"
                    value={model.weight.toFixed(1)}
                    onChange={(e) => updateWeight(model.modelId, Number(e.target.value))}
                    disabled={readOnly || model.locked}
                    className="w-16 px-2 py-1 text-sm text-right bg-gray-800 border border-gray-700 rounded text-white disabled:opacity-50"
                  />
                  <span className="text-gray-400">%</span>
                </div>
              </div>
              <div className="relative h-2 bg-gray-700 rounded-full overflow-hidden">
                <div
                  className={`absolute h-full transition-all ${getWeightColor(model.weight)}`}
                  style={{ width: `${model.weight}%` }}
                />
              </div>
              {!readOnly && !model.locked && (
                <input
                  type="range"
                  min="0"
                  max="100"
                  step="0.5"
                  value={model.weight}
                  onChange={(e) => updateWeight(model.modelId, Number(e.target.value))}
                  className="w-full h-2 mt-2 bg-transparent appearance-none cursor-pointer accent-blue-500"
                  style={{
                    background: 'transparent',
                  }}
                />
              )}
            </div>
          ))}
        </div>
      </div>

      {/* Info */}
      <div className="flex items-start gap-2 p-3 bg-blue-500/10 border border-blue-500/30 rounded-lg">
        <Info className="w-4 h-4 text-blue-400 flex-shrink-0 mt-0.5" />
        <div className="text-xs text-gray-300">
          <p className="mb-1">
            <strong className="text-blue-400">Weighted voting:</strong> Each model's prediction is multiplied by its weight.
          </p>
          <p className="mb-1">
            <strong className="text-blue-400">Majority voting:</strong> Signal generated when majority of models agree.
          </p>
          <p>
            <strong className="text-blue-400">Unanimous:</strong> All models must agree for a signal to be generated.
          </p>
        </div>
      </div>
    </div>
  );
};

export default EnsemblePanel;
