import React, { useState } from 'react';
import type { Locale, LangCode } from './i18n';
import type { NewsCategory } from './Subscribe';

type Bilingual = Record<LangCode, string>;

export interface NewsItem {
    slug: string;
    category: NewsCategory | null;
    title: Bilingual;
    excerpt: Bilingual;
    body?: Bilingual;
    cover: string | null;
    published_at: string | null;
    url: string;
}

function formatDate(iso: string | null, lang: LangCode): string {
    if (!iso) return '';
    return new Date(iso).toLocaleDateString(lang === 'zh' ? 'zh-HK' : 'en-GB', {
        year: 'numeric',
        month: 'short',
        day: 'numeric',
    });
}

function NewsCard({ post, lang, t, delay }: { post: NewsItem; lang: LangCode; t: Locale; delay: number }) {
    return (
        <a className="news-card" href={post.url} data-delay={delay}>
            <div className="news-cover">
                {post.cover ? (
                    <img src={post.cover} alt="" loading="lazy" draggable={false} />
                ) : (
                    <img className="news-cover-owl" src="/assets/owl.png" alt="" loading="lazy" draggable={false} />
                )}
            </div>
            <div className="news-card-body">
                <div className="news-meta">
                    {post.category && <span className="news-cat">{post.category.name[lang]}</span>}
                    <time className="news-date" dateTime={post.published_at ?? undefined}>
                        {formatDate(post.published_at, lang)}
                    </time>
                </div>
                <h3>{post.title[lang]}</h3>
                {post.excerpt[lang] && <p>{post.excerpt[lang]}</p>}
                <span className="news-link">
                    {t.news.readMore} <span className="arrow">→</span>
                </span>
            </div>
        </a>
    );
}

function initialFilter(): string | null {
    return new URLSearchParams(window.location.search).get('category');
}

export function NewsIndex({ t, lang, posts, categories }: { t: Locale; lang: LangCode; posts: NewsItem[]; categories: NewsCategory[] }) {
    const [filter, setFilter] = useState<string | null>(initialFilter);
    // Only offer filters for categories that actually have posts.
    const used = categories.filter((c) => posts.some((p) => p.category?.slug === c.slug));
    const shown = filter ? posts.filter((p) => p.category?.slug === filter) : posts;

    const choose = (slug: string | null) => {
        setFilter(slug);
        const url = new URL(window.location.href);
        if (slug) url.searchParams.set('category', slug);
        else url.searchParams.delete('category');
        window.history.replaceState(null, '', url);
    };

    return (
        <section className="news-page">
            <div className="wrap">
                <div className="section-head">
                    <div className="lead">
                        <span className="kicker reveal">{t.news.kicker}</span>
                        <h1 className="section-title reveal d1">{t.news.title}</h1>
                    </div>
                    <p className="reveal d2">{t.news.sub}</p>
                </div>
                {used.length > 0 && (
                    <div className="news-filters" role="tablist">
                        <button role="tab" aria-selected={!filter} className={!filter ? 'on' : ''} onClick={() => choose(null)}>
                            {t.news.all}
                        </button>
                        {used.map((c) => (
                            <button
                                key={c.slug}
                                role="tab"
                                aria-selected={filter === c.slug}
                                className={filter === c.slug ? 'on' : ''}
                                onClick={() => choose(c.slug)}
                            >
                                {c.name[lang]}
                            </button>
                        ))}
                    </div>
                )}
                {shown.length === 0 ? (
                    <p className="news-empty reveal in">{t.news.empty}</p>
                ) : (
                    <div className="news-grid">
                        {shown.map((p, i) => (
                            <NewsCard key={p.slug} post={p} lang={lang} t={t} delay={(i % 3) + 1} />
                        ))}
                    </div>
                )}
            </div>
        </section>
    );
}

export function NewsPost({ t, lang, post, more }: { t: Locale; lang: LangCode; post: NewsItem; more: NewsItem[] }) {
    return (
        <article className="news-page">
            <div className="wrap news-article">
                <a className="news-back" href="/news">
                    ← {t.news.back}
                </a>
                <div className="news-meta">
                    {post.category && (
                        <a className="news-cat" href={'/news?category=' + post.category.slug}>
                            {post.category.name[lang]}
                        </a>
                    )}
                    <time className="news-date" dateTime={post.published_at ?? undefined}>
                        {formatDate(post.published_at, lang)}
                    </time>
                </div>
                <h1 className="news-title">{post.title[lang]}</h1>
                {post.excerpt[lang] && <p className="news-lead">{post.excerpt[lang]}</p>}
                {post.cover && <img className="news-hero-img" src={post.cover} alt="" draggable={false} />}
                {/* Body HTML is authored by admins in the console's rich-text editor. */}
                <div className="news-body" dangerouslySetInnerHTML={{ __html: post.body?.[lang] ?? '' }} />
            </div>
            {more.length > 0 && (
                <div className="wrap news-more">
                    <h2>{t.news.more}</h2>
                    <div className="news-grid">
                        {more.map((p, i) => (
                            <NewsCard key={p.slug} post={p} lang={lang} t={t} delay={(i % 3) + 1} />
                        ))}
                    </div>
                </div>
            )}
        </article>
    );
}
