import { useEffect, useState } from 'react';
import {
  Hammer,
  Play,
  Pause,
  Square,
  Cpu,
  Blocks,
  TrendingUp,
  Clock,
  Zap,
} from 'lucide-react';
import { useMiningStore, formatHashrate } from '../../store/mining';
import { useNodeStore } from '../../store/node';
import { useWalletStore } from '../../store/wallet';

export default function MiningDashboard() {
  const {
    status,
    recentBlocks,
    hashrateHistory,
    defaultThreads,
    defaultCoinbaseAddress,
    startMining,
    stopMining,
    pauseMining,
    resumeMining,
    setThreads,
    refreshStatus,
    refreshStats,
    setupEventListeners,
    cleanupEventListeners,
  } = useMiningStore();

  const nodeStatus = useNodeStore((state) => state.status);
  const addresses = useWalletStore((state) => state.addresses);

  const [threads, setThreadsLocal] = useState(defaultThreads);
  const [coinbaseAddress, setCoinbaseAddress] = useState(
    defaultCoinbaseAddress || addresses[0]?.address || ''
  );
  const [isStarting, setIsStarting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Max threads available
  const maxThreads = navigator.hardwareConcurrency || 8;

  // Setup event listeners on mount
  useEffect(() => {
    setupEventListeners();
    return () => cleanupEventListeners();
  }, [setupEventListeners, cleanupEventListeners]);

  // Refresh stats periodically when mining
  useEffect(() => {
    if (!status.isMining) return;

    const interval = setInterval(() => {
      refreshStatus();
      refreshStats();
    }, 1000);

    return () => clearInterval(interval);
  }, [status.isMining, refreshStatus, refreshStats]);

  // Update coinbase address when addresses change
  useEffect(() => {
    if (!coinbaseAddress && addresses.length > 0) {
      setCoinbaseAddress(addresses[0].address);
    }
  }, [addresses, coinbaseAddress]);

  const handleStart = async () => {
    if (!nodeStatus.isConnected) {
      setError('Please connect to a node first');
      return;
    }

    if (!coinbaseAddress) {
      setError('Please select a coinbase address for rewards');
      return;
    }

    setIsStarting(true);
    setError(null);

    try {
      await startMining(coinbaseAddress, threads);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to start mining');
    } finally {
      setIsStarting(false);
    }
  };

  const handleStop = async () => {
    try {
      await stopMining();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to stop mining');
    }
  };

  const handlePauseResume = async () => {
    try {
      if (status.isPaused) {
        await resumeMining();
      } else {
        await pauseMining();
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Action failed');
    }
  };

  const handleThreadsChange = async (newThreads: number) => {
    setThreadsLocal(newThreads);
    if (status.isMining) {
      try {
        await setThreads(newThreads);
      } catch (err) {
        setError(err instanceof Error ? err.message : 'Failed to update threads');
      }
    }
  };

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-white flex items-center gap-3">
            <Hammer size={28} />
            Mining
          </h1>
          <p className="text-gray-400 mt-1">
            Mine SYN coins using your computer's CPU
          </p>
        </div>

        {/* Control buttons */}
        <div className="flex items-center gap-2">
          {status.isMining ? (
            <>
              <button
                onClick={handlePauseResume}
                className={`flex items-center gap-2 px-4 py-2 rounded-lg transition-colors ${
                  status.isPaused
                    ? 'bg-green-600 hover:bg-green-700 text-white'
                    : 'bg-yellow-600 hover:bg-yellow-700 text-white'
                }`}
              >
                {status.isPaused ? <Play size={18} /> : <Pause size={18} />}
                {status.isPaused ? 'Resume' : 'Pause'}
              </button>
              <button
                onClick={handleStop}
                className="flex items-center gap-2 px-4 py-2 rounded-lg bg-red-600 hover:bg-red-700 text-white transition-colors"
              >
                <Square size={18} />
                Stop
              </button>
            </>
          ) : (
            <button
              onClick={handleStart}
              disabled={isStarting || !nodeStatus.isConnected}
              className="flex items-center gap-2 px-6 py-2 rounded-lg bg-synor-600 hover:bg-synor-700 text-white font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
            >
              {isStarting ? (
                <Cpu size={18} className="animate-spin" />
              ) : (
                <Play size={18} />
              )}
              Start Mining
            </button>
          )}
        </div>
      </div>

      {/* Error display */}
      {error && (
        <div className="p-4 rounded-lg bg-red-900/30 border border-red-800 text-red-400">
          {error}
        </div>
      )}

      {/* Warning if not connected */}
      {!nodeStatus.isConnected && (
        <div className="p-4 rounded-lg bg-yellow-900/30 border border-yellow-800 text-yellow-400">
          Please connect to a node before starting mining
        </div>
      )}

      {/* Stats Grid */}
      <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
        <StatCard
          icon={<Zap size={20} className={status.isMining && !status.isPaused ? 'animate-pulse' : ''} />}
          label="Hashrate"
          value={formatHashrate(status.hashrate)}
          highlight={status.isMining && !status.isPaused}
        />
        <StatCard
          icon={<Blocks size={20} />}
          label="Blocks Found"
          value={status.blocksFound.toString()}
        />
        <StatCard
          icon={<Cpu size={20} />}
          label="Threads"
          value={`${status.threads || threads}/${maxThreads}`}
        />
        <StatCard
          icon={<Clock size={20} />}
          label="Status"
          value={
            status.isMining
              ? status.isPaused
                ? 'Paused'
                : 'Mining'
              : 'Idle'
          }
          highlight={status.isMining && !status.isPaused}
        />
      </div>

      {/* Configuration (when not mining) */}
      {!status.isMining && (
        <div className="p-6 rounded-xl bg-gray-900 border border-gray-800">
          <h3 className="text-lg font-semibold text-white mb-4">
            Mining Configuration
          </h3>
          <div className="space-y-4">
            {/* Coinbase address */}
            <div>
              <label className="block text-sm text-gray-400 mb-2">
                Reward Address
              </label>
              <select
                value={coinbaseAddress}
                onChange={(e) => setCoinbaseAddress(e.target.value)}
                className="w-full px-4 py-3 rounded-lg bg-gray-800 border border-gray-700 text-white focus:outline-none focus:border-synor-500"
              >
                <option value="">Select address...</option>
                {addresses.map((addr) => (
                  <option key={addr.address} value={addr.address}>
                    {addr.label || `Address ${addr.index}`} - {addr.address.slice(0, 20)}...
                  </option>
                ))}
              </select>
              <p className="text-xs text-gray-500 mt-1">
                Mining rewards will be sent to this address
              </p>
            </div>

            {/* Thread slider */}
            <div>
              <label className="block text-sm text-gray-400 mb-2">
                Mining Threads: {threads}
              </label>
              <input
                type="range"
                min={1}
                max={maxThreads}
                value={threads}
                onChange={(e) => handleThreadsChange(parseInt(e.target.value))}
                className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer accent-synor-500"
              />
              <div className="flex justify-between text-xs text-gray-500 mt-1">
                <span>1 (Low Power)</span>
                <span>{maxThreads} (Max Performance)</span>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Hashrate Chart (simplified) */}
      {status.isMining && hashrateHistory.length > 0 && (
        <div className="p-6 rounded-xl bg-gray-900 border border-gray-800">
          <h3 className="text-lg font-semibold text-white mb-4 flex items-center gap-2">
            <TrendingUp size={20} />
            Hashrate History
          </h3>
          <div className="h-32 flex items-end gap-0.5">
            {hashrateHistory.slice(-60).map((point, i) => {
              const maxHash = Math.max(...hashrateHistory.map((h) => h.hashrate));
              const height = maxHash > 0 ? (point.hashrate / maxHash) * 100 : 0;
              return (
                <div
                  key={i}
                  className="flex-1 bg-synor-500 rounded-t transition-all duration-300"
                  style={{ height: `${height}%` }}
                  title={`${formatHashrate(point.hashrate)}`}
                />
              );
            })}
          </div>
          <div className="flex justify-between text-xs text-gray-500 mt-2">
            <span>60s ago</span>
            <span>Now</span>
          </div>
        </div>
      )}

      {/* Recent Blocks */}
      {recentBlocks.length > 0 && (
        <div className="p-6 rounded-xl bg-gray-900 border border-gray-800">
          <h3 className="text-lg font-semibold text-white mb-4 flex items-center gap-2">
            <Blocks size={20} />
            Blocks Found
          </h3>
          <div className="space-y-2">
            {recentBlocks.slice(0, 5).map((block, i) => (
              <div
                key={i}
                className="flex items-center justify-between p-3 rounded-lg bg-gray-800"
              >
                <div>
                  <p className="text-sm text-white font-mono">
                    Block #{block.height.toLocaleString()}
                  </p>
                  <p className="text-xs text-gray-500">
                    {block.hash.slice(0, 24)}...
                  </p>
                </div>
                <div className="text-right">
                  <p className="text-sm text-synor-400 font-medium">
                    +{(block.reward / 100_000_000).toFixed(2)} SYN
                  </p>
                  <p className="text-xs text-gray-500">
                    {new Date(block.timestamp).toLocaleTimeString()}
                  </p>
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Mining Tips */}
      <div className="p-6 rounded-xl bg-gray-900/50 border border-gray-800">
        <h3 className="text-sm font-semibold text-gray-400 mb-3">Mining Tips</h3>
        <ul className="space-y-2 text-sm text-gray-500">
          <li>• Use fewer threads to keep your computer responsive</li>
          <li>• Mining profitability depends on network difficulty</li>
          <li>• Ensure adequate cooling for sustained mining</li>
          <li>• For best results, use an embedded node for lower latency</li>
        </ul>
      </div>
    </div>
  );
}

// Stat card component
function StatCard({
  icon,
  label,
  value,
  highlight = false,
}: {
  icon: React.ReactNode;
  label: string;
  value: string;
  highlight?: boolean;
}) {
  return (
    <div
      className={`p-4 rounded-xl border ${
        highlight
          ? 'bg-synor-900/30 border-synor-700'
          : 'bg-gray-900 border-gray-800'
      }`}
    >
      <div className="flex items-center gap-2 text-gray-400 mb-2">
        {icon}
        <span className="text-sm">{label}</span>
      </div>
      <p
        className={`text-xl font-bold ${
          highlight ? 'text-synor-400' : 'text-white'
        }`}
      >
        {value}
      </p>
    </div>
  );
}
