import React, { useEffect, useMemo, useState } from 'react';
import styled, { useTheme } from 'styled-components';
import { AxiosResponse } from 'axios';
import { axiosInstance } from '../../../axiosApi';

export type PromptHeatmapData = {
  tz: string;
  total: number;
  max: number;
  days: string[];
  hours: number[];
  matrix: number[][];
  most_active_day: string | null;
  most_active_hour: number | null;
  peak_cell: { day: string; hour: number; count: number } | null;
};

const GlassCard = styled.div`
  background: ${({ theme }) => theme.colors.cardBackground};
  backdrop-filter: blur(10px);
  border: 1px solid ${({ theme }) => theme.colors.cardBorder};
  border-radius: 1rem;
  padding: 2rem;
  width: 100%;
  max-width: 1000px;
  margin-bottom: 2rem;
  box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
`;

const CardTitle = styled.h2`
  font-size: 1.8rem;
  margin-bottom: 0.5rem;
  color: ${({ theme }) => theme.colors.text};
  border-bottom: 1px solid ${({ theme }) => theme.colors.cardBorder};
  padding-bottom: 1rem;
`;

const Subtitle = styled.p`
  margin: 0.75rem 0 1.25rem 0;
  color: ${({ theme }) => theme.colors.text};
  opacity: 0.7;
  font-size: 0.95rem;
  line-height: 1.5;
`;

const GridScroll = styled.div`
  overflow-x: auto;
`;

const HeatmapGrid = styled.div`
  display: grid;
  grid-template-columns: 3rem repeat(24, minmax(14px, 1fr));
  gap: 3px;
  min-width: 520px;
`;

const Corner = styled.div``;

const AxisLabel = styled.div`
  font-size: 0.7rem;
  color: ${({ theme }) => theme.colors.text};
  opacity: 0.55;
  display: flex;
  align-items: center;
  justify-content: center;
`;

const DayLabel = styled(AxisLabel)`
  justify-content: flex-start;
  padding-left: 0.15rem;
`;

const Cell = styled.button<{ $intensity: number; $color: string }>`
  aspect-ratio: 1;
  border: none;
  border-radius: 3px;
  padding: 0;
  cursor: default;
  background: ${({ $intensity, $color, theme }) =>
    $intensity <= 0
      ? theme.darkMode
        ? 'rgba(255,255,255,0.08)'
        : 'rgba(0,0,0,0.08)'
      : $color};
  opacity: ${({ $intensity }) => ($intensity <= 0 ? 1 : 0.35 + $intensity * 0.65)};

  &:hover {
    outline: 1px solid ${({ theme }) => theme.colors.text}66;
  }
`;

const Footer = styled.p`
  margin: 1rem 0 0 0;
  color: ${({ theme }) => theme.colors.text};
  opacity: 0.7;
  font-size: 0.9rem;
  line-height: 1.5;
`;

const StatusText = styled.p`
  color: ${({ theme }) => theme.colors.text};
  opacity: 0.7;
`;

const hexToRgb = (hex: string): { r: number; g: number; b: number } | null => {
  const cleaned = hex.replace('#', '');
  if (cleaned.length !== 6) return null;
  return {
    r: parseInt(cleaned.slice(0, 2), 16),
    g: parseInt(cleaned.slice(2, 4), 16),
    b: parseInt(cleaned.slice(4, 6), 16),
  };
};

const PromptHeatmapCard = (): JSX.Element => {
  const theme = useTheme();
  const [data, setData] = useState<PromptHeatmapData | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);
  const [hover, setHover] = useState<{ day: string; hour: number; count: number } | null>(null);

  useEffect(() => {
    let cancelled = false;
    const tz = Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';

    (async () => {
      try {
        const response: AxiosResponse<PromptHeatmapData> = await axiosInstance.get(
          '/analytics/user_prompt_heatmap/',
          { params: { tz } }
        );
        if (!cancelled) {
          setData(response.data);
          setError(false);
        }
      } catch {
        if (!cancelled) {
          setError(true);
          setData(null);
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();

    return () => {
      cancelled = true;
    };
  }, []);

  const themeColor = theme?.main || '#4a90e2';
  const rgb = useMemo(() => hexToRgb(themeColor), [themeColor]);

  const cellColor = (count: number, max: number) => {
    if (!rgb || max <= 0 || count <= 0) return themeColor;
    const t = count / max;
    return `rgb(${Math.round(rgb.r * (0.4 + 0.6 * t))}, ${Math.round(
      rgb.g * (0.4 + 0.6 * t)
    )}, ${Math.round(rgb.b * (0.4 + 0.6 * t))})`;
  };

  const hourLabels = [0, 6, 12, 18, 23];

  return (
    <GlassCard>
      <CardTitle>Prompt activity</CardTitle>
      <Subtitle>
        When you send prompts across the week (local timezone
        {data?.tz ? `: ${data.tz}` : ''}).
      </Subtitle>

      {loading && <StatusText>Loading heatmap…</StatusText>}
      {error && <StatusText>Could not load prompt activity.</StatusText>}
      {!loading && !error && data && (
        <>
          <GridScroll>
            <HeatmapGrid role="img" aria-label="Prompt activity heatmap by weekday and hour">
              <Corner />
              {data.hours.map((hour) => (
                <AxisLabel key={`h-${hour}`}>{hourLabels.includes(hour) ? hour : ''}</AxisLabel>
              ))}
              {data.days.map((day, dayIdx) => (
                <React.Fragment key={day}>
                  <DayLabel>{day}</DayLabel>
                  {data.hours.map((hour) => {
                    const count = data.matrix[dayIdx]?.[hour] ?? 0;
                    const intensity = data.max > 0 ? count / data.max : 0;
                    return (
                      <Cell
                        key={`${day}-${hour}`}
                        type="button"
                        $intensity={intensity}
                        $color={cellColor(count, data.max)}
                        aria-label={`${day} ${hour}:00 — ${count} prompts`}
                        onMouseEnter={() => setHover({ day, hour, count })}
                        onMouseLeave={() => setHover(null)}
                        onFocus={() => setHover({ day, hour, count })}
                        onBlur={() => setHover(null)}
                      />
                    );
                  })}
                </React.Fragment>
              ))}
            </HeatmapGrid>
          </GridScroll>
          <Footer>
            {hover
              ? `${hover.day} ${hover.hour}:00 — ${hover.count} prompt${hover.count === 1 ? '' : 's'}`
              : data.total === 0
                ? 'No prompts yet. Chat a bit and this grid fills in.'
                : [
                    `${data.total} prompt${data.total === 1 ? '' : 's'} total`,
                    data.most_active_day ? `Most active day: ${data.most_active_day}` : null,
                    data.most_active_hour != null
                      ? `Most active hour: ${data.most_active_hour}:00`
                      : null,
                    data.peak_cell
                      ? `Peak: ${data.peak_cell.day} ${data.peak_cell.hour}:00 (${data.peak_cell.count})`
                      : null,
                  ]
                    .filter(Boolean)
                    .join(' · ')}
          </Footer>
        </>
      )}
    </GlassCard>
  );
};

export default PromptHeatmapCard;
