'use client';

/**
 * Hour-of-week engagement heatmap. Driven by Umami's
 * `/api/websites/:id/sessions/weekly` endpoint which returns a 7×24
 * nested array of session counts (rows Sun…Sat, cols 0…23 UTC).
 *
 * Visual: a 7-row × 24-col grid of cells, with cell colour intensity
 * scaled to the max value across the whole grid. Hover any cell for a
 * floating tooltip showing the exact day/hour/count.
 */

import { useMemo, useState } from 'react';
import { Info } from 'lucide-react';

import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { Skeleton } from '@/components/ui/skeleton';
import { useUmamiSessionsWeekly } from './use-website-analytics';
import { type DateRange } from '@/lib/analytics/range';

interface Props {
  range: DateRange;
}

const DAYS_FULL = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
const DAYS_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

interface HoverInfo {
  dayIdx: number;
  hour: number;
  count: number;
}

export function WeeklyHeatmap({ range }: Props) {
  const query = useUmamiSessionsWeekly(range);
  const [hover, setHover] = useState<HoverInfo | null>(null);
  const grid = query.data?.data ?? null;
  const max = useMemo(() => {
    if (!grid) return 0;
    let m = 0;
    for (const row of grid) for (const v of row) if (v > m) m = v;
    return m;
  }, [grid]);

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-1.5 text-base">
          Engagement heatmap
          <Popover>
            <PopoverTrigger
              type="button"
              aria-label="How to read the engagement heatmap"
              className="inline-flex size-4 shrink-0 items-center justify-center rounded-full text-muted-foreground hover:bg-muted hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-400"
            >
              <Info className="size-3.5" aria-hidden />
            </PopoverTrigger>
            <PopoverContent align="start" className="w-80 text-xs leading-relaxed">
              <p className="font-semibold text-foreground">When is your audience active?</p>
              <p className="mt-2 text-muted-foreground">
                Each cell is one hour of one day - the columns are{' '}
                <strong>hours of the day in UTC</strong> (0 = midnight, 23 = 11 PM) and the rows are
                days of the week. Darker blue means more sessions started during that hour across
                the whole selected period. Hover any cell for the exact session count.
              </p>
            </PopoverContent>
          </Popover>
        </CardTitle>
      </CardHeader>
      <CardContent>
        {query.isLoading ? (
          <Skeleton className="h-[220px] w-full" />
        ) : !grid || max === 0 ? (
          <div className="py-10 text-center text-sm text-muted-foreground">
            No session activity in this range.
          </div>
        ) : (
          <div className="relative" onMouseLeave={() => setHover(null)}>
            {/* Hour-axis header */}
            <div className="flex pl-12 text-xs text-muted-foreground">
              {Array.from({ length: 24 }).map((_, h) => (
                <div key={h} className="flex-1 text-center">
                  {h % 2 === 0 ? h : ''}
                </div>
              ))}
            </div>
            {/* Grid */}
            <div className="mt-1">
              {grid.map((row, dIdx) => (
                <div key={dIdx} className="flex items-center">
                  <div className="w-12 pr-2 text-right text-xs text-muted-foreground">
                    {DAYS_SHORT[dIdx]}
                  </div>
                  <div className="flex flex-1 gap-px">
                    {row.map((v, h) => {
                      const intensity = v / max;
                      const isHovered = hover?.dayIdx === dIdx && hover?.hour === h;
                      return (
                        <div
                          key={h}
                          onMouseEnter={() => setHover({ dayIdx: dIdx, hour: h, count: v })}
                          className="aspect-square min-w-0 flex-1 rounded-sm transition-all cursor-pointer"
                          style={{
                            backgroundColor:
                              v === 0 ? '#f1f5f9' : `rgba(37, 99, 235, ${0.15 + 0.85 * intensity})`,
                            outline: isHovered ? '2px solid #f59e0b' : 'none',
                            outlineOffset: '-1px',
                          }}
                        />
                      );
                    })}
                  </div>
                </div>
              ))}
            </div>
            {/* Hour-axis footer (mirrors header so wide cards read symmetrically) */}
            <div className="mt-1 flex pl-12 text-xs text-muted-foreground">
              {Array.from({ length: 24 }).map((_, h) => (
                <div key={h} className="flex-1 text-center">
                  {h % 2 === 0 ? `${h}:00` : ''}
                </div>
              ))}
            </div>

            {/* Legend + floating value indicator */}
            <div className="mt-4 flex items-center justify-between gap-4 text-xs text-muted-foreground">
              <span>
                Hour of day (UTC) - colour intensity scaled to peak ({max.toLocaleString()}{' '}
                sessions)
              </span>
              <div className="flex items-center gap-1">
                <span>Less</span>
                <div className="flex gap-px">
                  {[0, 0.25, 0.5, 0.75, 1].map((i) => (
                    <div
                      key={i}
                      className="size-3 rounded-sm"
                      style={{
                        backgroundColor:
                          i === 0 ? '#f1f5f9' : `rgba(37, 99, 235, ${0.15 + 0.85 * i})`,
                      }}
                    />
                  ))}
                </div>
                <span>More</span>
              </div>
            </div>

            {/* Hover tooltip  -  single element re-positioned via the
                hovered cell's data, much cheaper than mounting 168
                Radix Tooltips. */}
            {hover ? (
              <div className="pointer-events-none absolute top-0 right-0 -mt-2 rounded-md border border-border bg-popover px-3 py-1.5 text-xs shadow-md">
                <div className="font-medium text-foreground">
                  {DAYS_FULL[hover.dayIdx]} {hover.hour}:00–{hover.hour}:59 UTC
                </div>
                <div className="tabular-nums text-muted-foreground">
                  {hover.count.toLocaleString()} session{hover.count === 1 ? '' : 's'}
                </div>
              </div>
            ) : null}
          </div>
        )}
      </CardContent>
    </Card>
  );
}
