'use client';

import { useEffect, useState } from 'react';
import { useRouter, useParams } from 'next/navigation';
import { ArrowLeft, BookOpen, Lightbulb, PenTool, CheckCircle2 } from 'lucide-react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { EmptyState } from '@/components/ui/EmptyState';
import { ModuleProgress } from '@/components/modules/ModuleProgress';
import { useModuleStore } from '@/store/useModuleStore';
import { api, apiEndpoints } from '@/lib/api';
import { useToast } from '@/hooks/use-toast';
import type { Module, Progress } from '@/types';
import Link from 'next/link';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { cn } from '@/lib/utils';
import { BlockMath } from 'react-katex';
import 'katex/dist/katex.min.css';
import ReactMarkdown from 'react-markdown';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
import type { Components } from 'react-markdown';

// Markdown component with LaTeX support
interface MarkdownMathProps {
  content: string;
  className?: string;
}

const MarkdownMath: React.FC<MarkdownMathProps> = ({ content, className }) => {
  const components: Partial<Components> = {
    code({ className: codeClassName, children, ...props }) {
      const match = /language-latex/.exec(codeClassName || '');
      if (match) {
        return <BlockMath math={String(children).replace(/\n$/, '')} />;
      }
      return (
        <code className={codeClassName} {...props}>
          {children}
        </code>
      );
    },
  };

  return (
    <div className={cn("prose prose-sm max-w-none dark:prose-invert", className)}>
      <ReactMarkdown
        remarkPlugins={[remarkMath]}
        rehypePlugins={[rehypeKatex]}
        components={components}
      >
        {content}
      </ReactMarkdown>
    </div>
  );
};

export default function ModuleDetailPage() {
  const router = useRouter();
  const params = useParams();
  const moduleId = params['moduleId'] as string;
  const { toast } = useToast();
  const { modules, setCurrentModule, updateModuleProgress } = useModuleStore();
  const [isLoading, setIsLoading] = useState(true);
  const [moduleData, setModuleData] = useState<{
    module: Module | null;
    progress: Progress | null;
    introduction: string | null;
    examples: { title?: string; content?: string; latexFormula?: string; explanation?: string }[] | null;
    exercises: { id?: string; statement?: string; difficulty?: string; points?: number }[] | null;
  }>({
    module: null,
    progress: null,
    introduction: null,
    examples: null,
    exercises: null,
  });

  useEffect(() => {
    const fetchModuleData = async () => {
      try {
        setIsLoading(true);

        // Find module in store or fetch from API
        let moduleItem = modules.find((m) => m.id === moduleId);
        if (!moduleItem) {
          const moduleDataResponse = await api.get<Module>(apiEndpoints.modules.detail(moduleId));
          moduleItem = moduleDataResponse;
        }

        if (!moduleItem) {
          throw new Error('Módulo no encontrado');
        }

        setCurrentModule(moduleItem);

        // Fetch module content with proper error handling
        let introductionRes: { introduction: string | null; name: string; description: string; estimatedHours: number | null } | null = null;
        let examplesRes: { moduleName: string; examples: { title: string; content: string; latexFormula: string; explanation: string }[] } | null = null;
        let exercisesRes: { id: string; statement: string; difficulty: string; points: number }[] | null = null;

        // Fetch introduction with error handling
        try {
          introductionRes = await api.get<{
            introduction: string | null;
            name: string;
            description: string;
            estimatedHours: number | null;
          }>(apiEndpoints.modules.introduction(moduleId));
        } catch (error) {
          toast({
            title: 'Error al cargar introducción',
            description: 'No se pudo cargar el contenido introductorio del módulo',
            variant: 'destructive',
          });
          console.error('Error loading module introduction:', error);
        }

        // Fetch examples with error handling
        try {
          examplesRes = await api.get<{
            moduleName: string;
            examples: { title: string; content: string; latexFormula: string; explanation: string }[];
          }>(apiEndpoints.modules.examples(moduleId));
        } catch (error) {
          toast({
            title: 'Error al cargar ejemplos',
            description: 'No se pudieron cargar los ejemplos del módulo',
            variant: 'destructive',
          });
          console.error('Error loading module examples:', error);
        }

        // Fetch exercises with error handling
        try {
          exercisesRes = await api.get<{ id: string; statement: string; difficulty: string; points: number }[]>(
            `${apiEndpoints.exercises.list}?moduleId=${moduleId}`
          );
        } catch (error) {
          toast({
            title: 'Error al cargar ejercicios',
            description: 'No se pudieron cargar los ejercicios del módulo',
            variant: 'destructive',
          });
          console.error('Error loading module exercises:', error);
        }

        const introduction = introductionRes?.introduction ?? null;
        const examples = examplesRes?.examples ?? null;
        // Backend may return examples as JSON string instead of parsed array
        let parsedExamples: { title?: string; content?: string; latexFormula?: string; explanation?: string }[] | null = null;
        if (typeof examples === 'string') {
          try { parsedExamples = JSON.parse(examples) as { title?: string; content?: string; latexFormula?: string; explanation?: string }[]; } catch { parsedExamples = null; }
        } else {
          parsedExamples = examples;
        }
        const exercises = Array.isArray(exercisesRes) ? exercisesRes : null;

        // Fetch progress
        let moduleProgress: Progress | null = null;
        try {
          const progressData = await api.get<Progress>(apiEndpoints.progress.module(moduleId));
          moduleProgress = progressData;
          updateModuleProgress(moduleId, progressData);
        } catch (error) {
          // Progress might not exist yet
        }

        setModuleData({
          module: moduleItem,
          progress: moduleProgress,
          introduction,
          examples: parsedExamples,
          exercises,
        });
      } catch (error) {
        toast({
          title: 'Error al cargar módulo',
          description: error instanceof Error ? error.message : 'No se pudo cargar el módulo',
          variant: 'destructive',
        });
        router.push('/dashboard/modules');
      } finally {
        setIsLoading(false);
      }
    };

    if (moduleId) {
      void fetchModuleData();
    }
  }, [moduleId, modules, setCurrentModule, updateModuleProgress, toast, router]);

  const { module, progress, introduction, examples, exercises } = moduleData;

  if (isLoading) {
    return (
      <div className="flex h-full items-center justify-center">
        <div className="flex flex-col items-center gap-4">
          <div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" />
          <p className="text-sm text-muted-foreground">Cargando módulo...</p>
        </div>
      </div>
    );
  }

  if (!module) {
    return (
      <div className="flex h-full items-center justify-center">
        <Card className="max-w-md">
          <CardContent>
            <EmptyState
              icon={<BookOpen className="h-12 w-12" />}
              title="Módulo no encontrado"
              description="El módulo que buscas no existe o no está disponible."
              action={{
                label: 'Volver a módulos',
                onClick: () => router.push('/dashboard/modules'),
              }}
            />
          </CardContent>
        </Card>
      </div>
    );
  }

  const exampleCount = examples?.length ?? 0;
  const exerciseCount = exercises?.length ?? 0;
  const completedExercises = progress?.exercisesCompleted ?? 0;
  const percentage = progress?.percentage ?? 0;
  const isCompleted = progress?.isCompleted ?? false;

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center gap-4">
        <Link href="/modules">
          <Button variant="ghost" size="icon">
            <ArrowLeft className="h-5 w-5" />
          </Button>
        </Link>
        <div className="flex-1">
          <div className="flex items-center gap-3">
            <h1 className="text-3xl font-bold tracking-tight">{module.name}</h1>
            {isCompleted && (
              <span className="inline-flex items-center gap-1 rounded-full bg-green-100 px-3 py-1 text-sm text-green-800 dark:bg-green-900 dark:text-green-200">
                <CheckCircle2 className="h-3 w-3" />
                Completado
              </span>
            )}
          </div>
          <p className="text-muted-foreground">{module.description}</p>
        </div>
      </div>

      {/* Progress Card */}
      <Card>
        <CardHeader>
          <CardTitle>Tu progreso</CardTitle>
        </CardHeader>
        <CardContent>
          <ModuleProgress
            percentage={percentage}
            isCompleted={isCompleted}
          />
          <div className="mt-4 grid grid-cols-3 gap-4 text-center">
            <div>
              <p className="text-2xl font-bold">{exampleCount}</p>
              <p className="text-sm text-muted-foreground">Ejemplos</p>
            </div>
            <div>
              <p className="text-2xl font-bold">{exerciseCount}</p>
              <p className="text-sm text-muted-foreground">Ejercicios</p>
            </div>
            <div>
              <p className="text-2xl font-bold">{completedExercises}</p>
              <p className="text-sm text-muted-foreground">Completados</p>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Content Tabs */}
      <Tabs defaultValue="introduction" className="space-y-4">
        <TabsList>
          <TabsTrigger value="introduction">
            <Lightbulb className="mr-2 h-4 w-4" />
            Introducción
          </TabsTrigger>
          <TabsTrigger value="examples">
            <BookOpen className="mr-2 h-4 w-4" />
            Ejemplos
          </TabsTrigger>
          <TabsTrigger value="exercises">
            <PenTool className="mr-2 h-4 w-4" />
            Ejercicios
          </TabsTrigger>
        </TabsList>

        <TabsContent value="introduction" className="space-y-4">
          <Card>
            <CardHeader>
              <CardTitle>Introducción al módulo</CardTitle>
              <CardDescription>
                Fundamentos teóricos y conceptos clave
              </CardDescription>
            </CardHeader>
            <CardContent>
              {introduction ? (
                <MarkdownMath content={introduction} />
              ) : (
                <EmptyState
                  icon={<Lightbulb className="h-12 w-12" />}
                  title="Introducción no disponible"
                  description="La introducción estará disponible pronto."
                />
              )}
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="examples" className="space-y-4">
          <Card>
            <CardHeader>
              <CardTitle>Ejemplos resueltos</CardTitle>
              <CardDescription>
                Aprende paso a paso con ejemplos detallados
              </CardDescription>
            </CardHeader>
            <CardContent>
              {examples && examples.length > 0 ? (
                <div className="space-y-4">
                  {examples.map((example: { title?: string; content?: string; latexFormula?: string; explanation?: string }, index: number) => (
                    <Card key={index}>
                      <CardHeader>
                        <CardTitle className="text-base">
                          {example.title ?? `Ejemplo ${index + 1}`}
                        </CardTitle>
                      </CardHeader>
                      <CardContent className="space-y-3">
                        {example.content && (
                          <MarkdownMath content={example.content} />
                        )}
                        {example.latexFormula && (
                          <div className="rounded-lg bg-muted p-4 my-2 overflow-x-auto">
                            <BlockMath math={example.latexFormula} />
                          </div>
                        )}
                        {example.explanation && (
                          <div className="text-muted-foreground">
                            <MarkdownMath content={example.explanation} />
                          </div>
                        )}
                      </CardContent>
                    </Card>
                  ))}
                </div>
              ) : (
                <EmptyState
                  icon={<BookOpen className="h-12 w-12" />}
                  title="Sin ejemplos"
                  description="Los ejemplos estarán disponibles pronto."
                />
              )}
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="exercises" className="space-y-4">
          <Card>
            <CardHeader>
              <div className="flex items-center justify-between">
                <div>
                  <CardTitle>Ejercicios prácticos</CardTitle>
                  <CardDescription>
                    Pon a prueba tus conocimientos
                  </CardDescription>
                </div>
              </div>
            </CardHeader>
            <CardContent>
              {exercises && exercises.length > 0 ? (
                <div className="space-y-4">
                  {exercises.map((exercise: { id?: string; statement?: string; difficulty?: string; points?: number }, index: number) => {
                    const isExerciseCompleted = index < completedExercises;
                    return (
                      <Card
                        key={index}
                        className={cn(
                          'transition-colors hover:bg-accent/50',
                          isExerciseCompleted && 'border-green-500'
                        )}
                      >
                        <CardContent className="p-4">
                          <div className="flex items-center justify-between">
                            <div className="flex items-center gap-3">
                              <div
                                className={cn(
                                  'flex h-8 w-8 items-center justify-center rounded-full',
                                  isExerciseCompleted
                                    ? 'bg-green-500 text-white'
                                    : 'bg-muted'
                                )}
                              >
                                {isExerciseCompleted ? (
                                  <CheckCircle2 className="h-4 w-4" />
                                ) : (
                                  <span className="text-sm font-medium">
                                    {index + 1}
                                  </span>
                                )}
                              </div>
                              <div className="flex-1">
                                <div className="flex items-center gap-2">
                                  <p className="font-medium">Ejercicio {index + 1}</p>
                                  {exercise.difficulty && (
                                    <span className="rounded-full bg-muted px-2 py-0.5 text-xs">
                                      {exercise.difficulty}
                                    </span>
                                  )}
                                  {exercise.points != null && (
                                    <span className="text-xs text-muted-foreground">
                                      {exercise.points} pts
                                    </span>
                                  )}
                                </div>
                                {exercise.statement ? (
                                  <p className="text-sm text-muted-foreground mt-1">
                                    {exercise.statement}
                                  </p>
                                ) : (
                                  <p className="text-sm text-muted-foreground">
                                    {isExerciseCompleted ? 'Completado' : 'Pendiente'}
                                  </p>
                                )}
                              </div>
                            </div>
                            <Button
                              variant="ghost"
                              size="sm"
                            >
                              {isExerciseCompleted ? 'Ver solución' : 'Resolver'}
                            </Button>
                          </div>
                        </CardContent>
                      </Card>
                    );
                  })}
                </div>
              ) : (
                <EmptyState
                  icon={<PenTool className="h-12 w-12" />}
                  title="Sin ejercicios"
                  description="Este módulo aún no tiene ejercicios publicados."
                />
              )}
            </CardContent>
          </Card>
        </TabsContent>
      </Tabs>
    </div>
  );
}
