import Link from "next/link";
import { redirect } from "next/navigation";
import { UserRole } from "@prisma/client";
import { requireUser } from "@/lib/auth/requireUser";
import { db } from "@/lib/prisma";
import { getActiveRecommendations, getMiniGameGrade } from "@/lib/recommendations";

type ProfilePrismaClient = {
  miniGameAttempt: {
    findMany: (args: object) => Promise<
      {
        miniGameId: string;
        scorePercent: number;
        miniGame: { id: string; title: string; slug: string };
      }[]
    >;
  };
};

function getText(value: unknown): string {
  if (!value) return "";
  if (typeof value === "string") return value;
  if (typeof value === "object") {
    const record = value as Record<string, unknown>;
    if (typeof record.en === "string") return record.en;
    if (typeof record.es === "string") return record.es;
  }
  return "";
}

const levelLabel: Record<string, string> = {
  BEGINNER: "Beginner",
  INTERMEDIATE: "Intermediate",
  ADVANCED: "Advanced",
  EXPERT: "Expert",
};

export default async function ProfilePage() {
  const user = await requireUser();
  if (!user?.id) {
    redirect("/auth/login?redirectTo=/profile");
  }

  const isTeacher = user.role === UserRole.TEACHER || user.role === UserRole.SUPER_ADMIN;

  if (isTeacher) {
    const authoredCourses = await db.course
      .findMany({
        where: { authorId: user.id },
        select: {
          id: true,
          title: true,
          slug: true,
          tags: true,
          level: true,
          status: true,
          learningOutcomes: true,
          updatedAt: true,
          _count: {
            select: {
              modules: true,
              enrollments: true,
            },
          },
          modules: {
            select: {
              lessons: {
                select: {
                  id: true,
                  videoUrl: true,
                  youtubeUrl: true,
                  isFreePreview: true,
                },
              },
            },
          },
        },
        orderBy: { updatedAt: "desc" },
      })
      .catch((error) => {
        console.error("Failed to load authored courses for profile.", error);
        return [];
      });

    const totalCourses = authoredCourses.length;
    const publishedCourses = authoredCourses.filter((course) => course.status === "PUBLISHED").length;
    const totalModules = authoredCourses.reduce((acc, course) => acc + course._count.modules, 0);
    const totalStudents = authoredCourses.reduce((acc, course) => acc + course._count.enrollments, 0);

    const lessons = authoredCourses.flatMap((course) => course.modules.flatMap((module) => module.lessons));
    const totalLessons = lessons.length;
    const uploadedLessons = lessons.filter((lesson) => lesson.videoUrl || lesson.youtubeUrl).length;
    const previewLessons = lessons.filter((lesson) => lesson.isFreePreview).length;

    const topicSet = new Set<string>();
    const outcomeSet = new Set<string>();
    for (const course of authoredCourses) {
      for (const tag of course.tags) {
        if (tag.trim()) topicSet.add(tag.trim());
      }
      if (Array.isArray(course.learningOutcomes)) {
        for (const outcome of course.learningOutcomes) {
          if (typeof outcome === "string" && outcome.trim()) {
            outcomeSet.add(outcome.trim());
          }
        }
      }
    }

    const masteredTopics = topicSet.size > 0 ? [...topicSet] : [...new Set(authoredCourses.map((course) => levelLabel[course.level] ?? course.level))];
    const strengths = [...outcomeSet].slice(0, 8);

    return (
      <div className="acve-page">
        <section className="acve-panel acve-section-base">
          <p className="acve-pill mb-3 w-fit">Profile</p>
          <h1 className="text-3xl font-semibold leading-tight text-[#222a38] md:text-4xl">{user.fullName || user.email}</h1>
          <p className="mt-2 text-base text-slate-600">Teacher account | {user.email}</p>
        </section>

        <section className="grid gap-4 md:grid-cols-4">
          <article className="acve-panel p-5">
            <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">Courses created</p>
            <p className="mt-2 text-4xl font-semibold text-slate-900">{totalCourses}</p>
          </article>
          <article className="acve-panel p-5">
            <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">Published</p>
            <p className="mt-2 text-4xl font-semibold text-slate-900">{publishedCourses}</p>
          </article>
          <article className="acve-panel p-5">
            <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">Students</p>
            <p className="mt-2 text-4xl font-semibold text-slate-900">{totalStudents}</p>
          </article>
          <article className="acve-panel p-5">
            <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">Content units</p>
            <p className="mt-2 text-4xl font-semibold text-slate-900">{totalModules + totalLessons}</p>
            <p className="mt-2 text-sm text-slate-600">{totalModules} modules + {totalLessons} lessons</p>
          </article>
        </section>

        <section className="grid gap-4 lg:grid-cols-2">
          <article className="acve-panel p-5">
            <h2 className="text-2xl font-semibold text-slate-900">Topics mastered</h2>
            {masteredTopics.length === 0 ? (
              <p className="mt-3 text-sm text-slate-600">No topic metadata yet. Add tags to your courses.</p>
            ) : (
              <div className="mt-3 flex flex-wrap gap-2">
                {masteredTopics.map((topic) => (
                  <span key={topic} className="rounded-full border border-slate-300 px-3 py-1 text-xs font-semibold text-slate-700">
                    {topic}
                  </span>
                ))}
              </div>
            )}
            {strengths.length > 0 ? (
              <ul className="mt-4 space-y-2 text-sm text-slate-700">
                {strengths.map((item) => (
                  <li key={item} className="rounded-lg border border-slate-200 px-3 py-2">
                    {item}
                  </li>
                ))}
              </ul>
            ) : null}
          </article>

          <article className="acve-panel p-5">
            <h2 className="text-2xl font-semibold text-slate-900">Upload information</h2>
            <ul className="mt-3 space-y-2 text-sm text-slate-700">
              <li className="rounded-lg border border-slate-200 px-3 py-2">
                Lessons with media: {uploadedLessons}/{totalLessons || 0}
              </li>
              <li className="rounded-lg border border-slate-200 px-3 py-2">Preview lessons enabled: {previewLessons}</li>
              <li className="rounded-lg border border-slate-200 px-3 py-2">Lessons pending upload: {Math.max(totalLessons - uploadedLessons, 0)}</li>
            </ul>
            <Link className="mt-4 inline-flex text-sm font-semibold text-brand hover:underline" href="/teacher/uploads">
              Open upload library
            </Link>
          </article>
        </section>

        <section className="acve-panel p-5">
          <h2 className="text-2xl font-semibold text-slate-900">Recent course activity</h2>
          {authoredCourses.length === 0 ? (
            <p className="mt-3 text-sm text-slate-600">No courses yet. Start by creating a new course.</p>
          ) : (
            <ul className="mt-3 space-y-2">
              {authoredCourses.slice(0, 6).map((course) => (
                <li key={course.id} className="rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-700">
                  <p className="font-semibold text-slate-900">{getText(course.title) || "Untitled course"}</p>
                  <p className="text-xs text-slate-500">
                    {course.status} | {course._count.modules} modules | {course._count.enrollments} students | updated{" "}
                    {new Date(course.updatedAt).toLocaleDateString()}
                  </p>
                  <Link className="mt-1 inline-flex text-xs font-semibold text-brand hover:underline" href={`/teacher/courses/${course.slug}/edit`}>
                    Open editor
                  </Link>
                </li>
              ))}
            </ul>
          )}
        </section>
      </div>
    );
  }

  const [grade, recommendations, certificates] = await Promise.all([
    getMiniGameGrade(user.id).catch((error) => {
      console.error("Failed to load mini-game grade.", error);
      return 0;
    }),
    getActiveRecommendations(user.id).catch((error) => {
      console.error("Failed to load recommendations.", error);
      return [];
    }),
    db.certificate
      .findMany({
        where: { userId: user.id },
        select: {
          id: true,
          issuedAt: true,
          metadataSnapshot: true,
          course: {
            select: {
              title: true,
              slug: true,
            },
          },
        },
        orderBy: { issuedAt: "desc" },
      })
      .catch((error) => {
        console.error("Failed to load certificates for profile.", error);
        return [];
      }),
  ]);

  let attempts: {
    miniGameId: string;
    scorePercent: number;
    miniGame: { id: string; title: string; slug: string };
  }[] = [];
  try {
    attempts = await (db as unknown as ProfilePrismaClient).miniGameAttempt.findMany({
      where: { userId: user.id },
      include: {
        miniGame: {
          select: {
            id: true,
            title: true,
            slug: true,
          },
        },
      },
      orderBy: { completedAt: "desc" },
    });
  } catch {
    attempts = [];
  }

  const latestByGame = new Map<string, number>();
  const bestByGame = new Map<string, number>();
  const titleByGame = new Map<string, string>();
  for (const attempt of attempts) {
    if (!latestByGame.has(attempt.miniGameId)) {
      latestByGame.set(attempt.miniGameId, attempt.scorePercent);
    }
    const best = bestByGame.get(attempt.miniGameId) ?? 0;
    if (attempt.scorePercent > best) {
      bestByGame.set(attempt.miniGameId, attempt.scorePercent);
    }
    titleByGame.set(attempt.miniGameId, attempt.miniGame.title);
  }

  const gameRows = [...titleByGame.keys()].map((gameId) => ({
    gameId,
    title: titleByGame.get(gameId) ?? "Mini-game",
    latest: latestByGame.get(gameId) ?? 0,
    best: bestByGame.get(gameId) ?? 0,
  }));

  return (
    <div className="acve-page">
      <section className="acve-panel acve-section-base">
        <p className="acve-pill mb-3 w-fit">Profile</p>
        <h1 className="text-3xl font-semibold leading-tight text-[#222a38] md:text-4xl">{user.fullName || user.email}</h1>
        <p className="mt-2 text-base text-slate-600">{user.email}</p>
      </section>

      <section className="grid gap-4 md:grid-cols-3">
        <article className="acve-panel p-5">
          <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">Mini-game grade</p>
          <p className="mt-2 text-4xl font-semibold text-slate-900">{grade}%</p>
          <p className="mt-2 text-sm text-slate-600">Average of latest attempts across mini-games.</p>
        </article>
        <article className="acve-panel p-5">
          <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">Attempts</p>
          <p className="mt-2 text-4xl font-semibold text-slate-900">{attempts.length}</p>
          <Link className="mt-2 inline-flex text-sm font-semibold text-brand hover:underline" href="/practice">
            Play mini-games
          </Link>
        </article>
        <article className="acve-panel p-5">
          <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">Certificates</p>
          <p className="mt-2 text-4xl font-semibold text-slate-900">{certificates.length}</p>
          <Link className="mt-2 inline-flex text-sm font-semibold text-brand hover:underline" href="/my-courses">
            View my courses
          </Link>
        </article>
      </section>

      <section className="grid gap-4 lg:grid-cols-2">
        <article className="acve-panel p-5">
          <h2 className="text-2xl font-semibold text-slate-900">Mini-game breakdown</h2>
          {gameRows.length === 0 ? (
            <p className="mt-3 text-sm text-slate-600">No attempts yet. Complete a mini-game to generate your grade.</p>
          ) : (
            <ul className="mt-3 space-y-2">
              {gameRows.map((row) => (
                <li key={row.gameId} className="rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-700">
                  <span className="font-semibold text-slate-900">{row.title}</span> | latest: {row.latest}% | best: {row.best}%
                </li>
              ))}
            </ul>
          )}
        </article>

        <article className="acve-panel p-5">
          <h2 className="text-2xl font-semibold text-slate-900">Recommended next</h2>
          {recommendations.length === 0 ? (
            <p className="mt-3 text-sm text-slate-600">No recommendations yet. Complete a mini-game or enroll in a course first.</p>
          ) : (
            <ul className="mt-3 space-y-2">
              {recommendations.map((recommendation) => (
                <li key={recommendation.courseId} className="rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-700">
                  <p className="font-semibold text-slate-900">{recommendation.title}</p>
                  <p className="text-xs text-slate-500">{recommendation.reason}</p>
                  <Link className="mt-1 inline-flex text-xs font-semibold text-brand hover:underline" href={`/courses/${recommendation.slug}`}>
                    Open course
                  </Link>
                </li>
              ))}
            </ul>
          )}
        </article>
      </section>

      <section className="acve-panel p-5">
        <h2 className="text-2xl font-semibold text-slate-900">Certificates</h2>
        {certificates.length === 0 ? (
          <p className="mt-3 text-sm text-slate-600">No certificates issued yet.</p>
        ) : (
          <ul className="mt-3 space-y-2">
            {certificates.map((certificate) => {
              const certificateNumber =
                (certificate as Record<string, unknown>).certificateNumber ??
                (certificate.metadataSnapshot as Record<string, unknown> | null)?.certificateNumber ??
                "N/A";
              return (
                <li key={certificate.id} className="rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-700">
                  <p className="font-semibold text-slate-900">{getText(certificate.course.title) || "Course"}</p>
                  <p className="text-xs text-slate-500">
                    Certificate #{String(certificateNumber)} | issued {new Date(certificate.issuedAt).toLocaleDateString()}
                  </p>
                  <Link className="mt-1 inline-flex text-xs font-semibold text-brand hover:underline" href={`/api/certificates/${certificate.id}/pdf`}>
                    Download PDF
                  </Link>
                </li>
              );
            })}
          </ul>
        )}
      </section>
    </div>
  );
}
