'use client';

import {VStack} from '@astryxdesign/core/Layout';
import {Banner} from '@astryxdesign/core/Banner';
import {PanelCard} from '@/shared/components/patterns/PanelCard';
import {SkeletonRows} from '@/shared/components/patterns/LoadingState';
import {EmptyPanel} from '@/shared/components/patterns/EmptyPanel';
import {formatCompact, formatLyt} from '@/shared/utils/format';
import {daysUntil} from '@/features/lyts/services/lytsService';
import type {Reward} from '@/features/lyts/types/reward';
import type {Resource} from '@/shared/hooks/useResource';

/**
 * Rewards lapsing within a fortnight.
 *
 * This panel exists because expiry is the one thing on this page with a
 * deadline. Everything else can be read whenever; an offer expiring in two
 * days either gets extended today or it doesn't.
 *
 * Sorted soonest-first, and the description leads with outstanding liability
 * rather than claim count — the actionable number is what customers are still
 * holding, not how popular the offer was.
 */
const HORIZON_DAYS = 14;

export function ExpiryAlerts({
  resource,
  nowMs,
}: {
  resource: Resource<Reward[]>;
  nowMs: number;
}) {
  return (
    <PanelCard
      title="Expiry alerts"
      subtitle={`Rewards lapsing in the next ${HORIZON_DAYS} days`}
      resource={resource}
      loading={<SkeletonRows count={2} height={64} />}
      empty={
        <EmptyPanel
          icon="expiry"
          title="Nothing expiring"
          description="No active rewards lapse in the next two weeks."
        />
      }
    >
      {(rewards) => {
        const soon = rewards
          .map((r) => ({r, days: daysUntil(r.expiresAt, nowMs)}))
          .filter(
            (x): x is {r: Reward; days: number} =>
              x.days !== null && x.days >= 0 && x.days <= HORIZON_DAYS,
          )
          .sort((a, b) => a.days - b.days);

        if (soon.length === 0) {
          return (
            <EmptyPanel
              icon="expiry"
              title="Nothing expiring"
              description="No active rewards lapse in the next two weeks."
            />
          );
        }

        return (
          <VStack gap={2}>
            {soon.map(({r, days}) => {
              const outstanding = r.claimed - r.used;
              return (
                <Banner
                  key={r.id}
                  // Under 3 days is an emergency; the rest is a heads-up.
                  status={days <= 3 ? 'error' : 'warning'}
                  title={`${r.name} expires ${days === 0 ? 'today' : days === 1 ? 'tomorrow' : `in ${days} days`}`}
                  description={`${formatCompact(outstanding)} unredeemed claims · ${formatLyt(outstanding * r.costLyt)} outstanding`}
                />
              );
            })}
          </VStack>
        );
      }}
    </PanelCard>
  );
}
