import React, { useState, useMemo } from 'react';

interface Cycle {
  elements: number[];
  length: number;
}

interface PermutationData {
  permutation: number[];
  cycles: Cycle[];
  hasLongCycle: boolean;
  id: string;
}

// Generate all permutations of [1, 2, ..., n]
function generatePermutations(n: number): number[][] {
  if (n === 1) return [[1]];
  
  const result: number[][] = [];
  const smaller = generatePermutations(n - 1);
  
  for (const perm of smaller) {
    for (let i = 0; i <= perm.length; i++) {
      const newPerm = [...perm.slice(0, i), n, ...perm.slice(i)];
      result.push(newPerm);
    }
  }
  
  return result;
}

// Find cycles in a permutation
function findCycles(permutation: number[]): Cycle[] {
  const n = permutation.length;
  const visited = new Array(n).fill(false);
  const cycles: Cycle[] = [];
  
  for (let i = 0; i < n; i++) {
    if (!visited[i]) {
      const cycle: number[] = [];
      let current = i;
      
      while (!visited[current]) {
        visited[current] = true;
        cycle.push(current + 1); // Convert to 1-indexed
        current = permutation[current] - 1; // Convert back to 0-indexed
      }
      
      cycles.push({
        elements: cycle,
        length: cycle.length,
      });
    }
  }
  
  return cycles.sort((a, b) => b.length - a.length);
}

const PermutationExplorer: React.FC = () => {
  const [n, setN] = useState(3);
  const [filter, setFilter] = useState<'all' | 'long' | 'short'>('all');

  const allPermutations = useMemo(() => {
    const perms = generatePermutations(n);
    return perms.map((perm, idx) => {
      const cycles = findCycles(perm);
      const hasLongCycle = cycles.some(c => c.length > n / 2);
      
      return {
        permutation: perm,
        cycles,
        hasLongCycle,
        id: `perm-${n}-${idx}`,
      };
    });
  }, [n]);

  const filteredPermutations = useMemo(() => {
    if (filter === 'all') return allPermutations;
    if (filter === 'long') return allPermutations.filter(p => p.hasLongCycle);
    return allPermutations.filter(p => !p.hasLongCycle);
  }, [allPermutations, filter]);

  const stats = useMemo(() => {
    const withLong = allPermutations.filter(p => p.hasLongCycle).length;
    const withoutLong = allPermutations.length - withLong;
    return { total: allPermutations.length, withLong, withoutLong };
  }, [allPermutations]);

  const formatCycleNotation = (cycles: Cycle[]) => {
    return cycles.map(cycle => `(${cycle.elements.join(' ')})`).join(' ');
  };

  const formatStandardNotation = (perm: number[]) => {
    return `[${perm.join(', ')}]`;
  };

  return (
    <div className="my-8 p-6 border-2 border-gray-300 rounded-lg bg-white">
      <h3 className="text-xl font-semibold mb-4">Permutation Cycle Explorer</h3>
      
      <div className="mb-6 space-y-4">
        <div>
          <label className="block text-md font-semibold mb-2">
            Size (n): {n}
          </label>
          <div className="flex items-center space-x-4">
            {[3, 4, 5].map(size => (
              <button
                key={size}
                onClick={() => setN(size)}
                className={`px-4 py-2 rounded font-semibold transition-colors ${
                  n === size
                    ? 'bg-blue-600 text-white'
                    : 'bg-gray-200 text-gray-700 hover:bg-gray-300'
                }`}
              >
                {size}
              </button>
            ))}
          </div>
        </div>

        <div>
          <label className="block text-md font-semibold mb-2">
            Filter Permutations:
          </label>
          <div className="flex items-center space-x-4">
            <button
              onClick={() => setFilter('all')}
              className={`px-4 py-2 rounded font-semibold transition-colors ${
                filter === 'all'
                  ? 'bg-blue-600 text-white'
                  : 'bg-gray-200 text-gray-700 hover:bg-gray-300'
              }`}
            >
              All ({stats.total})
            </button>
            <button
              onClick={() => setFilter('long')}
              className={`px-4 py-2 rounded font-semibold transition-colors ${
                filter === 'long'
                  ? 'bg-red-600 text-white'
                  : 'bg-gray-200 text-gray-700 hover:bg-gray-300'
              }`}
            >
              With Long Cycle ({stats.withLong})
            </button>
            <button
              onClick={() => setFilter('short')}
              className={`px-4 py-2 rounded font-semibold transition-colors ${
                filter === 'short'
                  ? 'bg-green-600 text-white'
                  : 'bg-gray-200 text-gray-700 hover:bg-gray-300'
              }`}
            >
              Without Long Cycle ({stats.withoutLong})
            </button>
          </div>
        </div>
      </div>

      <div className="mb-4 p-4 bg-blue-50 rounded">
        <p className="text-sm">
          <strong>Note:</strong> A "long cycle" is one with length &gt; n/2. For n={n}, 
          that means cycles longer than {Math.floor(n / 2)}. 
          There are <strong>{stats.withLong}</strong> permutations with at least one long cycle 
          (about {((stats.withLong / stats.total) * 100).toFixed(1)}%).
        </p>
      </div>

      <div className="space-y-3 max-h-96 overflow-y-auto">
        {filteredPermutations.map((perm) => (
          <div
            key={perm.id}
            className={`p-3 rounded border-2 ${
              perm.hasLongCycle
                ? 'bg-red-50 border-red-300'
                : 'bg-green-50 border-green-300'
            }`}
          >
            <div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-sm">
              <div>
                <span className="font-semibold">Standard:</span>{' '}
                <code className="bg-white px-2 py-1 rounded">
                  {formatStandardNotation(perm.permutation)}
                </code>
              </div>
              <div>
                <span className="font-semibold">Cycles:</span>{' '}
                <code className="bg-white px-2 py-1 rounded">
                  {formatCycleNotation(perm.cycles)}
                </code>
              </div>
            </div>
            <div className="mt-2 text-xs text-gray-600">
              Cycle lengths: {perm.cycles.map(c => c.length).join(', ')}
              {perm.hasLongCycle && (
                <span className="ml-2 text-red-700 font-semibold">
                  ⚠ Has long cycle!
                </span>
              )}
            </div>
          </div>
        ))}
      </div>

      <div className="mt-6 p-4 bg-gray-100 rounded">
        <h4 className="font-semibold mb-2">Understanding the Notation:</h4>
        <ul className="text-sm space-y-1 list-disc list-inside">
          <li>
            <strong>Standard notation [a, b, c, ...]:</strong> Position i contains value a[i]. 
            For example, [2,3,1] means box 1→2, box 2→3, box 3→1.
          </li>
          <li>
            <strong>Cycle notation (a b c ...):</strong> Shows the path a→b→c→...→a. 
            For example, (1 2 3) means 1→2→3→1.
          </li>
          <li>
            Permutations with long cycles (shown in red) would cause the loop strategy to fail 
            for at least one prisoner.
          </li>
        </ul>
      </div>
    </div>
  );
};

export default PermutationExplorer;
