import { MaterialCommunityIcons } from "@expo/vector-icons";
import { router } from "expo-router";
import { useCallback, useEffect, useState } from "react";
import { Text, TouchableOpacity, View } from "react-native";

import { RatingSheet } from "@/components/rating-sheet";
import { fetchAPI } from "@/lib/fetch";
import { useT } from "@/lib/i18n";

// Home-screen banner for unfinished business. Two things can be unfinished
// after the rider leaves the tracking screen:
//
//   * a ride still in flight — before this, killing the app mid-ride stranded
//     the rider with no route back to their driver, since home only lists
//     completed history;
//   * a finished ride they never rated — the prompt is easy to miss when the
//     app is backgrounded the moment the door closes.
//
// Both are recoverable from one poll, so they share one banner.

const POLL_MS = 15000;

type ActiveRide = {
  ride_id: number;
  status: string;
  service: string;
  destination_address: string;
  driver_name: string | null;
};

type PendingRating = {
  ride_id: number;
  destination_address: string;
  driver_name: string | null;
  driver_avatar: string | null;
};

const STATUS_KEY: Record<string, string> = {
  requested: "bookRide.status.requested",
  accepted: "bookRide.status.accepted",
  arrived: "bookRide.status.arrived",
  en_route: "bookRide.status.enRoute",
};

export const ActiveRideBanner = () => {
  const t = useT();
  const [active, setActive] = useState<ActiveRide | null>(null);
  const [pending, setPending] = useState<PendingRating | null>(null);
  const [ratingOpen, setRatingOpen] = useState(false);
  const [dismissed, setDismissed] = useState<number[]>([]);

  const load = useCallback(async () => {
    try {
      const res = await fetchAPI("/(api)/ride/active");
      setActive(res.data?.active ?? null);
      setPending(res.data?.pending_rating ?? null);
    } catch (err) {
      // A signed-out or offline home screen simply shows no banner.
      console.log("[ACTIVE_RIDE_BANNER]: ", err);
    }
  }, []);

  useEffect(() => {
    void load();
    const timer = setInterval(() => void load(), POLL_MS);
    return () => clearInterval(timer);
  }, [load]);

  if (active) {
    return (
      <TouchableOpacity
        onPress={() =>
          router.push({
            pathname: "/(root)/book-ride",
            params: { id: String(active.ride_id) },
          })
        }
        className="bg-primary-500 rounded-2xl p-4 mb-4 flex-row items-center"
      >
        <View className="flex-1">
          <Text className="text-white/80 text-xs font-JakartaMedium">
            {STATUS_KEY[active.status]
              ? t(STATUS_KEY[active.status])
              : active.status}
          </Text>
          <Text
            className="text-white font-JakartaBold mt-0.5"
            numberOfLines={1}
          >
            {active.driver_name
              ? t("home.activeRideWithDriver", { name: active.driver_name })
              : active.destination_address}
          </Text>
        </View>
        <MaterialCommunityIcons name="chevron-right" size={24} color="white" />
      </TouchableOpacity>
    );
  }

  if (pending && !dismissed.includes(pending.ride_id)) {
    return (
      <>
        <View className="bg-white dark:bg-neutral-900 rounded-2xl p-4 mb-4 flex-row items-center">
          <View className="flex-1">
            <Text className="text-general-200 dark:text-neutral-400 text-xs font-JakartaMedium">
              {t("home.rateLastRide")}
            </Text>
            <Text
              className="text-black dark:text-white font-JakartaBold mt-0.5"
              numberOfLines={1}
            >
              {pending.destination_address}
            </Text>
          </View>
          <TouchableOpacity
            onPress={() => setRatingOpen(true)}
            className="bg-primary-500 rounded-full px-4 py-2 ml-3"
          >
            <Text className="text-white font-JakartaBold text-xs">
              {t("home.rate")}
            </Text>
          </TouchableOpacity>
        </View>

        <RatingSheet
          visible={ratingOpen}
          rideId={pending.ride_id}
          audience="rider"
          subjectName={pending.driver_name}
          subjectAvatar={pending.driver_avatar}
          onDone={() => {
            setRatingOpen(false);
            setDismissed((prev) => [...prev, pending.ride_id]);
            void load();
          }}
          onSkip={() => {
            setRatingOpen(false);
            setDismissed((prev) => [...prev, pending.ride_id]);
          }}
        />
      </>
    );
  }

  return null;
};
