import React, { useState, useEffect, useRef } from 'react';
import { useRemoteControl } from '../hooks/useRemoteControl';
import { fetchChannels, fetchChannelAirings } from '../api';

// Hours to show in the EPG and width configs
const EPG_HOURS = 4;
const HOUR_WIDTH_PX = 360; 
const PX_PER_MS = HOUR_WIDTH_PX / (60 * 60 * 1000);

function fmtTime(iso) {
  if (!iso) return '';
  return new Date(iso).toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });
}

export default function Guide({ onClose, onSelectChannel }) {
  const [channels, setChannels] = useState([]);
  const [airings, setAirings] = useState({});   // { channelId: [airing, ...] }
  const [selectedIndex, setSelectedIndex] = useState(0);
  const [now, setNow] = useState(Date.now());
  const scrollRef = useRef(null);

  // Time anchor: align to previous 30-min boundary for clean axis
  const anchorTime = useRef(new Date(Math.floor(Date.now() / 1800000) * 1800000).getTime());

  useRemoteControl({
    onUp:    () => setSelectedIndex(prev => (prev - 1 + channels.length) % channels.length),
    onDown:  () => setSelectedIndex(prev => (prev + 1) % channels.length),
    onSelect: () => channels[selectedIndex] && onSelectChannel(channels[selectedIndex].id),
    onBack:  onClose,
  });

  // Clock tick
  useEffect(() => {
    const timer = setInterval(() => setNow(Date.now()), 15000); // 15s refresh
    return () => clearInterval(timer);
  }, []);

  // Fetch channels and airings
  useEffect(() => {
    fetchChannels()
      .then(data => {
        if (!data || data.length === 0) {
          setChannels([{ id: 99, channel_number: 99, name: 'No Channels Found' }]);
          return;
        }
        setChannels(data);

        // Fetch overlapping data for timeline
        Promise.allSettled(
          data.map(ch =>
            fetchChannelAirings(ch.id, EPG_HOURS)
              .then(list => ({ channelId: ch.id, list }))
              .catch(() => ({ channelId: ch.id, list: [] }))
          )
        ).then(results => {
          const map = {};
          for (const r of results) {
            if (r.status === 'fulfilled') {
              map[r.value.channelId] = r.value.list;
            }
          }
          setAirings(map);
        });
      })
      .catch((err) => {
        console.error("Guide fetch error:", err);
        setChannels([{ id: 99, channel_number: 99, name: 'Network Error' }]);
      });
  }, []);

  // Auto-scroll the timeline to keep the playhead visible but leave 
  // ~0.5 hours of padding on the left
  useEffect(() => {
    if (scrollRef.current) {
      const msOffset = now - anchorTime.current;
      const pxOffset = msOffset * PX_PER_MS;
      // scroll left to (current time - 30 mins)
      const targetScroll = Math.max(0, pxOffset - (HOUR_WIDTH_PX / 2));
      scrollRef.current.scrollLeft = targetScroll;
    }
  }, [now, airings]);

  const currentTimeStr = new Date(now).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
  const playheadPx = (now - anchorTime.current) * PX_PER_MS;

  // Generate grid time slots (half-hour chunks)
  const timeSlots = Array.from({ length: EPG_HOURS * 2 + 2 }).map((_, i) => {
    const ts = new Date(anchorTime.current + (i * 30 * 60 * 1000));
    return {
      label: ts.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }),
      left: i * (HOUR_WIDTH_PX / 2)
    };
  });

  // Background pattern width
  const containerWidthPx = (EPG_HOURS * HOUR_WIDTH_PX) + HOUR_WIDTH_PX;

  return (
    <div className="guide-container open">
      <div className="guide-header">
        <h1>PYTV Guide</h1>
        <div className="guide-clock">{currentTimeStr}</div>
      </div>

      <div className="epg-wrapper">
        
        {/* Left fixed column for Channels */}
        <div className="epg-channels-col">
          <div className="epg-corner"></div>
          <div className="epg-grid-rows">
            {channels.map((chan, idx) => (
              <div key={chan.id} className={`epg-row ${idx === selectedIndex ? 'active' : ''}`}>
                <div className="epg-ch-num">{chan.channel_number}</div>
                <div className="epg-ch-name">{chan.name}</div>
              </div>
            ))}
          </div>
        </div>

        {/* Scrollable Timeline */}
        <div className="epg-timeline-scroll" ref={scrollRef}>
          <div 
            className="epg-timeline-container" 
            style={{ width: `${containerWidthPx}px`, backgroundSize: `${HOUR_WIDTH_PX / 2}px 100%` }}
          >
            {/* Time Axis Row */}
            <div className="epg-time-axis">
              {timeSlots.map((slot, i) => (
                <div key={i} className="epg-time-slot" style={{ left: `${slot.left}px` }}>
                  {slot.label}
                </div>
              ))}
            </div>

            {/* Live Playhead Line */}
            {playheadPx > 0 && playheadPx < containerWidthPx && (
              <div className="epg-playhead" style={{ left: `${playheadPx}px` }} />
            )}

            {/* Grid Rows for Airings */}
            <div className="epg-grid-rows">
              {channels.map((chan, idx) => {
                const chanAirings = airings[chan.id];
                const isLoading = !chanAirings && chan.id !== 99;

                return (
                  <div key={chan.id} className={`epg-row ${idx === selectedIndex ? 'active' : ''}`}>
                    {isLoading && <div className="epg-loading">Loading...</div>}
                    {!isLoading && chanAirings?.length === 0 && (
                      <div className="epg-empty">No scheduled programs</div>
                    )}

                    {chanAirings && chanAirings.map(a => {
                      const sTs = new Date(a.starts_at).getTime();
                      const eTs = new Date(a.ends_at).getTime();
                      
                      // Filter anything that ended before our timeline anchor
                      if (eTs <= anchorTime.current) return null;

                      // Calculate block dimensions
                      const startPx = Math.max(0, (sTs - anchorTime.current) * PX_PER_MS);
                      const rawEndPx = (eTs - anchorTime.current) * PX_PER_MS;
                      const endPx = Math.min(containerWidthPx, rawEndPx);
                      const widthPx = Math.max(2, endPx - startPx);

                      let stateClass = 'future';
                      if (now >= sTs && now < eTs) stateClass = 'current';
                      if (now >= eTs) stateClass = 'past';

                      return (
                        <div 
                          key={a.id} 
                          className={`epg-program ${stateClass}`}
                          style={{ left: `${startPx}px`, width: `${widthPx}px` }}
                          onClick={() => onSelectChannel(chan.id)}
                        >
                          <div className="epg-program-title">{a.media_item_title}</div>
                          <div className="epg-program-time">{fmtTime(a.starts_at)} - {fmtTime(a.ends_at)}</div>
                        </div>
                      );
                    })}
                  </div>
                );
              })}
            </div>
          </div>
        </div>

      </div>

      <div style={{ padding: '0 3rem', flexShrink: 0, marginTop: '2rem', color: 'var(--pytv-text-dim)', textAlign: 'center' }}>
        Press <span style={{ color: '#fff' }}>Enter</span> to tune &middot; <span style={{ color: '#fff' }}>&uarr;&darr;</span> to navigate channels &middot; <span style={{ color: '#fff' }}>Escape</span> to close
      </div>
    </div>
  );
}
