/**
 * Лента ремонтов парка (Фича 2 + У5 + У38 + У39 + У40 + У41).
 *
 * Главный экран раздела «Ремонт». Все ремонты парка, сортировка
 * `created_at DESC`. Бесконечный скролл по 20. Pull-to-refresh,
 * обновление при возврате в приложение (через useRepairsFeed).
 *
 * Пустая лента — плейсхолдер «В парке пока нет ремонтов» (У41).
 */
import { useCallback, useEffect, useMemo, useRef } from "react";
import { useNavigate } from "react-router-dom";
import { useQuery } from "@tanstack/react-query";
import { ChevronLeft, Plus, Wrench } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useRepairsFeed } from "@/hooks/useRepairsFeed";
import { formatFeedTimestamp } from "@/lib/timeFormat";
import { getRepairsMonthStats, type FeedItem } from "@/api/repairsFeed";
import { groupByLocalDay, formatDayLabel, fmtMoney, pluralRepairs, pluralWorks } from "@/lib/repairsFeed";

export default function RepairsFeedPage() {
  const navigate = useNavigate();
  const {
    items,
    isLoading,
    isError,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    refetch,
    isFetching,
  } = useRepairsFeed();

  // Сумма и количество ремонтов за текущий месяц (отдельный endpoint —
  // не зависит от пагинации ленты).
  const monthStatsQuery = useQuery({
    queryKey: ["repairs-month-stats"],
    queryFn: getRepairsMonthStats,
    staleTime: 60_000,
  });

  // Группировка items по локальной дате (Asia/Vladivostok).
  const grouped = useMemo(() => groupByLocalDay(items), [items]);

  // IntersectionObserver для бесконечной прокрутки.
  const sentinelRef = useRef<HTMLDivElement | null>(null);
  useEffect(() => {
    const el = sentinelRef.current;
    if (!el || !hasNextPage) return;
    const io = new IntersectionObserver(
      (entries) => {
        if (entries[0]?.isIntersecting && !isFetchingNextPage) {
          void fetchNextPage();
        }
      },
      { rootMargin: "200px" },
    );
    io.observe(el);
    return () => io.disconnect();
  }, [hasNextPage, isFetchingNextPage, fetchNextPage]);

  // Pull-to-refresh: простой UX через тач-скролл сверху.
  // Делаем минимально-инвазивно: на тап-кнопку «обновить» вызываем refetch.
  // Полноценный pull-to-refresh с жестом — отдельная задача.
  const handleRefresh = useCallback(() => {
    void refetch();
  }, [refetch]);

  const handleAdd = () => navigate("/repairs/new");
  const handleOpen = (item: FeedItem) => navigate(`/repairs/${item.id}`);

  return (
    <div className="min-h-screen bg-background flex flex-col">
      <header className="sticky top-0 z-10 bg-background/95 backdrop-blur border-b">
        <div className="flex items-center justify-between p-3">
          <Button
            variant="ghost"
            size="sm"
            onClick={() => navigate("/")}
            className="-ml-2"
            aria-label="Назад"
          >
            <ChevronLeft className="h-5 w-5" />
            <span className="ml-1">Назад</span>
          </Button>
          <h1 className="text-base font-semibold">Ремонт</h1>
          <Button
            variant="default"
            size="sm"
            onClick={handleAdd}
            aria-label="Добавить ремонт"
          >
            <Plus className="h-4 w-4 mr-1" />
            <span className="hidden sm:inline">Добавить</span>
          </Button>
        </div>
      </header>

      <main className="flex-1 container max-w-2xl py-3 space-y-2">
        {/* Итого слева — сумма работ и количество ремонтов за текущий месяц
            (с 1-го числа по now). Обновить справа. */}
        <div className="flex items-center justify-between">
          <div className="text-sm">
            <span className="text-muted-foreground">За этот месяц:</span>{" "}
            <span className="font-semibold tabular-nums">
              {fmtMoney(monthStatsQuery.data?.total ?? 0)} ₽
            </span>
            {(monthStatsQuery.data?.count ?? 0) > 0 && (
              <span className="text-xs text-muted-foreground ml-2">
                ({monthStatsQuery.data!.count}{" "}
                {pluralRepairs(monthStatsQuery.data!.count)})
              </span>
            )}
          </div>
          <button
            type="button"
            onClick={handleRefresh}
            disabled={isFetching}
            className="text-xs text-muted-foreground hover:text-foreground disabled:opacity-50"
          >
            {isFetching ? "Обновляем…" : "Обновить"}
          </button>
        </div>

        {isLoading && (
          <div className="space-y-2">
            {Array.from({ length: 3 }).map((_, i) => (
              <div key={i} className="h-20 rounded-lg bg-muted animate-pulse" />
            ))}
          </div>
        )}

        {isError && !isLoading && (
          <div className="rounded-md border border-destructive bg-destructive/10 p-3 text-sm">
            Не удалось загрузить ленту ремонтов. Проверьте сеть и попробуйте снова.
          </div>
        )}

        {!isLoading && !isError && items.length === 0 && <EmptyState onAdd={handleAdd} />}

        {items.length > 0 && (
          <ul className="space-y-2">
            {grouped.map((group) => (
              <li key={group.key}>
                <DaySeparator dateKey={group.key} total={group.total} count={group.items.length} />
                <ul className="space-y-2 mt-2">
                  {group.items.map((item) => (
                    <li key={item.id}>
                      <RepairRow item={item} onOpen={() => handleOpen(item)} />
                    </li>
                  ))}
                </ul>
              </li>
            ))}
          </ul>
        )}

        <div ref={sentinelRef} aria-hidden="true" />
        {isFetchingNextPage && (
          <div className="text-center text-xs text-muted-foreground py-4">
            Загружаем ещё…
          </div>
        )}
        {!hasNextPage && items.length > 0 && !isFetchingNextPage && (
          <div className="text-center text-xs text-muted-foreground py-4">
            Это все ремонты.
          </div>
        )}
      </main>
    </div>
  );
}


// Группировка по локальной дате (VLA), форматирование сумм/склонений —
// в @/lib/repairsFeed (покрыто юнит-тестами).

function DaySeparator({ dateKey, total, count }: { dateKey: string; total: number; count: number }) {
  return (
    <div className="flex items-center gap-2 pt-3 pb-1 text-xs">
      <span className="font-medium text-foreground">{formatDayLabel(dateKey)}</span>
      <div className="flex-1 border-t border-dashed border-border" />
      <span className="tabular-nums text-muted-foreground">
        {fmtMoney(total)} ₽
        <span className="ml-1">({count} {pluralRepairs(count)})</span>
      </span>
    </div>
  );
}


function RepairRow({ item, onOpen }: { item: FeedItem; onOpen: () => void }) {
  const carLine = [item.car_plate, item.car_make, item.car_model]
    .filter(Boolean)
    .join(" · ");
  return (
    <button
      type="button"
      onClick={onOpen}
      className="w-full flex items-stretch gap-3 rounded-lg border bg-card hover:bg-accent/40 transition-colors text-left p-3"
    >
      <div className="w-16 h-16 rounded-md bg-muted overflow-hidden flex-shrink-0 flex items-center justify-center">
        {item.photo_url ? (
          // Lazy-load — браузер сам решит когда грузить.
          <img
            src={item.photo_url}
            alt=""
            loading="lazy"
            className="w-full h-full object-cover"
          />
        ) : (
          <Wrench className="h-6 w-6 text-muted-foreground" />
        )}
      </div>
      <div className="flex-1 min-w-0">
        <div className="flex items-baseline justify-between gap-2">
          <div className="font-medium truncate">
            {carLine}
            {item.is_external && (
              <span className="ml-1.5 align-middle text-[10px] font-semibold uppercase tracking-wide text-amber-700 bg-amber-100 rounded px-1 py-0.5">
                с улицы
              </span>
            )}
          </div>
          <div className="text-xs text-muted-foreground flex-shrink-0">
            {formatFeedTimestamp(item.created_at)}
          </div>
        </div>
        {item.driver_name && (
          <div className="text-xs text-muted-foreground truncate">
            Водитель: {item.driver_name}
          </div>
        )}
        <div className="text-xs text-muted-foreground truncate">
          Механик: {item.mechanic_name}
        </div>
        <div className="flex items-baseline justify-between gap-2">
          <WorksLine works={item.works_preview.map((w) => w.name)} extra={item.works_extra} />
          <div className="text-sm font-semibold tabular-nums flex-shrink-0">
            {fmtMoney(item.works_total || 0)} ₽
          </div>
        </div>
      </div>
    </button>
  );
}


function WorksLine({ works, extra }: { works: string[]; extra: number }) {
  // У40: ellipsis в одну строку. Соединяем имена работ через «·».
  if (works.length === 0) return null;
  const tail = extra > 0 ? ` · +${extra} ${pluralWorks(extra)}` : "";
  return (
    <div className="text-sm truncate" title={works.join(", ") + (extra ? ` (+${extra})` : "")}>
      {works.join(" · ")}
      {tail && <span className="text-muted-foreground">{tail}</span>}
    </div>
  );
}


function EmptyState({ onAdd }: { onAdd: () => void }) {
  return (
    <div className="flex flex-col items-center justify-center text-center py-16 px-4 space-y-4">
      <div className="rounded-full bg-muted p-4">
        <Wrench className="h-8 w-8 text-muted-foreground" />
      </div>
      <div className="space-y-1">
        <h2 className="text-base font-semibold">В парке пока нет ремонтов</h2>
        <p className="text-sm text-muted-foreground max-w-xs">
          Создайте первый ремонт — он появится здесь.
        </p>
      </div>
      <Button onClick={onAdd}>
        <Plus className="h-4 w-4 mr-1" />
        Добавить ремонт
      </Button>
    </div>
  );
}
