import React, { useState } from 'react';
import Image from 'next/image';
import { ColorScheme } from '../utils/colorSchemes';
import { generateYAML, generateJSON, generateXResources, generateTOML } from '../utils/exportFormats';
import { Highlight, themes } from 'prism-react-renderer';
import { motion, useAnimation } from 'framer-motion';
import ColorPalette from './ColorPalette';

interface ColorSchemeCardProps {
  scheme: ColorScheme;
  onLike: () => void;
  onDislike: () => void;
  index: number;
  isDarkMode: boolean;
  codeSample: string;
  outputFormat: string;
}

const ColorSchemeCard: React.FC<ColorSchemeCardProps> = ({ scheme, onLike, onDislike, index, isDarkMode, codeSample, outputFormat }) => {
  const [overlayColor, setOverlayColor] = useState('rgba(0, 0, 0, 0)');
  const controls = useAnimation();

  const getCodeExample = () => {
    // Add code samples for each language here
    const samples = {
      c: `#include <stdio.h>

int is_prime(int n) {
    if (n <= 1) return 0;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) return 0;
    }
    return 1;
}

void print_primes(int limit) {
    printf("Primes up to %d:\n", limit);
    for (int i = 2; i <= limit; i++) {
        if (is_prime(i)) {
            printf("%d ", i);
        }
    }
    printf("\n");
}

int main() {
    int limit = 50;
    print_primes(limit);

    int num = 7;
    printf("Is %d prime? %s\n", num, is_prime(num) ? "Yes" : "No");
    return 0;
}`,
      python: `import numpy as np

@timeit
def is_prime(n):
    if n <= 1:
        return False
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    return True


def primes_up_to(limit):
    """
    This function returns a list of prime numbers up to a given limit.
    """
    primes = []
    for i in range(2, limit + 1):
        if is_prime(i):
            primes.append(i)
    return primes

def fibonacci(n):
    fib_sequence = [0, 1] # Create a list with the first two numbers in the Fibonacci sequence
    for i in range(2, n):
        fib_sequence.append(fib_sequence[-1] + fib_sequence[-2])
    return fib_sequence

limit = 50
print(f"Primes up to {limit}: {primes_up_to(limit)}")
print(f"Fibonacci sequence up to 10: {fibonacci(10)}")
`,
      rust: `fn is_prime(n: u32) -> bool {
    if n <= 1 {
        return false;
    }
    for i in 2..=((n as f64).sqrt() as u32) {
        if n % i == 0 {
            return false;
        }
    }
    true
}

fn primes_up_to(limit: u32) -> Vec<u32> {
    let mut primes = Vec::new();
    for i in 2..=limit {
        if is_prime(i) {
            primes.push(i);
        }
    }
    primes
}

fn main() {
    let limit = 50;
    let primes = primes_up_to(limit);
    println!("Primes up to {}: {:?}", limit, primes);

    let num = 7;
    println!("Is {} prime? {}", num, is_prime(num));
}`,
      go: `package main

import (
	"fmt"
	"math"
)

func isPrime(n int) bool {
	if n <= 1 {
		return false
	}
	for i := 2; i <= int(math.Sqrt(float64(n))); i++ {
		if n%i == 0 {
			return false
		}
	}
	return true
}

func primesUpTo(limit int) []int {
	primes := []int{}
	for i := 2; i <= limit; i++ {
		if isPrime(i) {
			primes = append(primes, i)
		}
	}
	return primes
}

func main() {
	limit := 50
	fmt.Printf("Primes up to %d: %v\n", limit, primesUpTo(limit))

	num := 7
	fmt.Printf("Is %d prime? %v\n", num, isPrime(num))
}`,
      javascript: `function isPrime(n) {
    if (n <= 1) return false;
    for (let i = 2; i <= Math.sqrt(n); i++) {
        if (n % i === 0) return false;
    }
    return true;
}

function primesUpTo(limit) {
    let primes = [];
    for (let i = 2; i <= limit; i++) {
        if (isPrime(i)) primes.push(i);
    }
    return primes;
}

function fibonacci(n) {
    let fib = [0, 1];
    for (let i = 2; i < n; i++) {
        fib.push(fib[i - 1] + fib[i - 2]);
    }
    return fib;
}

let limit = 50;`,
      bash: `#!/bin/bash

is_prime() {
  local n=$1
  if [ $n -le 1 ]; then
    echo 0
    return
  fi
  for ((i=2; i*i<=n; i++)); do
    if ((n % i == 0)); then
      echo 0
      return
    fi
  done
  echo 1
}

primes_up_to() {
  local limit=$1
  for ((i=2; i<=limit; i++)); do
    if [ $(is_prime $i) -eq 1 ]; then
      echo -n "$i "
    fi
  done
  echo
}

limit=50
echo "Primes up to $limit: $(primes_up_to $limit)"

num=7
if [ $(is_prime $num) -eq 1 ]; then
  echo "$num is prime"
else
  echo "$num is not prime"
fi`
    };

    return samples[codeSample] || samples.javascript;
  };

  const handleDownload = (e: React.MouseEvent) => {
    e.stopPropagation();
    let content: string;
    let fileExtension: string;

    switch (outputFormat) {
      case 'json':
        content = generateJSON(scheme);
        fileExtension = 'json';
        break;
      case 'xresources':
        content = generateXResources(scheme);
        fileExtension = 'Xresources';
        break;
      case 'toml':
        content = generateTOML(scheme);
        fileExtension = 'toml';
        break;
      case 'yaml':
      default:
        content = generateYAML(scheme);
        fileExtension = 'yaml';
    }

    const blob = new Blob([content], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${scheme.name.replace(/\s+/g, '_').toLowerCase()}.${fileExtension}`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  };

  const handleLike = () => {
    setOverlayColor('rgba(0, 255, 0, 0.1)');
    controls.start({ x: 300, opacity: 0, transition: { duration: 0.3 } }).then(onLike);
  };

  const handleDislike = () => {
    setOverlayColor('rgba(255, 0, 0, 0.1)');
    controls.start({ x: -300, opacity: 0, transition: { duration: 0.3 } }).then(onDislike);
  };

  const paletteColors = [
    scheme.colors.normal.black,
    scheme.colors.normal.red,
    scheme.colors.normal.green,
    scheme.colors.normal.yellow,
    scheme.colors.normal.blue,
    scheme.colors.normal.magenta,
    scheme.colors.normal.cyan,
    scheme.colors.normal.white,
    scheme.colors.bright.black,
    scheme.colors.bright.red,
    scheme.colors.bright.green,
    scheme.colors.bright.yellow,
    scheme.colors.bright.blue,
    scheme.colors.bright.magenta,
    scheme.colors.bright.cyan,
    scheme.colors.bright.white,
  ];

  return (
    <motion.div
      className="absolute w-[80vw] max-w-[480px] h-[90vh] max-h-[600px] bg-white dark:bg-gray-800 rounded-lg shadow-lg overflow-hidden"
      initial={{ scale: 1 - index * 0.05, y: index * 15, opacity: 1 }}
      animate={controls}
      style={{ 
        zIndex: 3 - index
      }}
      drag="x"
      dragConstraints={{ left: -50, right: 50 }}
      onDragEnd={(e, { offset, velocity }) => {
        if (offset.x > 50) handleLike();
        else if (offset.x < -50) handleDislike();
      }}
    >
      <div className="p-4 h-full flex flex-col relative">
        <motion.div 
          className="absolute inset-0 rounded-lg"
          animate={{ backgroundColor: overlayColor }}
          initial={{ backgroundColor: 'rgba(0, 0, 0, 0)' }}
          transition={{ duration: 0.2 }}
        />
        <div className="flex justify-between items-center mb-2 z-10">
          <h2 className="text-lg font-semibold truncate">{scheme.name}</h2>
          <button 
            className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 transition-colors duration-300"
            onClick={handleDownload}
          >
            <Image src={isDarkMode ? "/download-icon-dark.svg" : "/download-icon-light.svg"} alt="Download" width={20} height={20} />
          </button>
        </div>
        <div className="bg-gray-100 dark:bg-gray-700 rounded-md mb-2 flex-grow overflow-hidden z-10 shadow-md">
          <Highlight theme={themes.dracula} code={getCodeExample()} language={codeSample}>
            {({ className, style, tokens, getLineProps, getTokenProps }) => (
              <pre className={`${className} text-sm p-4 h-full overflow-auto`} style={{ ...style, backgroundColor: scheme.colors.primary.background }}>
                {tokens.map((line, i) => (
                  <div key={i} {...getLineProps({ line, key: i })}>
                    {line.map((token, key) => {
                    let color = scheme.colors.primary.foreground;
                    if (token.types.includes('keyword')) color = scheme.colors.normal.blue;
                    if (token.types.includes('string')) color = scheme.colors.normal.green;
                    if (token.types.includes('number')) color = scheme.colors.normal.magenta;
                    if (token.types.includes('comment')) color = scheme.colors.bright.black;
                    if (token.types.includes('function')) color = scheme.colors.normal.yellow;
                    if (token.types.includes('operator')) color = scheme.colors.normal.cyan;
                    if (token.types.includes('class-name')) color = scheme.colors.bright.magenta;
                    if (token.types.includes('constant')) color = scheme.colors.bright.red;
                    if (token.types.includes('punctuation')) color = scheme.colors.bright.cyan;
                    if (token.types.includes('variable')) color = scheme.colors.bright.yellow;
                    if (token.types.includes('boolean')) color = scheme.colors.bright.yellow;
                    if (token.types.includes('builtin')) color = scheme.colors.bright.magenta;
                    if (token.types.includes('attr-name')) color = scheme.colors.normal.red;
                    if (token.types.includes('attr-value')) color = scheme.colors.bright.green;
                    if (token.types.includes('tag')) color = scheme.colors.normal.blue;
                    if (token.types.includes('namespace')) color = scheme.colors.normal.magenta;
                    if (token.types.includes('selector')) color = scheme.colors.normal.yellow;
                    if (token.types.includes('property')) color = scheme.colors.normal.cyan;
                    if (token.types.includes('unit')) color = scheme.colors.bright.yellow;
                    if (token.types.includes('important')) color = scheme.colors.bright.red;
                    if (token.types.includes('symbol')) color = scheme.colors.normal.magenta;        // Symbols (e.g., special characters)
                    if (token.types.includes('regex')) color = scheme.colors.bright.green;           // Regular expressions
                    if (token.types.includes('template-string')) color = scheme.colors.normal.green; // Template literals
                    if (token.types.includes('char')) color = scheme.colors.bright.yellow;           // Individual characters
                    if (token.types.includes('module')) color = scheme.colors.normal.cyan;           // Modules
                    if (token.types.includes('directive')) color = scheme.colors.normal.magenta;      // Directives (e.g., preprocessor)
                    if (token.types.includes('annotation')) color = scheme.colors.normal.green;      // Annotations (e.g., decorators)
                    if (token.types.includes('parameter')) color = scheme.colors.bright.yellow;      // Parameters in functions
                    if (token.types.includes('method')) color = scheme.colors.normal.yellow;         // Methods
                    if (token.types.includes('field')) color = scheme.colors.bright.blue;            // Fields within classes
                    if (token.types.includes('property-access')) color = scheme.colors.normal.cyan;  // Property accessors (e.g., dot notation)
                    if (token.types.includes('escape')) color = scheme.colors.bright.red;            // Escape sequences
                    if (token.types.includes('meta')) color = scheme.colors.bright.magenta;           // Meta information (e.g., HTML meta tags)
                    if (token.types.includes('label')) color = scheme.colors.bright.yellow;          // Labels (e.g., in loops)
                    if (token.types.includes('alias')) color = scheme.colors.normal.magenta;          // Aliases (e.g., imports or type aliases)
                    if (token.types.includes('error')) color = scheme.colors.bright.red;             // Error handling, error literals
                    if (token.types.includes('debug')) color = scheme.colors.bright.magenta;          // Debugging statements (e.g., console logs)
                    if (token.types.includes('property-declaration')) color = scheme.colors.normal.blue; // Property declarations in classes
                    if (token.types.includes('module-declaration')) color = scheme.colors.normal.cyan;   // Declarations of modules
                    if (token.types.includes('generic')) color = scheme.colors.bright.magenta;       // Generics (e.g., <T>)
                    if (token.types.includes('type')) color = scheme.colors.bright.blue;             // Types in TypeScript, Flow, etc.
                    if (token.types.includes('interface')) color = scheme.colors.normal.green;       // Interfaces (e.g., TypeScript)
                    if (token.types.includes('enums')) color = scheme.colors.bright.cyan;            // Enums in languages like TypeScript, Java
                    if (token.types.includes('modifier')) color = scheme.colors.normal.yellow;       // Modifiers (e.g., public, static)
                    if (token.types.includes('event')) color = scheme.colors.bright.blue;            // Events (e.g., DOM events or custom events)
                    if (token.types.includes('keyword-control')) color = scheme.colors.bright.yellow; // Control-flow keywords (e.g., if, for)
                    if (token.types.includes('loop')) color = scheme.colors.normal.magenta;           // Loop keywords (e.g., for, while)
                    if (token.types.includes('storage')) color = scheme.colors.normal.red;           // Storage-related keywords (e.g., var, let)
                    if (token.types.includes('annotation-function')) color = scheme.colors.bright.green; // Annotated functions
                    if (token.types.includes('doc-string')) color = scheme.colors.bright.blue;       // Docstrings or comments that are part of documentation
                      return <span key={key} {...getTokenProps({ token, key })} style={{ ...getTokenProps({ token, key }).style, color }} />;
                    })}
                  </div>
                ))}
              </pre>
            )}
          </Highlight>
        </div>
        <div className="mt-2 z-10">
          <ColorPalette 
            colors={paletteColors}
            size="small"
          />
        </div>
        <div className="flex justify-center space-x-4 mt-2 z-10">
          <button 
            className="bg-red-500 text-white p-2 rounded-full shadow-lg hover:bg-red-600 transition-colors duration-300"
            onClick={handleDislike}
          >
            <Image src={isDarkMode ? "/cross-icon-dark.svg" : "/cross-icon-light.svg"} alt="Dislike" width={24} height={24} />
          </button>
          <button 
            className="bg-green-500 text-white p-2 rounded-full shadow-lg hover:bg-green-600 transition-colors duration-300"
            onClick={handleLike}
          >
            <Image src={isDarkMode ? "/heart-icon-dark.svg" : "/heart-icon-light.svg"} alt="Like" width={24} height={24} />
          </button>
        </div>
      </div>
    </motion.div>
  );
};

export default ColorSchemeCard;