import { createFileRoute, Link } from '@tanstack/react-router';
import Breadcrumbs from "@/components/Breadcrumbs";
import { useMemo, useState } from 'react';
import { ExternalLink, FlaskConical, Shield, CheckCircle, Award, ArrowRight, Search, Sparkles, Scale, HeartPulse, TrendingUp, Calendar, ArrowUpDown } from 'lucide-react';
import { motion } from 'framer-motion';
import RelatedLinks from '@/components/RelatedLinks';
import { getRelatedLinks } from '@/lib/relatedLinks';
import { labTests, labCategoryLabels } from '@/data/labTests';
import { labResultText } from '@/data/labTests';
import { getLabtests, type LabTests } from '@/lib/content.functions';
import heroLab from '@/assets/hero-labtests.jpg';
import { useT, useLang, headLang, localizePath, SITE_URL, type T } from '@/lib/i18n';
import { tr } from '@/lib/kennisbank-i18n';

const CATEGORY_ICON: Record<string, typeof Sparkles> = {
  'glp1-weight': Scale,
  'healing-tissue': HeartPulse,
  'growth-secretagogues': TrendingUp,
  'other-peptides': Sparkles,
};

function categoryDescription(t: T, c: string): string {
  switch (c) {
    case 'glp1-weight': return t('GLP-1 en amyline-analogen zoals retatrutide en tirzepatide', 'GLP-1 and amylin analogues such as retatrutide and tirzepatide');
    case 'healing-tissue': return t('Peptiden voor herstel-onderzoek zoals BPC-157 en TB-500', 'Peptides for recovery research such as BPC-157 and TB-500');
    case 'growth-secretagogues': return t('HGH en groeihormoon-secretagogen', 'HGH and growth hormone secretagogues');
    case 'other-peptides': return t('Overige research-peptiden en hormonen', 'Other research peptides and hormones');
    default: return c;
  }
}

/** Order used when the database has no categories yet. */
const CATEGORY_ORDER: string[] = ['glp1-weight', 'healing-tissue', 'growth-secretagogues', 'other-peptides'];

const MONTHS_NL = ['januari','februari','maart','april','mei','juni','juli','augustus','september','oktober','november','december'];
const MONTHS_EN = ['January','February','March','April','May','June','July','August','September','October','November','December'];
type SortMode = 'newest' | 'oldest' | 'category' | 'name';
function monthKey(d: string): string {
  const [, month, year] = d.split('/');
  return `${year}-${month}`;
}
function productBase(name: string): string {
  return name.replace(/\s*\(.*?\)\s*/g, '').replace(/\s+\d+(?:[.,]\d+)?\s*(mg|iu)\b.*$/i, '').trim();
}
function monthLabel(key: string, lang: 'nl' | 'en'): string {
  const [year, month] = key.split('-');
  const months = lang === 'en' ? MONTHS_EN : MONTHS_NL;
  return `${months[Number(month) - 1]} ${year}`;
}

function parseDate(d: string): number {
  const [day, month, year] = d.split('/').map(Number);
  return new Date(year, month - 1, day).getTime();
}

export const Route = createFileRoute('/labtesten')({
  // The reports are managed in the admin panel; the list in this codebase is the
  // fallback for an installation where nothing has been imported yet.
  loader: async () => ({ labtests: await getLabtests() }),
  head: (ctx) => {
    const lang = headLang(ctx);
    const path = localizePath('/labtesten', lang);
    const title = lang === 'en' ? 'Lab Tests — Independent Quality Control | Peptidewinkel' : 'Labtesten — Onafhankelijke Kwaliteitscontrole | Peptidewinkel';
    const description = lang === 'en'
      ? 'View our independent lab results from Janoshik. All products are tested for purity, dosage and safety for your peace of mind.'
      : 'Bekijk onze onafhankelijke labresultaten van Janoshik. Alle producten worden getest op zuiverheid, dosering en veiligheid voor jouw zekerheid.';
    const ogTitle = lang === 'en' ? 'Lab Tests — Peptidewinkel' : 'Labtesten — Peptidewinkel';
    const ogDescription = lang === 'en' ? 'Independent analyses of purity and dosage.' : 'Onafhankelijke analyses op zuiverheid en dosering.';
    return {
      meta: [
        { title },
        { name: 'description', content: description },
        { property: 'og:title', content: ogTitle },
        { property: 'og:description', content: ogDescription },
        { property: 'og:url', content: `${SITE_URL}${path}` },
        { property: 'og:type', content: 'website' },
      ],
      links: [{ rel: 'canonical', href: `${SITE_URL}${path}` }],
    };
  },
  component: LabTestsPage,
});

const fadeUp = {
  initial: { opacity: 0, y: 30 },
  whileInView: { opacity: 1, y: 0 },
  viewport: { once: true, margin: '-50px' },
};

function LabTestsPage() {
  const t = useT();
  const lang = useLang();
  const { labtests } = Route.useLoaderData();
  return (
    <div className="overflow-hidden">
      <Breadcrumbs items={[{ label: t('Labtesten', 'Lab tests') }]} />
      <section className="relative min-h-[400px] md:min-h-[500px] overflow-hidden">
        <img src={heroLab} alt={t('HPLC en LC-MS labtesten van Peptidewinkel research peptiden — zuiverheid en identiteit', 'HPLC and LC-MS lab tests of Peptidewinkel research peptides — purity and identity')} width={1920} height={864} loading="eager" decoding="async" className="absolute inset-0 w-full h-full object-cover" />
        <div className="absolute inset-0 bg-gradient-to-r from-black/80 via-black/60 to-black/40" />
        <div className="container relative z-10 text-center py-20 md:py-28">
          <motion.div {...fadeUp} transition={{ duration: 0.5 }}>
            <div className="w-16 h-16 mx-auto mb-5 rounded-2xl bg-white/15 backdrop-blur-sm flex items-center justify-center border border-white/20">
              <FlaskConical className="w-8 h-8 text-white" />
            </div>
          </motion.div>
          <motion.h1 {...fadeUp} transition={{ duration: 0.6, delay: 0.1 }} className="text-4xl md:text-6xl font-black text-white mb-5 tracking-tight">
            {t('Lab', 'Lab')}<span className="bg-gradient-to-r from-[#FFD777] to-white bg-clip-text text-transparent">{t('testen', ' tests')}</span>
          </motion.h1>
          <motion.p {...fadeUp} transition={{ duration: 0.6, delay: 0.2 }} className="text-white/70 max-w-2xl mx-auto text-lg leading-relaxed">
            {t('Alle producten worden geproduceerd door Alpha BioPharma en getest door het externe laboratorium Janoshik Analytical. Elk rapport hieronder linkt naar het origineel op janoshik.com.', 'All products are manufactured by Alpha BioPharma and tested by the independent laboratory Janoshik Analytical. Each report below links to the original on janoshik.com.')}
          </motion.p>
        </div>
      </section>

      <section className="relative -mt-8 z-20">
        <div className="container">
          <motion.div {...fadeUp} transition={{ duration: 0.6, delay: 0.3 }} className="bg-card border border-border rounded-2xl shadow-card p-6 grid grid-cols-1 md:grid-cols-3 gap-5">
            {[
              { icon: Shield, title: t('Extern lab', 'Independent lab'), desc: t('Getest door Janoshik Analytical — geen eigendom van de fabrikant of van Peptidewinkel.', 'Tested by Janoshik Analytical — not owned by the manufacturer or by Peptidewinkel.') },
              { icon: CheckCircle, title: t('Datum per rapport', 'Date per report'), desc: t('Bij elk resultaat staat de testdatum, zodat je ziet hoe recent het is.', 'Each result shows the test date, so you can see how recent it is.') },
              { icon: Award, title: t('Transparantie voorop', 'Transparency first'), desc: t('Elk testresultaat is publiek toegankelijk zodat je zelf kunt verifiëren wat je koopt.', 'Every test result is publicly accessible so you can verify yourself what you are buying.') },
            ].map((item) => (
              <div key={item.title} className="flex items-start gap-4">
                <div className="w-10 h-10 rounded-xl gradient-primary flex items-center justify-center shadow-sm shrink-0">
                  <item.icon className="w-5 h-5 text-white" />
                </div>
                <div>
                  <h3 className="font-bold text-sm mb-0.5">{item.title}</h3>
                  <p className="text-xs text-muted-foreground leading-relaxed">{item.desc}</p>
                </div>
              </div>
            ))}
          </motion.div>
        </div>
      </section>

      <section className="container py-16 max-w-3xl">
        <motion.div {...fadeUp} transition={{ duration: 0.5 }}>
          <p className="text-primary text-sm font-semibold uppercase tracking-wider mb-2">{t('Onze aanpak', 'Our approach')}</p>
          <h2 className="text-2xl font-black mb-5">{t('Waarom wij testen', 'Why we test')}</h2>
          <div className="space-y-4 text-muted-foreground leading-relaxed text-sm">
            <p><strong className="text-foreground">{t('Wie produceert:', 'Who manufactures:')}</strong> {t('Alpha BioPharma, onze enige fabrikant. Peptidewinkel produceert zelf niet; wij kopen in, controleren de documentatie en verzenden.', 'Alpha BioPharma, our sole manufacturer. Peptidewinkel does not manufacture itself; we purchase, verify the documentation and ship.')}</p>
            <p><strong className="text-foreground">{t('Wie test:', 'Who tests:')}</strong> {t('Janoshik Analytical, een extern analyselaboratorium. De opdracht en de monsters komen van Alpha BioPharma.', 'Janoshik Analytical, an independent analytical laboratory. The commission and the samples come from Alpha BioPharma.')}</p>
            <p><strong className="text-foreground">{t('Wat "onafhankelijk" betekent:', 'What "independent" means:')}</strong> {t('het lab is geen eigendom van de fabrikant of van Peptidewinkel en publiceert het rapport zelf. Je kunt elk rapport op janoshik.com controleren via de link en de unieke code in de URL.', 'the lab is not owned by the manufacturer or by Peptidewinkel and publishes the report itself. You can verify every report on janoshik.com via the link and the unique code in the URL.')}</p>
            <p><strong className="text-foreground">{t('Methode:', 'Method:')}</strong> {t('Janoshik meet zuiverheid met HPLC en, waar vermeld, het gehalte in mg of IU per flacon. De exacte methode en het monster staan in het originele rapport.', 'Janoshik measures purity with HPLC and, where stated, the content in mg or IU per vial. The exact method and sample are in the original report.')}</p>
            <p><strong className="text-foreground">{t('Per resultaat tonen we:', 'Per result we show:')}</strong> {t('product, batch (als die in het rapport staat), testdatum, gemeten resultaat en de link naar het rapport. Niet elk product en niet elke batch is getest; staat een product hier niet, dan is er (nog) geen rapport.', 'product, batch (if stated in the report), test date, measured result and the link to the report. Not every product and not every batch has been tested; if a product does not appear here, no report exists (yet).')}</p>
          </div>
        </motion.div>
      </section>

      <LabResultsSection data={labtests} />


      <section className="container py-20">
        <motion.div {...fadeUp} transition={{ duration: 0.6 }} className="gradient-primary rounded-3xl p-10 md:p-16 text-center relative overflow-hidden">
          <div className="absolute -top-20 -right-20 w-64 h-64 bg-white/10 rounded-full blur-2xl" />
          <div className="absolute -bottom-16 -left-16 w-48 h-48 bg-white/5 rounded-full blur-2xl" />
          <div className="relative z-10">
            <h2 className="text-3xl md:text-4xl font-black text-white mb-4">{t('Overtuigd van onze kwaliteit?', 'Convinced of our quality?')}</h2>
            <p className="text-white/70 mb-8 max-w-md mx-auto text-lg">{t('Bekijk ons uitgebreide assortiment van lab-geteste producten.', 'Browse our extensive range of lab-tested products.')}</p>
            <div className="flex flex-wrap gap-4 justify-center">
              <Link to="/shop" className="group inline-flex items-center gap-2.5 bg-white text-foreground font-bold px-8 py-4 rounded-xl hover:shadow-xl transition-all duration-300 text-sm uppercase tracking-wide">
                {t('Bekijk producten', 'View products')} <ArrowRight className="w-4 h-4 group-hover:translate-x-1 transition-transform" />
              </Link>
              <Link to="/contact-us" className="inline-flex items-center gap-2 border border-white/25 text-white font-semibold px-8 py-4 rounded-xl hover:bg-white/10 transition-all duration-300 text-sm uppercase tracking-wide">
                {t('Vragen? Neem contact op', 'Questions? Get in touch')}
              </Link>
            </div>
          </div>
        </motion.div>
      </section>

      <RelatedLinks title={t('Meer informatie & tools', 'More information & tools')} subtitle={t('Verdiep je verder in onze producten, kennis en hulpmiddelen.', 'Learn more about our products, knowledge and tools.')} links={getRelatedLinks('labtesten', lang)} />
    </div>
  );
}

function LabResultsSection({ data }: { data: LabTests | null }) {
  const t = useT();
  const lang = useLang();

  // Reports, labels and categories come from the admin panel when it has them.
  const reports = data?.tests.length ? data.tests : labTests;
  const categoryLabels: Record<string, { nl: string; en: string }> = data?.categories.length
    ? Object.fromEntries(data.categories.map((c) => [c.slug, c.name]))
    : labCategoryLabels;
  const categoryOrder = data?.categories.length ? data.categories.map((c) => c.slug) : CATEGORY_ORDER;

  const labelFor = (slug: string): string => {
    const label = categoryLabels[slug];
    return label ? tr(label, lang) : slug;
  };

  const descriptionFor = (slug: string): string => {
    const fromPanel = data?.categories.find((c) => c.slug === slug)?.description;
    const text = fromPanel && (fromPanel.nl || fromPanel.en) ? tr(fromPanel, lang) : '';
    return text !== '' ? text : categoryDescription(t, slug);
  };

  const [query, setQuery] = useState('');
  const [activeCategory, setActiveCategory] = useState<string>('all');
  const [month, setMonth] = useState<string>('all');
  const [sort, setSort] = useState<SortMode>('newest');
  const [product, setProduct] = useState<string>('all');
  const productOptions = useMemo(
    () => Array.from(new Set(reports.map((t2) => productBase(t2.product)))).sort((a, b) => a.localeCompare(b, 'nl')),
    [reports],
  );

  const monthOptions = useMemo(
    () => Array.from(new Set(reports.map((t2) => monthKey(t2.date)))).sort().reverse(),
    [reports],
  );

  const categoryCounts = useMemo(() => {
    const counts: Record<string, number> = { all: reports.length };
    for (const c of categoryOrder) counts[c] = reports.filter((t2) => t2.category === c).length;
    return counts;
  }, [reports, categoryOrder]);

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    return reports
      .filter((t2) => (activeCategory === 'all' ? true : t2.category === activeCategory))
      .filter((t2) => (!q ? true : t2.product.toLowerCase().includes(q) || t2.result.toLowerCase().includes(q) || t2.date.includes(q)))
      .filter((t2) => (month === 'all' ? true : monthKey(t2.date) === month))
      .filter((t2) => (product === 'all' ? true : productBase(t2.product) === product))
      .sort((a, b) => {
        if (sort === 'oldest') return parseDate(a.date) - parseDate(b.date);
        if (sort === 'name') return a.product.localeCompare(b.product, 'nl');
        return parseDate(b.date) - parseDate(a.date);
      });
  }, [reports, query, activeCategory, month, sort, product]);

  const grouped = useMemo(() => {
    const map = new Map<string, typeof filtered>();
    for (const c of categoryOrder) map.set(c, []);
    for (const t2 of filtered) {
      const bucket = map.get(t2.category ?? '');
      if (bucket) bucket.push(t2);
    }
    return map;
  }, [filtered, categoryOrder]);

  return (
    <section className="bg-surface/50">
      <div className="container py-16 max-w-5xl">
        <div className="text-center mb-8">
          <p className="text-primary text-sm font-semibold uppercase tracking-wider mb-2">{t('Resultaten', 'Results')}</p>
          <h2 className="text-2xl md:text-3xl font-black">{reports.length} {t('geteste producten', 'tested products')}</h2>
          <p className="text-sm text-muted-foreground mt-2">{t('Zoek op productnaam of datum, filter op product of maand, of rangschik per categorie.', 'Search by product name or date, filter by product or month, or sort by category.')}</p>
        </div>

        <div className="bg-card border border-border rounded-2xl p-4 md:p-5 mb-8 shadow-card">
          <div className="relative mb-4">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
            <input
              type="text"
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              placeholder={t('Zoek bv. retatrutide, hgh of 09/2026...', 'Search e.g. retatrutide, hgh or 09/2026...')}
              className="w-full pl-10 pr-4 py-2.5 text-sm bg-surface border border-border rounded-xl focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary transition"
            />
          </div>
          <div className="grid sm:grid-cols-3 gap-3 mb-4">
            <label className="relative block">
              <span className="sr-only">{t('Filter op product', 'Filter by product')}</span>
              <FlaskConical className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground pointer-events-none" />
              <select value={product} onChange={(e) => setProduct(e.target.value)} className="w-full pl-10 pr-4 py-2.5 text-sm bg-surface border border-border rounded-xl focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary">
                <option value="all">{t('Alle producten', 'All products')}</option>
                {productOptions.map((p) => <option key={p} value={p}>{p}</option>)}
              </select>
            </label>
            <label className="relative block">
              <span className="sr-only">{t('Filter op testdatum', 'Filter by test date')}</span>
              <Calendar className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground pointer-events-none" />
              <select value={month} onChange={(e) => setMonth(e.target.value)} className="w-full pl-10 pr-4 py-2.5 text-sm bg-surface border border-border rounded-xl focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary">
                <option value="all">{t('Alle testdatums', 'All test dates')}</option>
                {monthOptions.map((m) => <option key={m} value={m}>{monthLabel(m, lang)}</option>)}
              </select>
            </label>
            <label className="relative block">
              <span className="sr-only">{t('Rangschikken', 'Sort')}</span>
              <ArrowUpDown className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground pointer-events-none" />
              <select value={sort} onChange={(e) => setSort(e.target.value as SortMode)} className="w-full pl-10 pr-4 py-2.5 text-sm bg-surface border border-border rounded-xl focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary">
                <option value="newest">{t('Nieuwste eerst', 'Newest first')}</option>
                <option value="oldest">{t('Oudste eerst', 'Oldest first')}</option>
                <option value="category">{t('Per categorie', 'By category')}</option>
                <option value="name">{t('Naam (A–Z)', 'Name (A–Z)')}</option>
              </select>
            </label>
          </div>
          <div className="flex flex-wrap gap-2">
            <FilterChip active={activeCategory === 'all'} onClick={() => setActiveCategory('all')} label={t('Alle', 'All')} count={categoryCounts.all} />
            {categoryOrder.map((c) => {
              const Icon = CATEGORY_ICON[c] ?? Sparkles;
              return (
                <FilterChip
                  key={c}
                  active={activeCategory === c}
                  onClick={() => setActiveCategory(c)}
                  label={labelFor(c)}
                  count={categoryCounts[c]}
                  icon={<Icon className="w-3.5 h-3.5" />}
                />
              );
            })}
          </div>
        </div>

        {filtered.length === 0 ? (
          <div className="text-center py-12 text-sm text-muted-foreground bg-card border border-border rounded-2xl">
            {t('Geen resultaten gevonden voor je zoekopdracht.', 'No results found for your search.')}
          </div>
        ) : (
          <div className="space-y-10">
            {(sort === 'category' ? categoryOrder : [null]).map((cat) => {
              const items = cat ? grouped.get(cat) ?? [] : filtered;
              if (items.length === 0) return null;
              const Icon = cat ? CATEGORY_ICON[cat] ?? Sparkles : Sparkles;
              return (
                <div key={cat ?? 'all'}>
                  {cat && <div className="flex items-center gap-3 mb-4">
                    <div className="w-9 h-9 rounded-xl gradient-primary flex items-center justify-center shadow-sm">
                      <Icon className="w-4 h-4 text-white" />
                    </div>
                    <div>
                      <h3 className="font-bold text-base">{labelFor(cat)} <span className="text-muted-foreground font-normal text-xs">({items.length})</span></h3>
                      <p className="text-xs text-muted-foreground">{descriptionFor(cat)}</p>
                    </div>
                  </div>}
                  <div className="space-y-3">
                    {items.map((test, i) => (
                      <motion.div
                        key={test.product + test.date}
                        initial={{ opacity: 0, y: 10 }}
                        whileInView={{ opacity: 1, y: 0 }}
                        viewport={{ once: true, margin: '-30px' }}
                        transition={{ duration: 0.3, delay: Math.min(i * 0.02, 0.2) }}
                        className="bg-card border border-border rounded-2xl p-5 flex flex-col sm:flex-row sm:items-center justify-between gap-3 hover:border-primary/50 hover:shadow-card-hover transition-all duration-300 group"
                      >
                        <div className="flex items-start gap-3">
                          <div className="w-10 h-10 rounded-xl bg-primary/10 flex items-center justify-center shrink-0 mt-0.5">
                            <FlaskConical className="w-4 h-4 text-primary" />
                          </div>
                          <div>
                            <h4 className="font-semibold text-sm group-hover:text-primary transition-colors">{test.product}</h4>
                            <div className="flex flex-wrap items-center gap-2 mt-1.5">
                              <span className="inline-flex items-center gap-1 text-[11px] text-muted-foreground bg-surface rounded-full px-2.5 py-0.5"><Calendar className="w-3 h-3" aria-hidden="true" /> {test.date}</span>
                              <span className="inline-flex items-center gap-1 text-[11px] font-semibold text-primary bg-primary/10 rounded-full px-2.5 py-0.5"><CheckCircle className="w-3 h-3" aria-hidden="true" /> {labResultText(test.result, lang)}</span>
                            </div>
                          </div>
                        </div>
                        {test.url !== '#' ? (
                          <a href={test.url} target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-1.5 text-xs font-semibold text-primary hover:underline shrink-0 bg-primary/5 hover:bg-primary/10 px-4 py-2 rounded-lg transition-colors">
                            {t('Bekijk rapport', 'View report')} <ExternalLink className="w-3.5 h-3.5" />
                          </a>
                        ) : (
                          <span className="inline-flex items-center gap-1.5 text-xs text-muted-foreground shrink-0 bg-surface px-4 py-2 rounded-lg">
                            <CheckCircle className="w-3.5 h-3.5" /> {t('Beschikbaar', 'Available')}
                          </span>
                        )}
                      </motion.div>
                    ))}
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>
    </section>
  );
}

function FilterChip({ active, onClick, label, count, icon }: { active: boolean; onClick: () => void; label: string; count: number; icon?: React.ReactNode }) {
  return (
    <button
      type="button"
      onClick={onClick}
      className={`inline-flex items-center gap-1.5 text-xs font-semibold px-3.5 py-1.5 rounded-full border transition ${
        active
          ? 'bg-primary text-white border-primary shadow-sm'
          : 'bg-surface text-foreground border-border hover:border-primary/50 hover:text-primary'
      }`}
    >
      {icon}
      {label}
      <span className={`text-[10px] font-bold px-1.5 py-0.5 rounded-full ${active ? 'bg-white/20' : 'bg-background'}`}>{count}</span>
    </button>
  );
}
