import { useEffect, useState } from "react";
import { Pressable, View } from "react-native";
import { router } from "expo-router";
import { keepPreviousData, useQuery } from "@tanstack/react-query";
import { api, ApiError } from "@/lib/api";
import { useAnalytics } from "@/lib/analytics";
import { recommendationsViewed } from "@app/analytics";
import { getLanguageTag, t } from "@/lib/i18n";
import {
  Body,
  Button,
  Card,
  EmptyState,
  ErrorView,
  Heading,
  Input,
  LoadingView,
  Row,
  Screen,
  Small,
  Spacer,
  Tag,
  Title,
} from "@/components/ui";
import { colors, spacing } from "@/lib/theme";

/** "Vad ska vi äta?" (spec §4.1, §18) – appens viktigaste vy. */

interface Recommendation {
  recipeId: string;
  titleSv: string;
  title?: string;
  score: number;
  whySv: string;
  missingIngredients: string[];
  usesExpiring: Array<{ nameSv: string; name?: string; daysLeft: number | null }>;
  coveragePercent: number;
  ratingAverage: number | null;
  ratingCount: number;
}
interface MealBoxSuggestion {
  mealBoxId: string;
  titleSv: string;
  title?: string;
  portionsRemaining: number;
  recommendedUseBy: string;
  useByUrgent: boolean;
}
interface WhatToEatResponse {
  recommendations: Recommendation[];
  mealBoxSuggestions: MealBoxSuggestion[];
  context: {
    activeHolidays: Array<{ slug: string; name: string }>;
    remainingKcal: number;
    remainingProteinG: number;
    searchSuggestion?: string | null;
  };
}

// Kategori-flikar. Alla använder SAMMA rekommendations-motor (what-to-eat) så
// vyn blir identisk överallt: %-hemma, stjärnor och "Visa fler". De flesta
// filtrerar på måltidstyp; "Baka" på taggen "baking" (ctxMeal styr bara
// poängsättningen så bakverk inte nedviktas som "fel måltid").
const CATS: ReadonlyArray<{
  key: string;
  labelKey: string | null;
  label?: string;
  mealType?: string;
  tag?: string;
  ctxMeal?: string;
  glyph: string;
}> = [
  { key: "breakfast", labelKey: "myday.mealType.breakfast", mealType: "breakfast", glyph: "🥣" },
  { key: "lunch", labelKey: "myday.mealType.lunch", mealType: "lunch", glyph: "🥗" },
  { key: "dinner", labelKey: "myday.mealType.dinner", mealType: "dinner", glyph: "🍽️" },
  { key: "snack", labelKey: "myday.mealType.snack", mealType: "snack", glyph: "🍎" },
  { key: "dessert", labelKey: "myday.mealType.dessert", mealType: "dessert", glyph: "🍰" },
  { key: "baking", labelKey: "cat.baking", tag: "baking", ctxMeal: "dessert", glyph: "🥐" },
];

const errText = (e: unknown): string | undefined =>
  e instanceof ApiError ? `[${e.status}] ${e.message}` : e instanceof Error ? e.message : undefined;

export default function WhatToEatScreen() {
  const [searchText, setSearchText] = useState("");
  const [submittedSearch, setSubmittedSearch] = useState("");
  const [page, setPage] = useState(0);
  const [cat, setCat] = useState<string | null>(null); // null = Rekommenderat
  const [holiday, setHoliday] = useState<string | null>(null); // vald högtid (slug)
  const { track } = useAnalytics();

  const hour = new Date().getHours();
  const currentMeal = hour < 10 ? "breakfast" : hour < 14 ? "lunch" : "dinner";

  const activeCat = cat === null ? null : CATS.find((c) => c.key === cat);

  const query = useQuery({
    queryKey: ["what-to-eat", cat, holiday, submittedSearch, currentMeal],
    queryFn: () => {
      let path = "/v1/recommendations/what-to-eat?limit=20&view=default";
      if (activeCat?.tag) {
        path += `&tag=${activeCat.tag}&mealType=${activeCat.ctxMeal ?? "dessert"}`;
      } else {
        path += `&mealType=${activeCat?.mealType ?? currentMeal}`;
      }
      if (holiday) path += `&holiday=${encodeURIComponent(holiday)}`;
      // Sök bland alla recept (på titel) oavsett vald flik/högtid.
      if (submittedSearch) path += `&search=${encodeURIComponent(submittedSearch)}`;
      return api<WhatToEatResponse>(path);
    },
    placeholderData: keepPreviousData,
  });

  // Sök, flik och högtid är ömsesidigt uteslutande – ett aktivt filter i taget.
  const submitSearch = (value: string) => {
    setSearchText(value);
    setSubmittedSearch(value.trim());
    setHoliday(null);
    setPage(0);
  };
  const selectCat = (value: string | null) => {
    setCat(value);
    setHoliday(null);
    setSearchText("");
    setSubmittedSearch("");
    setPage(0);
  };
  const selectHoliday = (slug: string) => {
    setHoliday((cur) => (cur === slug ? null : slug)); // toggla av/på
    setCat(null);
    setSearchText("");
    setSubmittedSearch("");
    setPage(0);
  };

  const allRecs = query.data?.recommendations ?? [];
  const shownRecs: Recommendation[] = allRecs.length
    ? Array.from(
        { length: Math.min(5, allRecs.length) },
        (_, i) => allRecs[(page * 5 + i) % allRecs.length],
      ).filter((r): r is Recommendation => r != null)
    : [];

  useEffect(() => {
    if (query.data) {
      track(
        recommendationsViewed({
          properties: {
            craving: submittedSearch || undefined,
            count: query.data.recommendations.length,
            hasMealBoxSuggestions: query.data.mealBoxSuggestions.length > 0,
          },
        }),
      );
    }
  }, [query.data]); // eslint-disable-line react-hooks/exhaustive-deps

  return (
    <Screen>
      <Title>{t("wte.title")}</Title>
      <Small>{t("wte.subtitle")}</Small>
      <Spacer size={spacing.sm} />

      {/* Sök bland recept (fungerar i alla flikar, söker på namn). */}
      <Input
        placeholder={t("wte.searchPlaceholder")}
        value={searchText}
        onChangeText={setSearchText}
        onSubmitEditing={() => submitSearch(searchText)}
        returnKeyType="search"
        autoCorrect={false}
      />

      {/* Aktuella högtider/säsonger – snabbknappar direkt under sökrutan. */}
      {query.data && query.data.context.activeHolidays.length > 0 && (
        <>
          <Spacer size={spacing.xs} />
          <Row style={{ flexWrap: "wrap" }}>
            {query.data.context.activeHolidays.map((h) => {
              // Säsongsnamn på användarens språk; fallback till serverns namn (egennamn m.m.).
              const name = t(`season.${h.slug}`, { defaultValue: h.name });
              return (
                <Pressable key={h.slug} onPress={() => selectHoliday(h.slug)}>
                  <Tag label={`🎉 ${name}`} tone={holiday === h.slug ? "success" : "accent"} />
                </Pressable>
              );
            })}
          </Row>
        </>
      )}
      <Spacer size={spacing.sm} />

      {/* Kategori-flikar med enhetliga rutor (2 kolumner). Filtrerar in-place. */}
      <Row style={{ flexWrap: "wrap", justifyContent: "space-between" }}>
        <Button
          label={`🍽️ ${t("wte.recommended")}`}
          variant={cat === null ? "secondary" : "ghost"}
          onPress={() => selectCat(null)}
          style={{ width: "48%", marginBottom: spacing.xs }}
        />
        {CATS.map((c) => (
          <Button
            key={c.key}
            label={`${c.glyph} ${c.labelKey ? t(c.labelKey as never) : (c.label ?? "")}`}
            variant={cat === c.key ? "secondary" : "ghost"}
            onPress={() => selectCat(c.key)}
            style={{ width: "48%", marginBottom: spacing.xs }}
          />
        ))}
      </Row>
      <Spacer size={spacing.sm} />

      {query.isLoading && <LoadingView />}
      {query.isError && (
        <ErrorView message={errText(query.error)} onRetry={() => void query.refetch()} />
      )}

      {query.data && (
        <>
          {cat === null &&
            !submittedSearch &&
            !holiday &&
            query.data.mealBoxSuggestions.length > 0 && (
              <>
                <Heading>{t("wte.mealBoxFirst")}</Heading>
                {query.data.mealBoxSuggestions.map((box) => (
                  <Card key={box.mealBoxId} onPress={() => router.push("/meal-boxes")}>
                    <Row style={{ justifyContent: "space-between" }}>
                      <Body>🍱 {box.title ?? box.titleSv}</Body>
                      <Tag
                        label={t("mealbox.portionsLeft", { count: box.portionsRemaining })}
                        tone="success"
                      />
                    </Row>
                    <Small>
                      {t(box.useByUrgent ? "mealbox.eatBy" : "mealbox.ready", {
                        date: box.recommendedUseBy,
                      })}
                    </Small>
                  </Card>
                ))}
                <Spacer size={spacing.sm} />
              </>
            )}

          {allRecs.length === 0 && (
            <EmptyState
              text={
                submittedSearch
                  ? t("wte.emptySearch")
                  : holiday
                    ? t("wte.emptyHoliday")
                    : t("wte.empty")
              }
            />
          )}

          {/* "Menade du …?" – stavningsförslag när sök gav noll träffar. */}
          {allRecs.length === 0 && submittedSearch && query.data.context.searchSuggestion && (
            <Pressable onPress={() => submitSearch(query.data!.context.searchSuggestion!)}>
              <Tag
                label={t("wte.didYouMean", { suggestion: query.data.context.searchSuggestion })}
                tone="accent"
              />
            </Pressable>
          )}

          {shownRecs.map((rec, index) => (
            <Card key={rec.recipeId} onPress={() => router.push(`/recipe/${rec.recipeId}`)}>
              <Row style={{ justifyContent: "space-between", alignItems: "center" }}>
                <Heading>{rec.title ?? rec.titleSv}</Heading>
                {page === 0 && index === 0 && !submittedSearch && !holiday && (
                  <Tag label={t("wte.topPick")} tone="accent" />
                )}
              </Row>
              <Row>
                {rec.ratingCount > 0 && rec.ratingAverage != null && (
                  <Tag
                    label={`★ ${new Intl.NumberFormat(getLanguageTag(), {
                      minimumFractionDigits: 1,
                      maximumFractionDigits: 1,
                    }).format(rec.ratingAverage)} · ${rec.ratingCount}`}
                    tone="accent"
                  />
                )}
                <Tag
                  label={t("wte.coverage", { pct: rec.coveragePercent })}
                  tone={rec.coveragePercent >= 80 ? "success" : "neutral"}
                />
                {rec.usesExpiring.slice(0, 2).map((item) => (
                  <Tag key={item.nameSv} label={`⏳ ${item.name ?? item.nameSv}`} tone="warning" />
                ))}
              </Row>
              <View
                style={{
                  backgroundColor: colors.surfaceAlt,
                  borderRadius: 10,
                  padding: spacing.sm,
                  marginTop: spacing.xs,
                }}
              >
                <Small>💡 {rec.whySv}</Small>
              </View>
              {rec.missingIngredients.length > 0 && (
                <Small>
                  {t("wte.missing", { items: rec.missingIngredients.slice(0, 4).join(", ") })}
                </Small>
              )}
            </Card>
          ))}

          {allRecs.length > 5 && (
            <>
              <Spacer size={spacing.sm} />
              <Button
                label={t("wte.refresh")}
                variant="secondary"
                loading={query.isFetching}
                onPress={() => setPage((p) => p + 1)}
              />
            </>
          )}
        </>
      )}
    </Screen>
  );
}
