import "katex/dist/katex.min.css";
import { DomUtils, parseDocument } from "htmlparser2";
import Latex from "react-latex-next";
import { useState } from "react";
import { Link, Navigate, useNavigate, useParams } from "react-router";
import { Button } from "~/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import {
  ArrowLeft,
  Clock,
  User,
  UserCheck,
  MessageSquare,
  Paperclip,
  Star,
  ChevronUp,
  ChevronDown,
  MapPinHouse,
  RefreshCw,
  Share2,
  ExternalLink,
  Users,
  Album,
} from "lucide-react";
import { Separator } from "~/components/ui/separator";
import ColleDetailsSkeleton from "~/components/details/skeleton-details";
import AttachmentItem from "~/components/details/attachment";
import Error from "~/components/error";
import { Badge } from "~/components/ui/badge";
import {
  AUTH_ERROR,
  refreshColle,
  useColle,
  useUser,
  type Colle,
} from "~/lib/api";
import { toast } from "sonner";
import {
  formatDate,
  formatGrade,
  formatTime,
  getColleWeek,
  getColorClass,
  getSubjectColor,
  getSubjectEmoji,
  goBack,
} from "~/lib/utils";
import { useQueryClient } from "@tanstack/react-query";

// TODO: Move all code to components
export default function ColleDetailPage() {
  const { user, isLoading: isUserLoading, error: userError } = useUser();
  const queryClient = useQueryClient();

  const navigate = useNavigate();
  const params = useParams<{ colleId: string }>();

  const colleId = parseInt(params.colleId!);
  if (isNaN(colleId)) {
    return <Navigate to="/" />;
  }
  const { colle, error, isLoading } = useColle(colleId);

  const [isReloading, setIsReloading] = useState(false);

  if (isUserLoading) {
    return <ColleDetailsSkeleton />;
  }
  if (userError?.message === AUTH_ERROR) {
    return <Navigate to="/login" replace />;
  }
  if (userError) {
    return <Error message={userError.message} />;
  }

  // TODO: Favorite toggle function
  const toggleStar = () => {};

  if (error)
    return (
      <Error
        title="Impossible de charger cette colle"
        message={error?.toString()}
        code={500}
        description="Une erreur s'est produite lors du chargement de la colle."
      />
    );
  if (isLoading || !colle) return <ColleDetailsSkeleton />;

  const handleToggleFavorite = () => {};

  // TODO: Temp fix to get the colle syllabus
  const getColleSyllabus = (colle: Colle) => {
    // Return YYYYMMDD format
    const formatDateForSyllabus = (date: Date) => {
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, "0");
      const day = String(date.getDate()).padStart(2, "0");
      return `${year}${month}${day}`;
    };

    // Physique-Chimie
    if (colle.subject.name === "Physique-Chimie") {
      return (
        "https://bjcolle.fr/syllabus_oral.php?disc=22&jour=" +
        formatDateForSyllabus(new Date(colle.date))
      );
    }

    // Mathématiques
    if (colle.subject.name === "Mathématiques" && (user.className == "MP-1" || user.className == "MP-2")) {
      const week = getColleWeek(new Date(colle.date)); // Syllabus weeks are 1-indexed
      if (week)
        return "http://www.mp1.bginette.com/Colles/ColleXX.pdf".replace(
          "XX",
          (week + 1).toString().padStart(2, "0")
        );
    }

    return null;
  };

  const handleReload = () => {
    setIsReloading(true);
    refreshColle(colle.id)
      .then(() => {
        toast("Les données de cette colle vont être mises à jour", {
          icon: "🔄",
          description: "Rafraîchissement en cours...",
        });
      })
      .catch((error) => {
        console.error("Error refreshing colle:", error);
        toast.error("Échec du rafraîchissement de la colle", {
          icon: "❌",
          description: "Veuillez réessayer plus tard.",
        });
      })
      .finally(() => {
        setIsReloading(false);
        queryClient.invalidateQueries({
          queryKey: ["colle", colle.id],
        });
      });
  };

  const handleShare = async () => {
    const shareUrl = window.location.href;
    const shareTitle = `Colle de ${colle.subject.name} - ${colle.student.fullName}`;
    const shareText = `Colle de ${colle.subject.name} du ${formatDate(
      colle.date
    )} à ${formatTime(colle.date)} - ${colle.student.fullName} avec ${
      colle.examiner.name
    }.\n\nConsultez-le résumé ici :`;
    try {
      if (navigator.share) {
        await navigator.share({
          title: shareTitle,
          text: shareText,
          url: shareUrl,
        });
      } else {
        // Fallback to copying the URL
        await navigator.clipboard.writeText(shareUrl);
        toast("Lien copié dans le presse-papiers", {
          icon: "📋",
          description: "Vous pouvez le partager avec vos amis !",
        });
      }
    } catch (error) {
      console.error("Error sharing:", error);
    }
  };

  const handleOpenBJColle = () => {
    const url = `https://bjcolle.fr/students_oral_disp.php?colle=${colle.bjid}&hgfebrgl8ri3h=${colle.bjsecret}`;
    window.open(url, "_blank");
    toast("Ouverture de BJColle", {
      icon: "🔗",
      description: "Redirection vers BJColle...",
    });
  };

  const subjectColor = getColorClass(
    getSubjectColor(colle.subject.name, user.preferences)
  );
  const subjectEmoji = getSubjectEmoji(colle.subject.name, user.preferences);
  const syllabusLink = getColleSyllabus(colle);

  return (
    <div className="container mx-auto py-6 px-4 pb-20 md:pb-6 md:py-8">
      <div className="flex justify-between items-center mb-4">
        <Button variant="outline" onClick={() => goBack(navigate)}>
          <ArrowLeft className="h-4 w-4 mr-2" />
          Retour
        </Button>
        <div className="flex md:hidden items-center gap-2">
          <div className="space-x-2">
            <Button
              variant="outline"
              size="icon"
              className="h-10 w-10"
              onClick={handleReload}
              disabled={isReloading}
            >
              <RefreshCw
                className={`h-5 w-5 ${isReloading ? "animate-spin" : ""}`}
              />
              <span className="sr-only">Recharger</span>
            </Button>
            {syllabusLink && (
              <Button
                variant="outline"
                size="icon"
                className="h-10 w-10"
                onClick={() => window.open(syllabusLink, "_blank")}
              >
                <Album className={"h-5 w-5"} />
                <span className="sr-only">Programme de colle</span>
              </Button>
            )}
            <Button
              variant="outline"
              size="icon"
              className="h-10 w-10"
              onClick={handleShare}
            >
              <Share2 className="h-5 w-5" />
            </Button>
          </div>
        </div>
      </div>

      <Card className="max-w-3xl mx-auto">
        <CardHeader className="pb-2">
          <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-2">
            <div className="flex flex-col">
              <div className="flex items-center justify-between">
                <CardTitle className="text-xl">
                  Colle de {colle.subject.name}
                </CardTitle>
                {colle.grade && (
                  <div
                    className={`md:hidden px-3 py-1 rounded-md text-sm font-medium ${subjectColor}`}
                  >
                    {formatGrade(colle.grade)}/20
                  </div>
                )}
              </div>
              <div className="flex items-center gap-2 mt-2">
                <Badge className={subjectColor}>
                  {colle.subject.name} {subjectEmoji}
                </Badge>
              </div>
            </div>

            {/* Desktop Action Buttons */}
            <div className="hidden md:flex items-center gap-2">
              <Button
                variant="outline"
                size="sm"
                className="h-9 w-9"
                onClick={handleShare}
                title="Partager"
              >
                <Share2 className="h-4 w-4" />
                <span className="sr-only">Partager</span>
              </Button>

              {syllabusLink && (
                <Button
                  variant="outline"
                  size="icon"
                  className="h-10 w-10"
                  onClick={() => window.open(syllabusLink, "_blank")}
                >
                  <Album className={"h-5 w-5"} />
                  <span className="sr-only">Programme de colle</span>
                </Button>
              )}

              <Button
                variant="outline"
                size="sm"
                className="h-9 w-9"
                onClick={handleReload}
                disabled={isReloading}
                title="Recharger"
              >
                <RefreshCw
                  className={`h-4 w-4 ${isReloading ? "animate-spin" : ""}`}
                />
                <span className="sr-only">Recharger</span>
              </Button>

              {/* <Button
                variant="ghost"
                size="sm"
                className={`h-9 w-9 ${
                  // TODO: Use a proper favorite state
                  false ? "text-yellow-500" : "text-muted-foreground"
                }`}
                onClick={handleToggleFavorite}
              >
                <Star
                  className={`h-5 w-5 ${
                    // TODO: Use a proper favorite state
                    false ? "fill-yellow-500" : ""
                  }`}
                />
                <span className="sr-only">Ajouter aux favoris</span>
              </Button> */}

              {colle.grade && (
                <div
                  className={`px-3 py-1 rounded-md text-sm font-medium ${subjectColor}`}
                >
                  {formatGrade(colle.grade)}/20
                </div>
              )}
            </div>
          </div>
        </CardHeader>

        <CardContent className="space-y-4">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-2">
            <div className="space-y-2">
              <div>
                <h3 className="text-sm font-medium text-muted-foreground mb-1">
                  Date
                </h3>
                <div className="flex items-center gap-2">
                  <Clock className="h-4 w-4" />
                  <span>
                    {formatDate(colle.date)}, à {formatTime(colle.date)}
                  </span>
                </div>
              </div>

              <div>
                <h3 className="text-sm font-medium text-muted-foreground mb-1">
                  Colleur
                </h3>
                <div className="flex items-center gap-2">
                  <UserCheck className="h-4 w-4" />
                  <span>{colle.examiner.name}</span>
                </div>
              </div>
            </div>

            <div className="space-y-2">
              <div>
                <h3 className="text-sm font-medium text-muted-foreground mb-1">
                  Élève
                </h3>
                <div className="flex items-center gap-2">
                  <User className="h-4 w-4" />
                  <span>{colle.student.fullName}</span>
                </div>
              </div>

              {colle.relatives?.length > 0 && (
                <div>
                  <h3 className="text-sm font-medium text-muted-foreground mb-1">
                    Autres élèves
                  </h3>
                  {colle.relatives.map((linkedColle) => (
                    <div className="flex items-center gap-2">
                      <Users className="h-4 w-4" />
                      <Link
                        to={`/colles/${linkedColle.id}`}
                        key={linkedColle.id}
                      >
                        {linkedColle.student.fullName}
                      </Link>
                    </div>
                  ))}
                </div>
              )}
            </div>

            {colle.room && (
              <div className="space-y-2">
                <div>
                  <h3 className="text-sm font-medium text-muted-foreground mb-1">
                    Salle
                  </h3>
                  <div className="flex items-center gap-2">
                    <MapPinHouse className="h-4 w-4" />
                    <span>{colle.room.name}</span>
                  </div>
                </div>
              </div>
            )}
          </div>

          {colle.content && (
            <>
              <Separator />

              <div>
                <h3 className="text-lg font-medium mb-2 flex items-center gap-2">
                  <MessageSquare className="h-5 w-5" />
                  Sujet
                </h3>

                <div className="p-4 bg-muted rounded-lg">
                  <ExpandableComment comment={colle.content} />
                </div>
              </div>
            </>
          )}

          {colle.comment && (
            <>
              <Separator />

              <div>
                <h3 className="text-lg font-medium mb-2 flex items-center gap-2">
                  <MessageSquare className="h-5 w-5" />
                  Commentaires
                </h3>
                <div className="p-4 bg-muted rounded-lg">
                  <ExpandableComment comment={colle.comment} />
                </div>
              </div>
            </>
          )}

          {colle.attachments && colle.attachments?.length > 0 && (
            <div>
              <h3 className="text-lg font-medium mb-3 flex items-center gap-2">
                <Paperclip className="h-5 w-5" />
                Pièces jointes
              </h3>
              <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
                {colle.attachments.map((attachment, index) => (
                  <AttachmentItem key={index} attachment={attachment} />
                ))}
              </div>
            </div>
          )}

          {/* BJColle External Link */}
          <div className="mt-8 pt-4 border-t border-dashed">
            <div className="flex justify-end items-center space-x-1 mt-1 text-xs text-muted-foreground">
              <ExternalLink className="h-4 w-4" />
              <span onClick={handleOpenBJColle}>
                Accéder à la colle depuis BJColle
              </span>
            </div>
          </div>
        </CardContent>
      </Card>
    </div>
  );
}

// TODO: Custom render component for LaTeX rendering
// Component for expandable comments
function ExpandableComment({ comment }: { comment: string }) {
  // Crop comments longer than 750 characters
  const [isExpanded, setIsExpanded] = useState(false);
  const commentLimit = 750; // Character limit before truncating
  const isLongComment = removeHtmlElements(comment).length > commentLimit;

  const toggleExpand = () => {
    setIsExpanded(!isExpanded);
  };

  const displayedComment =
    isExpanded || !isLongComment
      ? comment
      : `${comment.substring(0, commentLimit)}...`;

  return (
    <div>
      <Latex delimiters={[{ left: "$$", right: "$$", display: false }]}>
        {displayedComment}
      </Latex>
      {isLongComment && (
        <Button
          variant="ghost"
          size="sm"
          className="mt-1 h-7 px-2 text-primary"
          onClick={toggleExpand}
        >
          {isExpanded ? (
            <span className="flex items-center gap-1">
              Afficher moins <ChevronUp className="h-3 w-3" />
            </span>
          ) : (
            <span className="flex items-center gap-1">
              Afficher plus <ChevronDown className="h-3 w-3" />
            </span>
          )}
        </Button>
      )}
    </div>
  );
}

// Remove HTML elements and return plain text (for text length calculation and cropping)
function removeHtmlElements(htmlString: string) {
  const document = parseDocument(htmlString);
  return DomUtils.textContent(document).trim();
}
