<script setup lang="ts">
import ArticleCard from './ArticleCard.vue';

interface Story {
    source: string;
    time: string | null;
    headline: string;
    deck?: string | null;
    image?: string | null;
    link: string;
}

interface Category {
    label: string;
    hero: boolean;
    items: Story[];
}

const props = withDefaults(
    defineProps<{
        category: Category;
        index?: number;
    }>(),
    {
        index: 0,
    },
);

type Variant = 'hero' | 'banner' | 'feature' | 'standard' | 'brief';

interface Slot {
    variant: Variant;
    span: number;
}

// A hero category always gets the same big-lead treatment. Non-hero
// categories rotate through a few distinct shapes by position, so
// adjacent sections don't all read as the same grid: one leans on two
// medium photos, one leans on a single wide banner, one is mostly
// small thumbnails with more falling through to the text-only list.
const nonHeroLayouts: Slot[][] = [
    // gallery: two medium features side by side, three small below
    [
        { variant: 'feature', span: 3 },
        { variant: 'feature', span: 3 },
        { variant: 'standard', span: 2 },
        { variant: 'standard', span: 2 },
        { variant: 'standard', span: 2 },
    ],
    // lead: one wide banner feature, three small below
    [
        { variant: 'banner', span: 6 },
        { variant: 'standard', span: 2 },
        { variant: 'standard', span: 2 },
        { variant: 'standard', span: 2 },
    ],
    // digest: small thumbnails only, text-heavy section
    [
        { variant: 'standard', span: 2 },
        { variant: 'standard', span: 2 },
        { variant: 'standard', span: 2 },
    ],
];

const heroLayout: Slot[] = [
    { variant: 'hero', span: 6 },
    { variant: 'feature', span: 3 },
    { variant: 'feature', span: 3 },
    { variant: 'standard', span: 2 },
    { variant: 'standard', span: 2 },
    { variant: 'standard', span: 2 },
];

const slots = props.category.hero
    ? heroLayout
    : nonHeroLayouts[props.index % nonHeroLayouts.length];

const gridItems = props.category.items
    .slice(0, slots.length)
    .map((story, i) => ({
        story,
        variant: slots[i].variant,
        span: slots[i].span,
    }));

const briefItems = props.category.items.slice(slots.length);
</script>

<template>
    <section class="category">
        <div class="category-header">
            <span class="category-label">{{ category.label }}</span>
            <a href="#" class="category-more">More</a>
        </div>

        <div v-if="category.items.length === 0" class="category-empty">
            No stories yet. Feeds may still be fetching.
        </div>

        <template v-else>
            <div class="section-grid">
                <ArticleCard
                    v-for="entry in gridItems"
                    :key="entry.story.link"
                    :story="entry.story"
                    :variant="entry.variant"
                    :style="{ gridColumn: `span ${entry.span}` }"
                />
            </div>

            <div v-if="briefItems.length" class="brief-section">
                <div class="brief-label">In brief</div>
                <div class="brief-grid">
                    <ArticleCard
                        v-for="item in briefItems"
                        :key="item.link"
                        :story="item"
                        variant="brief"
                    />
                </div>
            </div>
        </template>
    </section>
</template>

<style scoped lang="sass">
.category
    border-bottom: 1px solid #E8E8E8
    padding: 1.5rem 0

    &:last-child
        border-bottom: none

.category-header
    display: flex
    align-items: baseline
    justify-content: space-between
    margin-bottom: 1rem

.category-label
    font-size: 10px
    font-weight: 600
    letter-spacing: 2px
    text-transform: uppercase
    color: #111

.category-more
    font-size: 12px
    color: #C0392B
    text-decoration: none

    &:hover
        text-decoration: underline

.category-empty
    font-size: 12px
    color: #999
    padding: 1rem 0

.section-grid
    display: grid
    grid-template-columns: repeat(6, 1fr)
    gap: 1px
    background: #E8E8E8

.brief-section
    margin-top: 4px

.brief-label
    font-size: 10px
    font-weight: 600
    letter-spacing: 1px
    text-transform: uppercase
    color: #999
    padding: 0.9rem 0 0.3rem

.brief-grid
    display: grid
    grid-template-columns: repeat(2, 1fr)
    column-gap: 2rem
</style>
