'use client';

import { fetchLatestCommodityPrices, fetchLatestPrices } from '@/actions/prices.js';
import type { getLatestPrices } from '@/generated/prisma/sql.js';
import { deserialize } from '@/lib/superjson.js';
import { cn } from '@/lib/utils.js';
import { useEffect, useState } from 'react';

interface TickerItem {
  label: string;
  price: string;
  change: number | null;
  unit: string;
}

function formatPrice(price: number, unit: string): string {
  if (unit === '$/MWh') {
    return `$${price.toFixed(2)}`;
  }
  return `$${price.toFixed(2)}`;
}

function TickerItemDisplay({ item }: { item: TickerItem }) {
  const changeColor =
    item.change === null ? 'text-muted-foreground' : item.change >= 0 ? 'text-emerald-400' : 'text-red-400';

  const changeSymbol = item.change === null ? '' : item.change >= 0 ? '\u25B2' : '\u25BC';

  return (
    <span className="inline-flex items-center gap-1.5 px-4 text-sm whitespace-nowrap">
      <span className="font-medium text-muted-foreground">{item.label}</span>
      <span className="font-bold tabular-nums">{item.price}</span>
      <span className="text-xs text-muted-foreground">{item.unit}</span>
      {item.change !== null && (
        <span className={cn('text-xs font-medium tabular-nums', changeColor)}>
          {changeSymbol} {Math.abs(item.change).toFixed(1)}%
        </span>
      )}
      <span className="ml-3 text-border">|</span>
    </span>
  );
}

export function TickerTape() {
  const [items, setItems] = useState<TickerItem[]>([]);

  useEffect(() => {
    async function loadPrices() {
      const [priceResult, commodityResult] = await Promise.all([fetchLatestPrices(), fetchLatestCommodityPrices()]);

      const tickerItems: TickerItem[] = [];

      if (priceResult.ok) {
        const prices = deserialize<getLatestPrices.Result[]>(priceResult.data);
        for (const p of prices) {
          tickerItems.push({
            label: p.region_code,
            price: formatPrice(p.price_mwh, '$/MWh'),
            change: null,
            unit: '$/MWh',
          });
        }
      }

      if (commodityResult.ok) {
        const commodities = deserialize<
          Array<{
            commodity: string;
            price: number;
            unit: string;
            timestamp: Date;
            source: string;
          }>
        >(commodityResult.data);

        const commodityLabels: Record<string, string> = {
          natural_gas: 'Nat Gas',
          wti_crude: 'WTI Crude',
          coal: 'Coal',
        };

        for (const c of commodities) {
          tickerItems.push({
            label: commodityLabels[c.commodity] ?? c.commodity,
            price: formatPrice(c.price, c.unit),
            change: null,
            unit: c.unit,
          });
        }
      }

      setItems(tickerItems);
    }

    void loadPrices();

    const interval = setInterval(() => void loadPrices(), 60_000);
    return () => clearInterval(interval);
  }, []);

  if (items.length === 0) {
    return null;
  }

  return (
    <div className="overflow-hidden border-b border-border/40 bg-muted/30">
      <div className="ticker-scroll-container flex py-1.5">
        {/* Duplicate items for seamless looping */}
        <div className="ticker-scroll flex shrink-0">
          {items.map((item, i) => (
            <TickerItemDisplay key={`a-${i}`} item={item} />
          ))}
        </div>
        <div className="ticker-scroll flex shrink-0" aria-hidden>
          {items.map((item, i) => (
            <TickerItemDisplay key={`b-${i}`} item={item} />
          ))}
        </div>
      </div>
    </div>
  );
}
