import { useState, useEffect, useRef, useCallback } from 'react';
import { format, addDays, addMonths, startOfMonth, endOfMonth, parseISO, differenceInDays } from 'date-fns';
import { ja } from 'date-fns/locale';
import { api } from '../api.js';
import { formatDateRange, formatReservationTooltip } from '../utils/carUtils.js';
import ReservationModal from './ReservationModal.jsx';
import styles from './TimelineView.module.css';

const ROW_HEIGHT = 48; // px per reservation row
const LABEL_WIDTH = 180; // px for reservation info column
const HEADER_HEIGHT = 60; // px for date header
const DAY_WIDTH = 36; // px per day column
const BAR_PADDING = 4; // px gap between bar and row edge

// Same colour palette as ScheduleView
const COLORS = [
  { bg: '#dbeafe', border: '#3b82f6', text: '#1e3a8a' },
  { bg: '#dcfce7', border: '#22c55e', text: '#14532d' },
  { bg: '#fef9c3', border: '#eab308', text: '#713f12' },
  { bg: '#fce7f3', border: '#ec4899', text: '#831843' },
  { bg: '#ede9fe', border: '#8b5cf6', text: '#3b0764' },
  { bg: '#ffedd5', border: '#f97316', text: '#7c2d12' },
  { bg: '#e0f2fe', border: '#0ea5e9', text: '#0c4a6e' },
  { bg: '#f0fdf4', border: '#16a34a', text: '#14532d' },
];

function getColor(index) {
  return COLORS[index % COLORS.length];
}

function dateToStr(date) {
  return format(date, 'yyyy-MM-dd');
}

export default function TimelineView({ reloadKey = 0 }) {
  const [cars, setCars] = useState([]);
  const [reservations, setReservations] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [modal, setModal] = useState(null);
  const [contextMenu, setContextMenu] = useState(null);

  // View window: show the current month by default
  const [viewStart, setViewStart] = useState(() => startOfMonth(new Date()));
  const [viewEnd, setViewEnd] = useState(() => endOfMonth(new Date()));

  const gridRef = useRef(null);

  const days = (() => {
    const result = [];
    let d = viewStart;
    while (d <= viewEnd) {
      result.push(d);
      d = addDays(d, 1);
    }
    return result;
  })();

  const totalWidth = LABEL_WIDTH + days.length * DAY_WIDTH;
  const todayStr = dateToStr(new Date());

  // --- Data loading ---
  const loadData = useCallback(async () => {
    try {
      setLoading(true);
      const [carsData, resData] = await Promise.all([api.getCars(), api.getReservations()]);
      setCars(carsData);
      setReservations(resData);
      setError(null);
    } catch (e) {
      setError(e.message);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    loadData();
  }, [loadData, reloadKey]);

  // Close context menu on click / Escape
  useEffect(() => {
    if (!contextMenu) return;
    const close = () => setContextMenu(null);
    const onKey = (e) => { if (e.key === 'Escape') close(); };
    window.addEventListener('click', close);
    window.addEventListener('keydown', onKey);
    return () => {
      window.removeEventListener('click', close);
      window.removeEventListener('keydown', onKey);
    };
  }, [contextMenu]);

  // --- Navigation ---
  const prevMonth = () => {
    const start = addMonths(viewStart, -1);
    setViewStart(startOfMonth(start));
    setViewEnd(endOfMonth(start));
  };
  const nextMonth = () => {
    const start = addMonths(viewStart, 1);
    setViewStart(startOfMonth(start));
    setViewEnd(endOfMonth(start));
  };
  const goThisMonth = () => {
    setViewStart(startOfMonth(new Date()));
    setViewEnd(endOfMonth(new Date()));
  };

  // --- Handlers ---
  const handleModalSave = async (data) => {
    try {
      if (modal.mode === 'edit') {
        await api.updateReservation(modal.reservation.id, data);
      } else {
        await api.createReservation(data);
      }
      setModal(null);
      await loadData();
    } catch (e) {
      setError(`予約の保存に失敗しました: ${e.message}`);
    }
  };

  const handleModalDelete = async (id) => {
    try {
      await api.deleteReservation(id);
      setModal(null);
      await loadData();
    } catch (e) {
      setError(`予約の削除に失敗しました: ${e.message}`);
    }
  };

  // Build car colour map
  const carColorMap = {};
  cars.forEach((car, i) => { carColorMap[car.id] = getColor(i); });

  // Sort reservations by start_date then car
  const sortedReservations = [...reservations].sort((a, b) => {
    if (a.start_date !== b.start_date) return a.start_date < b.start_date ? -1 : 1;
    return a.car_id - b.car_id;
  });

  const viewStartStr = dateToStr(viewStart);
  const viewEndStr = dateToStr(viewEnd);

  // Filter to reservations that overlap the view window
  const visibleReservations = sortedReservations.filter(
    (r) => r.end_date >= viewStartStr && r.start_date <= viewEndStr
  );

  function getBarLayout(r) {
    const clampedStart = r.start_date < viewStartStr ? viewStartStr : r.start_date;
    const clampedEnd = r.end_date > viewEndStr ? viewEndStr : r.end_date;
    const startOffset = differenceInDays(parseISO(clampedStart), viewStart);
    const endOffset = differenceInDays(parseISO(clampedEnd), viewStart);
    const left = startOffset * DAY_WIDTH;
    const width = (endOffset - startOffset + 1) * DAY_WIDTH;
    return { left, width };
  }

  return (
    <div className={styles.container}>
      {/* Toolbar */}
      <div className={styles.toolbar}>
        <div className={styles.navGroup}>
          <button className={styles.toolBtn} onClick={prevMonth}>‹ 前月</button>
          <button className={styles.toolBtn} onClick={goThisMonth}>今月</button>
          <button className={styles.toolBtn} onClick={nextMonth}>次月 ›</button>
        </div>
        <div className={styles.monthLabel}>
          {format(viewStart, 'yyyy年M月', { locale: ja })}
        </div>
        <button
          className={styles.addBtn}
          disabled={cars.length === 0}
          onClick={() =>
            setModal({
              mode: 'create',
              prefill: {
                car_id: cars[0]?.id,
                start_date: todayStr,
                end_date: todayStr,
              },
            })
          }
        >
          + 予約を追加
        </button>
      </div>

      {error && <div className={styles.error}>エラー: {error}</div>}

      {/* Timeline grid */}
      <div className={styles.gridWrapper} ref={gridRef}>
        {loading && (
          <div
            className={styles.loadingOverlay}
            style={{ height: HEADER_HEIGHT }}
          >
            読み込み中...
          </div>
        )}
        <div className={styles.grid} style={{ width: totalWidth }}>
          {/* Sticky header: month/day labels */}
          <div className={styles.headerRow} style={{ height: HEADER_HEIGHT }}>
            {/* Corner */}
            <div
              className={styles.cornerCell}
              style={{ width: LABEL_WIDTH, height: HEADER_HEIGHT }}
            >
              <span className={styles.cornerText}>予約一覧</span>
            </div>
            {/* Day columns */}
            {days.map((date) => {
              const ds = dateToStr(date);
              const isToday = ds === todayStr;
              const dow = format(date, 'E', { locale: ja });
              const isWeekend = dow === '土' || dow === '日';
              const isSun = dow === '日';
              const isSat = dow === '土';
              return (
                <div
                  key={ds}
                  className={`${styles.dayHeader} ${isToday ? styles.todayHeader : ''} ${isWeekend ? styles.weekendHeader : ''}`}
                  style={{ width: DAY_WIDTH, height: HEADER_HEIGHT }}
                >
                  <span className={styles.dayNum}>{format(date, 'd')}</span>
                  <span className={`${styles.dayDow} ${isSun ? styles.sunDow : ''} ${isSat ? styles.satDow : ''}`}>{dow}</span>
                </div>
              );
            })}
          </div>

          {/* Reservation rows */}
          {visibleReservations.map((r) => {
            const car = cars.find((c) => c.id === r.car_id);
            const color = carColorMap[r.car_id] || COLORS[0];
            const { left, width } = getBarLayout(r);

            return (
              <div key={r.id} className={styles.resRow} style={{ height: ROW_HEIGHT }}>
                {/* Label: car + customer */}
                <div
                  className={styles.resLabel}
                  style={{ width: LABEL_WIDTH, height: ROW_HEIGHT }}
                >
                  <span className={styles.carDot} style={{ background: color.border }} />
                  <div className={styles.labelText}>
                    <span className={styles.labelCar}>{car?.name ?? '—'}</span>
                    <span className={styles.labelCustomer}>{r.customer_name || '(名前なし)'}</span>
                  </div>
                </div>

                {/* Day cells (background) */}
                <div
                  className={styles.cellArea}
                  style={{ width: days.length * DAY_WIDTH, height: ROW_HEIGHT, position: 'relative' }}
                >
                  {days.map((date) => {
                    const ds = dateToStr(date);
                    const isToday = ds === todayStr;
                    const dow = format(date, 'E', { locale: ja });
                    const isWeekend = dow === '土' || dow === '日';
                    return (
                      <div
                        key={ds}
                        className={`${styles.cell} ${isToday ? styles.todayCell : ''} ${isWeekend ? styles.weekendCell : ''}`}
                        style={{ width: DAY_WIDTH, height: ROW_HEIGHT }}
                      />
                    );
                  })}

                  {/* Bar */}
                  <div
                    className={styles.bar}
                    style={{
                      left,
                      width: width - BAR_PADDING,
                      background: color.bg,
                      borderColor: color.border,
                      color: color.text,
                    }}
                    onClick={() => setModal({ mode: 'edit', reservation: r })}
                    onContextMenu={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      setContextMenu({ x: e.clientX, y: e.clientY, reservation: r });
                    }}
                    title={formatReservationTooltip(r)}
                  >
                    <span className={styles.barText}>
                      {r.customer_name || '予約'}
                    </span>
                    {width > 80 && (
                      <span className={styles.barDates}>
                        {formatDateRange(r.start_date, r.start_period, r.end_date, r.end_period)}
                      </span>
                    )}
                  </div>
                </div>
              </div>
            );
          })}

          {visibleReservations.length === 0 && !loading && (
            <div className={styles.empty}>
              この月には予約がありません。
            </div>
          )}
        </div>
      </div>

      {/* Reservation Modal */}
      {modal && (
        <ReservationModal
          cars={cars}
          reservation={modal.mode === 'edit' ? modal.reservation : modal.prefill}
          onSave={handleModalSave}
          onDelete={handleModalDelete}
          onClose={() => setModal(null)}
        />
      )}

      {/* Right-click context menu */}
      {contextMenu && (
        <div
          className={styles.contextMenu}
          style={{ left: contextMenu.x, top: contextMenu.y }}
          onClick={(e) => e.stopPropagation()}
        >
          <button
            className={styles.contextMenuItem}
            onClick={() => {
              setModal({ mode: 'edit', reservation: contextMenu.reservation });
              setContextMenu(null);
            }}
          >
            ✏️ 編集
          </button>
          <button
            className={`${styles.contextMenuItem} ${styles.contextMenuItemDelete}`}
            onClick={async () => {
              setContextMenu(null);
              await handleModalDelete(contextMenu.reservation.id);
            }}
          >
            🗑️ 削除
          </button>
        </div>
      )}
    </div>
  );
}
