import { createFileRoute, Link } from '@tanstack/react-router'
import { computeDuration, formatDate, CONTACT_EMAIL } from '#/data/portfolio'
import type { TExperience, TEducation, TSkill } from '#/types/strapi'
import {
  fetchExperiences,
  fetchEducations,
  fetchProfile,
} from '#/data/loaders/portfolio'

export const Route = createFileRoute('/')({
  loader: async () => {
    const [experiences, educations, profile] = await Promise.all([
      fetchExperiences(),
      fetchEducations(),
      fetchProfile(),
    ])
    return { experiences, educations, profile }
  },
  errorComponent: StrapiErrorPage,
  component: HomePage,
})

// ── Error page ────────────────────────────────────────────────────────────

function StrapiErrorPage() {
  return (
    <div className="page-wrap flex min-h-[60vh] flex-col items-center justify-center gap-4 text-center">
      <p className="island-kicker">Service Unavailable</p>
      <h1 className="display-title text-4xl">We'll be right back</h1>
      <p
        style={{ color: 'var(--sea-ink-soft)' }}
        className="max-w-md text-base"
      >
        The portfolio data is temporarily unavailable. Please check back in a
        few minutes.
      </p>
    </div>
  )
}

// ── Shared UI primitives ──────────────────────────────────────────────────

type ButtonVariant = 'primary' | 'ghost'

const BUTTON_VARIANT_CLASSES: Record<ButtonVariant, string> = {
  primary:
    'rounded-full border border-[rgba(50,143,151,0.35)] bg-[rgba(79,184,178,0.15)] px-5 py-2.5 text-sm font-semibold text-[var(--lagoon-deep)] no-underline transition hover:-translate-y-0.5 hover:bg-[rgba(79,184,178,0.26)]',
  ghost:
    'rounded-full border border-[var(--line)] bg-[var(--surface-strong)] px-5 py-2.5 text-sm font-semibold text-[var(--sea-ink)] no-underline transition hover:-translate-y-0.5 hover:border-[rgba(23,58,64,0.3)]',
}

function ButtonLink({
  href,
  variant,
  children,
}: {
  readonly href: string
  readonly variant: ButtonVariant
  readonly children: React.ReactNode
}) {
  return (
    <a href={href} className={BUTTON_VARIANT_CLASSES[variant]}>
      {children}
    </a>
  )
}

function TechChip({ label }: { readonly label: string }) {
  return (
    <span className="inline-block rounded-full border border-[var(--chip-line)] bg-[var(--chip-bg)] px-2.5 py-0.5 text-xs font-semibold text-[var(--lagoon-deep)]">
      {label}
    </span>
  )
}

// ── Section heading ───────────────────────────────────────────────────────

function SectionHeading({
  kicker,
  title,
  id,
}: {
  readonly kicker: string
  readonly title: string
  readonly id: string
}) {
  return (
    <div id={id} className="mb-8 scroll-mt-20">
      <p className="island-kicker mb-2">{kicker}</p>
      <h2 className="display-title m-0 text-2xl font-bold tracking-tight text-[var(--sea-ink)] sm:text-3xl">
        {title}
      </h2>
    </div>
  )
}

// ── Experience card ───────────────────────────────────────────────────────

const EMPLOYMENT_TYPE_LABEL: Record<'full-time' | 'part-time', string> = {
  'full-time': 'Full-time',
  'part-time': 'Part-time',
}

function ExperienceCard({
  exp,
  index,
}: {
  readonly exp: TExperience
  readonly index: number
}) {
  const startIso = exp.startDate.slice(0, 7)
  const endIso = exp.endDate?.slice(0, 7)
  const duration = computeDuration(startIso, endIso)
  const startLabel = formatDate(startIso)
  const endLabel = endIso ? formatDate(endIso) : 'Present'

  return (
    <div
      className="rise-in relative flex gap-4 sm:gap-6"
      style={{ animationDelay: `${index * 80}ms` }}
    >
      {/* Timeline dot + connector line */}
      <div className="flex flex-col items-center">
        <div className="mt-1.5 h-3.5 w-3.5 flex-shrink-0 rounded-full border-2 border-[var(--lagoon)] bg-[var(--lagoon-deep)] shadow-[0_0_0_4px_rgba(79,184,178,0.18)]" />
        <div className="mt-1.5 w-0.5 flex-1 bg-[linear-gradient(to_bottom,var(--lagoon),transparent)]" />
      </div>

      {/* Card */}
      <div className="island-shell feature-card mb-6 flex-1 rounded-2xl p-5 pb-6">
        <div className="mb-2 flex flex-wrap items-start justify-between gap-2">
          <Link
            to="/experience/$slug"
            params={{ slug: exp.slug }}
            className="group min-w-0"
          >
            <p className="island-kicker mb-0.5">{exp.company}</p>
            <h3 className="m-0 text-base font-bold text-[var(--sea-ink)] transition group-hover:text-[var(--lagoon-deep)]">
              {exp.role}
            </h3>
          </Link>
          {exp.type != null && (
            <span className="mt-0.5 flex-shrink-0 rounded-full border border-[var(--chip-line)] bg-[var(--chip-bg)] px-2.5 py-0.5 text-xs font-semibold text-[var(--sea-ink-soft)]">
              {EMPLOYMENT_TYPE_LABEL[exp.type]}
            </span>
          )}
        </div>

        <div className="mb-3 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-[var(--sea-ink-soft)]">
          <span>
            {startLabel} — {endLabel}
          </span>
          <span className="h-1 w-1 rounded-full bg-[var(--lagoon)]" />
          <span>{duration}</span>
        </div>

        {(exp.objectives ?? []).length > 0 && (
          <ul className="mb-3 ml-0 list-none space-y-1.5 p-0">
            {(exp.objectives ?? []).map((obj) => (
              <li
                key={obj.id}
                className="flex gap-2 text-sm text-[var(--sea-ink-soft)]"
              >
                <span className="mt-1.5 h-1.5 w-1.5 flex-shrink-0 rounded-full bg-[var(--lagoon)]" />
                {obj.description}
              </li>
            ))}
          </ul>
        )}

        {(exp.technologies ?? []).length > 0 && (
          <div className="flex flex-wrap gap-1.5">
            {(exp.technologies ?? []).map((tech) => (
              <TechChip key={tech.id} label={tech.name} />
            ))}
          </div>
        )}
      </div>
    </div>
  )
}

// ── Education card ────────────────────────────────────────────────────────

function EducationCard({ edu }: { readonly edu: TEducation }) {
  const startYear = new Date(edu.startDate).getFullYear()
  const endYear = edu.endDate ? new Date(edu.endDate).getFullYear() : null

  return (
    <div className="island-shell feature-card rise-in rounded-2xl p-6">
      <p className="island-kicker mb-2">{edu.institution}</p>
      <h3 className="mb-2 text-base font-bold leading-snug text-[var(--sea-ink)]">
        {edu.degree}
        {edu.fieldOfStudy ? ` ${edu.fieldOfStudy}` : ''}
      </h3>
      <div className="flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-[var(--sea-ink-soft)]">
        <span>
          {startYear} – {endYear ?? 'Present'}
        </span>
        {edu.grade != null && (
          <>
            <span className="h-1 w-1 rounded-full bg-[var(--lagoon)]" />
            <span className="font-semibold text-[var(--lagoon-deep)]">
              Grade: {edu.grade}
            </span>
          </>
        )}
      </div>
    </div>
  )
}

// ── Skill group card ──────────────────────────────────────────────────────

function SkillGroupCard({
  category,
  skills,
}: {
  readonly category: string
  readonly skills: readonly TSkill[]
}) {
  return (
    <div className="island-shell feature-card rise-in rounded-2xl p-5">
      <p className="island-kicker mb-3">{category}</p>
      <div className="flex flex-wrap gap-2">
        {skills.map((skill) => (
          <TechChip key={skill.id} label={skill.name} />
        ))}
      </div>
    </div>
  )
}

// ── Page ──────────────────────────────────────────────────────────────────

function HomePage() {
  const { experiences, educations, profile } = Route.useLoaderData()

  const skillsByGroup = profile.skills.reduce<Record<string, TSkill[]>>(
    (acc, skill) => {
      const key = skill.group
      acc[key] = [...(acc[key] ?? []), skill]
      return acc
    },
    {},
  )

  return (
    <main className="page-wrap px-4 pb-16 pt-10">
      {/* ── Hero ──────────────────────────────────────────── */}
      <section className="island-shell rise-in relative overflow-hidden rounded-[2rem] px-6 py-12 sm:px-12 sm:py-16">
        <div className="pointer-events-none absolute -left-24 -top-24 h-72 w-72 rounded-full bg-[radial-gradient(circle,rgba(79,184,178,0.3),transparent_65%)]" />
        <div className="pointer-events-none absolute -bottom-24 -right-24 h-72 w-72 rounded-full bg-[radial-gradient(circle,rgba(47,106,74,0.18),transparent_65%)]" />
        <div className="pointer-events-none absolute right-1/3 top-0 h-48 w-48 rounded-full bg-[radial-gradient(circle,rgba(79,184,178,0.12),transparent_70%)]" />

        <p className="island-kicker mb-4">
          Software Engineer · Copenhagen, Denmark
        </p>
        <h1 className="display-title mb-4 max-w-2xl text-5xl font-bold leading-[1.02] tracking-tight text-[var(--sea-ink)] sm:text-7xl">
          Hi, I'm {profile.firstname}.
        </h1>
        <p className="mb-8 max-w-xl text-base leading-relaxed text-[var(--sea-ink-soft)] sm:text-lg">
          {profile.about ??
            'Crafting robust full-stack solutions with a passion for clean architecture, great developer experience, and shipping products people love.'}
        </p>

        <div className="flex flex-wrap gap-3">
          <ButtonLink href="#experience" variant="primary">
            View Experience
          </ButtonLink>
          <ButtonLink href={`mailto:${CONTACT_EMAIL}`} variant="ghost">
            Get in Touch
          </ButtonLink>
        </div>
      </section>

      {/* ── Experience ────────────────────────────────────── */}
      <section className="mt-16">
        <SectionHeading
          kicker="Career"
          title="Work Experience"
          id="experience"
        />
        <div>
          {experiences.map((exp, i) => (
            <ExperienceCard key={exp.id} exp={exp} index={i} />
          ))}
        </div>
      </section>

      {/* ── Education ─────────────────────────────────────── */}
      <section className="mt-16">
        <SectionHeading kicker="Background" title="Education" id="education" />
        <div className="grid gap-4 sm:grid-cols-2">
          {educations.map((edu) => (
            <EducationCard key={edu.id} edu={edu} />
          ))}
        </div>
      </section>

      {/* ── Skills ────────────────────────────────────────── */}
      <section className="mt-16">
        <SectionHeading
          kicker="Toolkit"
          title="Skills & Technologies"
          id="skills"
        />
        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          {Object.entries(skillsByGroup).map(([groupKey, skills]) => (
            <SkillGroupCard
              key={groupKey}
              category={groupKey}
              skills={skills}
            />
          ))}
        </div>
      </section>

      {/* ── Contact CTA ───────────────────────────────────── */}
      <section id="contact" className="mt-16 scroll-mt-20">
        <div className="island-shell rise-in relative overflow-hidden rounded-[2rem] px-6 py-12 text-center sm:px-12">
          <div className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_at_center,rgba(79,184,178,0.1),transparent_70%)]" />
          <p className="island-kicker mb-3">Let's connect</p>
          <h2 className="display-title mb-4 text-2xl font-bold text-[var(--sea-ink)] sm:text-4xl">
            Open to new opportunities
          </h2>
          <p className="mx-auto mb-8 max-w-md text-[var(--sea-ink-soft)]">
            I'm always interested in hearing about exciting engineering
            challenges and the teams building them.
          </p>
          <ButtonLink href={`mailto:${CONTACT_EMAIL}`} variant="primary">
            Say hello →
          </ButtonLink>
        </div>
      </section>
    </main>
  )
}
