/*
  page.tsx
  spboucher.ai Web
  Author: Simon-Pierre Boucher
  Mail: contact@spboucher.ai
*/

import type { Metadata } from "next";
import type { LucideIcon } from "lucide-react";
import {
  BadgeCheck,
  BookOpen,
  FileText,
  Github,
  Library,
  NotebookPen,
  PencilLine,
  Presentation,
  School,
  Sigma,
  Terminal,
  Users,
  Wrench,
} from "lucide-react";

import { Badge } from "@/components/ui/badge";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { PillLink } from "@/components/pill-link";
import { Reveal } from "@/components/reveal";
import { SectionHeading } from "@/components/section-heading";

export const metadata: Metadata = {
  title: "Teaching",
  description:
    "Courses taught by Simon-Pierre Boucher at Université Laval — capital markets, financial econometrics, financial management, and financial theory.",
};

const UQO_REPO = "https://git.spboucher.ai/uqo_cours_public";
const UQO_RAW =
  "https://raw.githubusercontent.com/spboucher-ai/UQO_COURS_PUBLIC/main";

const imm1033Slides = [
  "seance01_introduction",
  "seance02_cadre_conceptuel",
  "seance03_evaluation_terrain",
  "seance04_analyse_terrain",
  "seance05_reproduction_remplacement",
  "seance06_methodes_estimation",
  "seance07_couts_directs",
  "seance08_couts_indirects",
  "seance09_concepts_depreciation",
  "seance10_depreciation_physique",
  "seance11_depreciation_fonctionnelle",
  "seance12_depreciation_economique",
  "seance13_applications_specialisees",
  "seance14_synthese_revision",
];

interface UqoCourse {
  code: string;
  title: string;
  description: string;
  dir: string;
  slides: { label: string; file: string; topic?: string }[];
  tps: { label: string; file: string }[];
}

const uqoCourses: UqoCourse[] = [
  {
    code: "IMM1003",
    title: "Éléments d'évaluation immobilière",
    description:
      "Foundations of real-estate appraisal — market analysis, comparison and income methods.",
    dir: "IMM1003-20_Elements_evaluation_immobiliere",
    slides: Array.from({ length: 14 }, (_, i) => {
      const n = String(i + 1).padStart(2, "0");
      return { label: n, file: `02_Slides/pdf/seance${n}.pdf` };
    }),
    tps: [
      {
        label: "TP1 — Tableau de bord du marché",
        file: "03_Travaux_pratiques/TP1_Tableau_de_bord_du_marche/enonce/IMM1003-20_TP1_enonce.pdf",
      },
      {
        label: "TP2 — Méthode de comparaison",
        file: "03_Travaux_pratiques/TP2_Methode_de_comparaison/enonce/IMM1003-20_TP2_enonce.pdf",
      },
      {
        label: "TP3 — Méthode du revenu",
        file: "03_Travaux_pratiques/TP3_Methode_du_revenu/enonce/IMM1003-20_TP3_enonce.pdf",
      },
    ],
  },
  {
    code: "IMM1033",
    title: "Méthodes du coût",
    description:
      "Cost approach to valuation — land value, replacement cost, and depreciation analysis.",
    dir: "IMM1033-20_Methodes_du_cout",
    slides: imm1033Slides.map((name, i) => ({
      label: String(i + 1).padStart(2, "0"),
      file: `02_Slides/pdf/${name}.pdf`,
      topic: name.slice(9).replace(/_/g, " "),
    })),
    tps: [
      {
        label: "TP1 — Évaluation d'un terrain",
        file: "03_Travaux_pratiques/TP1_Evaluation_d_un_terrain/enonce/IMM1033-20_TP1_enonce.pdf",
      },
      {
        label: "TP2 — Bordereau de coût neuf",
        file: "03_Travaux_pratiques/TP2_Bordereau_de_cout_neuf/enonce/IMM1033-20_TP2_enonce.pdf",
      },
      {
        label: "TP3 — Ventilation de la dépréciation",
        file: "03_Travaux_pratiques/TP3_Ventilation_de_la_depreciation/enonce/IMM1033-20_TP3_enonce.pdf",
      },
    ],
  },
];

const GH_RAW = "https://raw.githubusercontent.com/spboucher-ai";

interface MaterialGroup {
  title: string;
  kind: "pills" | "list";
  icon: LucideIcon;
  links: { label: string; file: string; topic?: string }[];
}

interface UlavalCourse {
  code: string;
  title: string;
  term: string;
  repoName: string;
  description: string;
  groups: MaterialGroup[];
}

const ulavalCourses: UlavalCourse[] = [
  {
    code: "GSF-3100",
    title: "Capital Markets (Marché des capitaux)",
    term: "Undergraduate · F2021–W2023",
    repoName: "gsf3100",
    description:
      "Fixed income and capital markets — LaTeX Beamer slides for every section of the course.",
    groups: [
      {
        title: "Slides — 13 section decks (PDF)",
        kind: "pills",
        icon: Presentation,
        links: [
          { label: "01", file: "Section 1/GSF3100_S01.pdf" },
          { label: "02", file: "Section 2/GSF3100_S02.pdf" },
          { label: "03", file: "Section 3/GSF3100_S03.pdf" },
          { label: "04", file: "Section 4/GSF3100_S04.pdf" },
          { label: "05", file: "Section 5/GSF3100_S05.pdf" },
          { label: "06", file: "Section 6/GSF3100_S6.pdf" },
          { label: "07", file: "Section 7/GSF3100_S7.pdf" },
          { label: "08", file: "Section 8/GSF3100_S08.pdf" },
          { label: "9a", file: "Section 9/a/GSF3100_S09a.pdf" },
          { label: "9b", file: "Section 9/b/GSF3100_S09b.pdf" },
          { label: "9c", file: "Section 9/c/GSF3100_S09c.pdf" },
          { label: "10a", file: "Section 10/a/GSF3100_S10a.pdf" },
          { label: "10b", file: "Section 10/b/GSF3100_S10b.pdf" },
        ],
      },
    ],
  },
  {
    code: "GSF-6053",
    title: "Financial Econometrics I",
    term: "Graduate · W2022",
    repoName: "gsf6053",
    description:
      "OLS, MLE, hypothesis testing, and time-series econometrics — session slides plus Stata lab sessions.",
    groups: [
      {
        title: "Slides — sessions 2–12 (PDF)",
        kind: "pills",
        icon: Presentation,
        links: Array.from({ length: 11 }, (_, i) => {
          const n = i + 2;
          return {
            label: String(n).padStart(2, "0"),
            file: `Séance ${n}/GSF6053_S${n}.pdf`,
          };
        }),
      },
      {
        title: "Stata labs (PDF)",
        kind: "list",
        icon: Terminal,
        links: [
          { label: "Stata session 02", file: "STATA_S02/GSF6053_STATA_02.pdf" },
          { label: "Stata session 03", file: "STATA_S03/GSF6053_STATA_03.pdf" },
        ],
      },
    ],
  },
  {
    code: "GSF-6053",
    title: "Financial Econometrics I",
    term: "Graduate · W2025",
    repoName: "gsf6053_h25",
    description:
      "Full W2025 edition — lecture slides, typed lecture notes, formal proofs, and 14 exercise sets with complete solutions.",
    groups: [
      {
        title: "Lecture slides (PDF)",
        kind: "list",
        icon: Presentation,
        links: [
          {
            label: "S1 — Introduction",
            file: "PDF/GSF6053_H25_Séance1_Introduction.pdf",
          },
          {
            label: "S1 — Statistics review",
            file: "PDF/GSF6053_H25_Séance1_Révision.pdf",
          },
          { label: "S1 — OLS (MCO)", file: "PDF/GSF6053_H25_Séance1_MCO.pdf" },
          {
            label: "S2 — Maximum likelihood (MLE)",
            file: "PDF/GSF6053_H25_Séance2_MLE.pdf",
          },
          {
            label: "S3 — Hypothesis tests & ANOVA",
            file: "PDF/GS6053_H25_Séance3_Tests_ANOVA.pdf",
          },
          {
            label: "S4 — Extensions of the linear model",
            file: "PDF/GSF6053_H25_Séance4_Extensions_Modèle_Linéaire.pdf",
          },
          {
            label: "S5 — Heteroskedasticity",
            file: "PDF/GSF6053_H25_Séance5_Hétéroscédasticité.pdf",
          },
          {
            label: "S6 — Autocorrelation",
            file: "PDF/GSF6053_H25_Séance6_Autocorrélation.pdf",
          },
        ],
      },
      {
        title: "Lecture notes (PDF)",
        kind: "list",
        icon: NotebookPen,
        links: [
          { label: "Introduction", file: "PDF/GSF6053_H25_NOTE_INTRO.pdf" },
          {
            label: "Prerequisites",
            file: "PDF/GSF6053_H25_NOTE_PRÉALABLE.pdf",
          },
          { label: "OLS (MCO)", file: "PDF/GSF6053_H25_NOTE_MCO.pdf" },
          { label: "MLE", file: "PDF/GSF6053_H25_NOTE_MLE.pdf" },
          {
            label: "Hypothesis testing",
            file: "PDF/GSF6053_H25_NOTE_Test_hypothèse.pdf",
          },
          { label: "ANOVA", file: "PDF/GSF6053_H25_NOTE_ANOVA.pdf" },
          { label: "GLS (MCG)", file: "PDF/GSF6053_H25_NOTE_MCG.pdf" },
          {
            label: "Heteroskedasticity",
            file: "PDF/GSF6053_H25_NOTE_HETEROSCEDASTICITE.pdf",
          },
          { label: "White test", file: "PDF/GSF6053_H25_NOTE_WHITE_TEST.pdf" },
          {
            label: "Breusch–Pagan test",
            file: "PDF/GSF6053_H25_Note_Breusch_Pagan.pdf",
          },
          {
            label: "Autocorrelation",
            file: "PDF/GSF6053_H25_NOTE_AUTOCORÉLATION.pdf",
          },
        ],
      },
      {
        title: "Formal proofs (PDF)",
        kind: "list",
        icon: Sigma,
        links: [
          {
            label: "OLS — summation form",
            file: "PDF/GSF6053_H25_preuve_MCO_sommation.pdf",
          },
          {
            label: "OLS — matrix form",
            file: "PDF/GSF6053_H25_preuve_MCO_matriciel.pdf",
          },
          { label: "GLS", file: "PDF/GSF6053_H25_preuve_MCG.pdf" },
          { label: "MLE", file: "PDF/GSF6053_H25_preuve_MLE.pdf" },
          {
            label: "Cramér–Rao bound",
            file: "PDF/GSF6053_H25_preuve_cramer_rao.pdf",
          },
          {
            label: "Cochrane–Orcutt",
            file: "PDF/GSF6053_H25_preuve_cochrane_orcutt.pdf",
          },
          {
            label: "Prais–Winsten",
            file: "PDF/GSF6053_H25_preuve_prais_winsten.pdf",
          },
        ],
      },
      {
        title: "Exercise sets 1–14 (PDF)",
        kind: "pills",
        icon: PencilLine,
        links: Array.from({ length: 14 }, (_, i) => {
          const n = String(i + 1).padStart(3, "0");
          return {
            label: String(i + 1).padStart(2, "0"),
            file: `PDF/GSF6053_H25_EXO_${n}.pdf`,
          };
        }),
      },
      {
        title: "Solutions 1–14 (PDF)",
        kind: "pills",
        icon: BadgeCheck,
        links: Array.from({ length: 14 }, (_, i) => {
          const n = String(i + 1).padStart(3, "0");
          return {
            label: String(i + 1).padStart(2, "0"),
            file: `PDF/GSF6053_H25_SOL_${n}.pdf`,
          };
        }),
      },
    ],
  },
];

const courses = [
  {
    code: "GSF-3100",
    title: "Capital Markets",
    level: "Undergraduate",
    terms: "F2021, W2021, F2022, W2023",
  },
  {
    code: "GSF-6053",
    title: "Financial Econometrics I",
    level: "Graduate",
    terms: "W2022, W2025",
  },
  {
    code: "GSF-1500",
    title: "Financial Management",
    level: "Undergraduate",
    terms: "S2022",
  },
  {
    code: "GSF-6028",
    title: "Financial Theory",
    level: "Graduate",
    terms: "W2024",
  },
];

const taCourses = [
  { code: "GSF-2101", title: "Portfolio Management" },
  { code: "GSF-2102", title: "Corporate Finance" },
  { code: "GSF-6008", title: "Corporate Finance" },
  { code: "GSF-6025", title: "Financial Strategies & Policies I" },
  { code: "GSF-6028", title: "Financial Theory" },
];

export default function TeachingPage() {
  return (
    <div className="mx-auto max-w-5xl px-4 py-16 sm:px-6">
      <Reveal>
        <SectionHeading
          as="h1"
          eyebrow="Courses"
          title="Teaching"
          icon={BookOpen}
          description="Professor at Université du Québec en Outaouais (UQO), previously Lecturer (2021–Present) and Teaching Assistant (2018–2021) at Université Laval."
        />
      </Reveal>

      {/* UQO courses with material */}
      <section className="mt-12">
        <Reveal>
          <SectionHeading
            title="Professor — Université du Québec en Outaouais (UQO)"
            icon={School}
            description="Complete course material — Beamer slides, practical assignments with Excel templates, and a Québec real-estate market report — is openly available on GitHub."
          />
        </Reveal>
        <div className="mt-4 grid gap-4 sm:grid-cols-2">
          {uqoCourses.map((course, i) => (
            <Reveal key={course.code} delay={i * 0.08} className="h-full">
              <Card className="flex h-full flex-col">
                <CardHeader>
                  <Badge className="w-fit font-mono">{course.code}</Badge>
                  <CardTitle className="text-lg leading-snug">
                    {course.title}
                  </CardTitle>
                  <CardDescription>{course.description}</CardDescription>
                </CardHeader>
                <CardContent className="flex flex-1 flex-col gap-4">
                  <div>
                    <PillLink
                      href={`${UQO_RAW}/${course.dir}/01_Plan_de_cours/plan_de_cours.pdf`}
                      icon={FileText}
                    >
                      Course plan (PDF)
                    </PillLink>
                  </div>

                  <div>
                    <p className="inline-flex items-center gap-2 text-sm font-medium">
                      <Presentation
                        className="h-4 w-4 text-primary"
                        aria-hidden="true"
                      />
                      Slides — 14 sessions (PDF)
                    </p>
                    <div className="mt-2 flex flex-wrap gap-1.5">
                      {course.slides.map((slide) => (
                        <a
                          key={slide.file}
                          href={`${UQO_RAW}/${course.dir}/${slide.file}`}
                          target="_blank"
                          rel="noopener noreferrer"
                          title={slide.topic}
                          aria-label={`Session ${slide.label}${slide.topic ? ` — ${slide.topic}` : ""} (PDF)`}
                          className="inline-flex h-8 w-9 items-center justify-center rounded-full border border-border/70 bg-card/70 text-xs font-medium text-muted-foreground shadow-sm transition-all hover:-translate-y-px hover:border-primary/40 hover:bg-primary/10 hover:text-primary"
                        >
                          {slide.label}
                        </a>
                      ))}
                    </div>
                  </div>

                  <div>
                    <p className="inline-flex items-center gap-2 text-sm font-medium">
                      <Wrench
                        className="h-4 w-4 text-primary"
                        aria-hidden="true"
                      />
                      Practical assignments (PDF)
                    </p>
                    <div className="mt-2 flex flex-wrap gap-1.5">
                      {course.tps.map((tp) => (
                        <PillLink
                          key={tp.file}
                          href={`${UQO_RAW}/${course.dir}/${tp.file}`}
                        >
                          {tp.label}
                        </PillLink>
                      ))}
                    </div>
                  </div>
                </CardContent>
              </Card>
            </Reveal>
          ))}
        </div>
        <Reveal className="mt-4">
          <div className="flex flex-wrap gap-2">
            <PillLink
              href={`${UQO_RAW}/Rapport_Immobilier_Quebec/rapport_immobilier_quebec.pdf`}
              icon={FileText}
            >
              Québec real-estate market report (PDF)
            </PillLink>
            <PillLink href={UQO_REPO} icon={Github}>
              Full course repository
            </PillLink>
          </div>
        </Reveal>
      </section>

      {/* Lecturer */}
      <section className="mt-12">
        <Reveal>
          <SectionHeading
            title="Lecturer — Université Laval (2021–Present)"
            icon={BookOpen}
          />
          <Card className="mt-4 overflow-x-auto">
            <CardContent className="p-0">
              <table className="w-full text-sm">
                <thead>
                  <tr className="border-b border-border text-left">
                    <th scope="col" className="px-4 py-3 font-medium">
                      Code
                    </th>
                    <th scope="col" className="px-4 py-3 font-medium">
                      Course
                    </th>
                    <th scope="col" className="px-4 py-3 font-medium">
                      Level
                    </th>
                    <th scope="col" className="px-4 py-3 font-medium">
                      Terms
                    </th>
                  </tr>
                </thead>
                <tbody>
                  {courses.map((course) => (
                    <tr
                      key={`${course.code}-${course.terms}`}
                      className="border-b border-border last:border-0"
                    >
                      <td className="px-4 py-3 font-mono text-xs">
                        {course.code}
                      </td>
                      <td className="px-4 py-3 font-medium">{course.title}</td>
                      <td className="px-4 py-3">
                        <Badge
                          variant={
                            course.level === "Graduate"
                              ? "default"
                              : "secondary"
                          }
                        >
                          {course.level}
                        </Badge>
                      </td>
                      <td className="px-4 py-3 text-muted-foreground">
                        {course.terms}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </CardContent>
          </Card>
        </Reveal>

        <Reveal className="mt-8">
          <SectionHeading
            as="h3"
            title="Course Material — Université Laval"
            icon={Library}
            description="Complete material from courses previously taught at Université Laval — LaTeX Beamer slides, lecture notes, formal proofs, Stata labs, and exercise sets with solutions — openly available on GitHub."
          />
        </Reveal>
        <div className="mt-4 space-y-4">
          {ulavalCourses.map((course, i) => (
            <Reveal key={course.repoName} delay={i * 0.08}>
              <Card>
                <CardHeader>
                  <div className="flex flex-wrap items-center gap-2">
                    <Badge className="w-fit font-mono">{course.code}</Badge>
                    <Badge variant="secondary" className="w-fit">
                      {course.term}
                    </Badge>
                  </div>
                  <CardTitle className="text-lg leading-snug">
                    {course.title}
                  </CardTitle>
                  <CardDescription>{course.description}</CardDescription>
                </CardHeader>
                <CardContent className="flex flex-col gap-4">
                  {course.groups.map((group) => (
                    <div key={group.title}>
                      <p className="inline-flex items-center gap-2 text-sm font-medium">
                        <group.icon
                          className="h-4 w-4 text-primary"
                          aria-hidden="true"
                        />
                        {group.title}
                      </p>
                      {group.kind === "pills" ? (
                        <div className="mt-2 flex flex-wrap gap-1.5">
                          {group.links.map((link) => (
                            <a
                              key={link.file}
                              href={encodeURI(
                                `${GH_RAW}/${course.repoName}/main/${link.file}`,
                              )}
                              target="_blank"
                              rel="noopener noreferrer"
                              aria-label={`${course.code} — ${group.title} — ${link.label} (PDF)`}
                              className="inline-flex h-8 min-w-9 items-center justify-center rounded-full border border-border/70 bg-card/70 px-2 text-xs font-medium text-muted-foreground shadow-sm transition-all hover:-translate-y-px hover:border-primary/40 hover:bg-primary/10 hover:text-primary"
                            >
                              {link.label}
                            </a>
                          ))}
                        </div>
                      ) : (
                        <div className="mt-2 flex flex-wrap gap-1.5">
                          {group.links.map((link) => (
                            <PillLink
                              key={link.file}
                              href={encodeURI(
                                `${GH_RAW}/${course.repoName}/main/${link.file}`,
                              )}
                            >
                              {link.label}
                            </PillLink>
                          ))}
                        </div>
                      )}
                    </div>
                  ))}
                  <div>
                    <PillLink
                      href={`https://git.spboucher.ai/${course.repoName}`}
                      icon={Github}
                    >
                      Full course repository
                    </PillLink>
                  </div>
                </CardContent>
              </Card>
            </Reveal>
          ))}
        </div>
      </section>

      {/* Teaching assistant */}
      <section className="mt-12">
        <Reveal>
          <SectionHeading
            title="Teaching Assistant — Université Laval (2018–2021)"
            icon={Users}
          />
        </Reveal>
        <div className="mt-4 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          {taCourses.map((course, i) => (
            <Reveal key={`${course.code}-${course.title}`} delay={i * 0.06}>
              <Card className="h-full">
                <CardHeader>
                  <Badge variant="outline" className="w-fit font-mono">
                    {course.code}
                  </Badge>
                  <CardTitle className="text-base">{course.title}</CardTitle>
                </CardHeader>
              </Card>
            </Reveal>
          ))}
        </div>
      </section>
    </div>
  );
}
