import { MaterialCommunityIcons } from "@expo/vector-icons";
import { router } from "expo-router";
import { useCallback, useEffect, useState } from "react";
import {
  ActivityIndicator,
  Alert,
  Image,
  ScrollView,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";

import { CustomButton } from "@/components/custom-button";
import { icons, images } from "@/constants";
import { SERVICES, type ServiceId } from "@/constants/services";
import { ApiError, fetchAPI } from "@/lib/fetch";
import { useT } from "@/lib/i18n";
import { useSession } from "@/lib/session";
import { useTheme } from "@/lib/theme";
import { useDriverLocation } from "@/lib/use-driver-location";
import { formatTime } from "@/lib/utils";

// Poll cadence for the driver dashboard (offers / active ride / earnings).
const POLL_MS = 4000;

type Profile = {
  id: number;
  first_name: string;
  last_name: string;
  profile_image_url: string | null;
  car_image_url: string | null;
  car_seats: number;
  rating: number;
  service: ServiceId;
  online: boolean;
  car_model: string | null;
};

type Offer = {
  offer_id: number;
  offered_at: string;
  ride_id: number;
  origin_address: string;
  destination_address: string;
  ride_time: number;
  fare_price: number;
  payment_status: string;
  service: string;
};

type ActiveRide = {
  ride_id: number;
  status: string;
  service: string;
  payment_status: string;
  origin_address: string;
  destination_address: string;
  ride_time: number;
  fare_price: number;
  rider_name: string | null;
  rider_phone: string | null;
};

type Dashboard = {
  offers: Offer[];
  active: ActiveRide | null;
  recent: { ride_id: number; fare_price: number; service: string }[];
  earnings: number;
};

const DriverHome = () => {
  const { signOut, user } = useSession();
  const { isDark } = useTheme();
  const t = useT();
  const [loading, setLoading] = useState(true);
  const [profile, setProfile] = useState<Profile | null>(null);
  const [online, setOnline] = useState(false);
  const [dashboard, setDashboard] = useState<Dashboard | null>(null);
  const [busy, setBusy] = useState(false);

  const loadProfile = useCallback(async () => {
    try {
      const res = await fetchAPI("/(api)/driver/profile");
      const p = res.data as Profile;
      setProfile(p);
      setOnline(p.online);
    } catch (err) {
      // 403 with code ONBOARD means no profile yet — show the onboarding form.
      if (err instanceof ApiError && err.status === 403) {
        setProfile(null);
      } else {
        console.log("[DRIVER_PROFILE_LOAD]: ", err);
      }
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void loadProfile();
  }, [loadProfile]);

  // Keep the location heartbeat running only while the driver is online and
  // has completed onboarding.
  useDriverLocation(online && profile !== null);

  // Poll the dashboard while online. useCallback keeps the fetcher stable so the
  // interval effect doesn't re-subscribe on every render.
  const fetchDashboard = useCallback(async () => {
    try {
      const res = await fetchAPI("/(api)/driver/rides");
      setDashboard(res.data as Dashboard);
    } catch (err) {
      console.log("[DRIVER_DASHBOARD_POLL]: ", err);
    }
  }, []);

  useEffect(() => {
    if (!online || !profile) return;
    void fetchDashboard();
    const timer = setInterval(() => void fetchDashboard(), POLL_MS);
    return () => clearInterval(timer);
  }, [online, profile, fetchDashboard]);

  const toggleOnline = async () => {
    if (!profile) return;
    const next = !online;
    setBusy(true);
    try {
      await fetchAPI("/(api)/driver/profile", {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ online: next }),
      });
      setOnline(next);
      setProfile({ ...profile, online: next });
      if (!next) setDashboard(null);
    } catch (err) {
      console.log("[DRIVER_TOGGLE]: ", err);
      Alert.alert(t("driver.home.alertErrorTitle"), t("driver.home.alertToggleBody"));
    } finally {
      setBusy(false);
    }
  };

  const respond = async (offer: Offer, action: "accept" | "decline") => {
    setBusy(true);
    try {
      await fetchAPI(`/(api)/ride/${offer.ride_id}/respond`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ action }),
      });
      await fetchDashboard();
    } catch (err) {
      console.log("[DRIVER_RESPOND]: ", err);
      Alert.alert(
        t("driver.activeRide.alertErrorTitle"),
        action === "accept"
          ? t("driver.activeRide.alertAcceptBody")
          : t("driver.activeRide.alertDeclineBody"),
      );
    } finally {
      setBusy(false);
    }
  };

  const advance = async (rideId: number, status: "en_route" | "completed") => {
    setBusy(true);
    try {
      await fetchAPI(`/(api)/ride/${rideId}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ status }),
      });
      await fetchDashboard();
    } catch (err) {
      console.log("[DRIVER_ADVANCE]: ", err);
      Alert.alert(t("driver.activeRide.alertErrorTitle"), t("driver.activeRide.alertUpdateBody"));
    } finally {
      setBusy(false);
    }
  };

  if (loading) {
    return (
      <SafeAreaView className="flex-1 bg-white dark:bg-neutral-950 items-center justify-center">
        <ActivityIndicator size="large" color={isDark ? "#0286ff" : "#0286ff"} />
      </SafeAreaView>
    );
  }

  if (!profile) {
    return (
      <Onboarding onCreated={loadProfile} signOut={signOut} userName={user?.name} />
    );
  }

  const earnings = dashboard?.earnings ?? 0;
  const rideCount = dashboard?.recent.length ?? 0;

  return (
    <SafeAreaView className="flex-1 bg-general-500 dark:bg-neutral-950">
      <ScrollView
        className="flex-1 px-5"
        contentContainerStyle={{ paddingBottom: 40 }}
      >
        <View className="flex-row items-center justify-between my-5">
          <Text className="text-2xl font-JakartaExtraBold text-black dark:text-white">
            {t("driver.home.driverMode")}
          </Text>
          <TouchableOpacity
            onPress={signOut}
            className="w-10 h-10 rounded-full bg-white dark:bg-neutral-900 items-center justify-center"
          >
            <Image source={icons.out} className="w-4 h-4" alt={t("driver.home.signOutAlt")} />
          </TouchableOpacity>
        </View>

        {/* Online / offline toggle */}
        <TouchableOpacity
          onPress={toggleOnline}
          disabled={busy}
          className={`rounded-2xl p-5 items-center mb-4 ${
            online ? "bg-emerald-500" : "bg-neutral-700 dark:bg-neutral-800"
          }`}
        >
          <Text className="text-white text-lg font-JakartaBold">
            {online ? t("driver.home.online") : t("driver.home.goOnline")}
          </Text>
        </TouchableOpacity>

        {/* Earnings summary */}
        <View className="bg-white dark:bg-neutral-900 rounded-2xl p-4 mb-4 flex-row justify-between">
          <View>
            <Text className="text-general-200 dark:text-neutral-400 text-xs font-JakartaMedium">
              {t("driver.home.todaysEarnings")}
            </Text>
            <Text className="text-2xl font-JakartaExtraBold text-black dark:text-white">
              ${(earnings / 100).toFixed(2)}
            </Text>
          </View>
          <View className="items-end">
            <Text className="text-general-200 dark:text-neutral-400 text-xs font-JakartaMedium">
              {t("driver.home.completedToday")}
            </Text>
            <Text className="text-2xl font-JakartaExtraBold text-black dark:text-white">{rideCount}</Text>
          </View>
        </View>

        {/* Active ride */}
        {dashboard?.active ? (
          <ActiveRideCard
            ride={dashboard.active}
            busy={busy}
            onAdvance={advance}
          />
        ) : null}

        {/* Incoming offers */}
        <Text className="text-xl font-JakartaBold mt-4 mb-3 text-black dark:text-white">
          {online
            ? t("driver.home.incomingRequests")
            : t("driver.home.incomingRequestsOffline")}
        </Text>

        {!online ? null : dashboard?.offers.length ? (
          dashboard.offers.map((offer) => (
            <OfferCard
              key={offer.offer_id}
              offer={offer}
              busy={busy}
              onAccept={() => respond(offer, "accept")}
              onDecline={() => respond(offer, "decline")}
            />
          ))
        ) : (
          <View className="bg-white dark:bg-neutral-900 rounded-2xl p-6 items-center">
            <Image source={images.noResult} className="w-24 h-24" resizeMode="contain" />
            <Text className="text-general-200 dark:text-neutral-400 mt-2">
              {online ? t("driver.home.waitingRequests") : t("driver.home.goOnlineStart")}
            </Text>
          </View>
        )}
      </ScrollView>
    </SafeAreaView>
  );
};

// --- Onboarding form ------------------------------------------------------

const Onboarding = ({
  onCreated,
  signOut,
  userName,
}: {
  onCreated: () => Promise<void>;
  signOut: () => Promise<void>;
  userName?: string | null;
}) => {
  const t = useT();
  const { isDark } = useTheme();
  const [service, setService] = useState<ServiceId>("car");
  const [carModel, setCarModel] = useState("");
  const [carSeats, setCarSeats] = useState("4");
  const [submitting, setSubmitting] = useState(false);

  const submit = async () => {
    const seats = Number(carSeats);
    if (!Number.isInteger(seats) || seats < 1 || seats > 8) {
      Alert.alert(t("driver.home.alertSeatsTitle"), t("driver.home.alertSeatsBody"));
      return;
    }
    setSubmitting(true);
    try {
      await fetchAPI("/(api)/driver/profile", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          service,
          car_model: carModel.trim() || null,
          car_seats: seats,
        }),
      });
      await onCreated();
    } catch (err) {
      console.log("[DRIVER_ONBOARD]: ", err);
      Alert.alert(t("driver.home.alertErrorTitle"), t("driver.home.alertCreateBody"));
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <SafeAreaView className="flex-1 bg-white dark:bg-neutral-950">
      <ScrollView className="flex-1 px-5" contentContainerStyle={{ paddingBottom: 40 }}>
        <View className="flex-row items-center justify-between my-5">
          <Text className="text-2xl font-JakartaExtraBold text-black dark:text-white">
            {t("driver.home.welcome", {
              name: userName?.split(" ")[0] || t("driver.home.welcomeFallback"),
            })}
          </Text>
          <TouchableOpacity
            onPress={signOut}
            className="w-10 h-10 rounded-full bg-neutral-100 dark:bg-neutral-900 items-center justify-center"
          >
            <Image source={icons.out} className="w-4 h-4" alt={t("driver.home.signOutAlt")} />
          </TouchableOpacity>
        </View>

        <Text className="text-base text-general-200 dark:text-neutral-400 font-Jakarta mb-4">
          {t("driver.home.setupIntro")}
        </Text>

        <Text className="text-lg font-JakartaSemiBold mb-3 text-black dark:text-white">
          {t("driver.home.whatDrive")}
        </Text>
        <View className="flex-row gap-2 mb-5">
          {SERVICES.map((item) => {
            const active = item.id === service;
            return (
              <TouchableOpacity
                key={item.id}
                onPress={() => setService(item.id)}
                className={`flex-1 items-center rounded-2xl border py-3 ${
                  active
                    ? "border-primary-500 bg-primary-500/10"
                    : "border-neutral-100 dark:border-neutral-800 bg-neutral-100 dark:bg-neutral-900"
                }`}
              >
                <MaterialCommunityIcons
                  name={item.icon}
                  size={24}
                  color={active ? "#0286ff" : isDark ? "#9ca3af" : "#858585"}
                />
                <Text
                  className={`mt-1.5 text-xs font-JakartaBold ${
                    active ? "text-primary-500" : "text-black dark:text-white"
                  }`}
                >
                  {t(item.labelKey)}
                </Text>
              </TouchableOpacity>
            );
          })}
        </View>

        <Text className="text-lg font-JakartaSemiBold mb-3 text-black dark:text-white">
          {t("driver.home.carModel")}
        </Text>
        <TextInput
          value={carModel}
          onChangeText={setCarModel}
          placeholder={t("driver.home.carModelPlaceholder")}
          placeholderTextColor={isDark ? "#737373" : "#858585"}
          className="bg-neutral-100 dark:bg-neutral-900 text-black dark:text-white rounded-full px-4 py-4 font-JakartaSemiBold text-[15px] mb-4"
          autoCapitalize="words"
        />

        <Text className="text-lg font-JakartaSemiBold mb-3 text-black dark:text-white">
          {t("driver.home.carSeats")}
        </Text>
        <TextInput
          value={carSeats}
          onChangeText={setCarSeats}
          placeholder={t("driver.home.carSeatsPlaceholder")}
          placeholderTextColor={isDark ? "#737373" : "#858585"}
          keyboardType="number-pad"
          className="bg-neutral-100 dark:bg-neutral-900 text-black dark:text-white rounded-full px-4 py-4 font-JakartaSemiBold text-[15px] mb-8"
        />

        <CustomButton
          title={submitting ? t("common.saving") : t("driver.home.startDriving")}
          onPress={submit}
          disabled={submitting}
        />
      </ScrollView>
    </SafeAreaView>
  );
};

// --- Offer card -----------------------------------------------------------

const OfferCard = ({
  offer,
  busy,
  onAccept,
  onDecline,
}: {
  offer: Offer;
  busy: boolean;
  onAccept: () => void;
  onDecline: () => void;
}) => {
  const t = useT();
  return (
    <View className="bg-white dark:bg-neutral-900 rounded-2xl p-4 mb-3">
      <View className="flex-row items-center justify-between mb-2">
        <Text className="text-sm font-JakartaBold text-primary-500">
          {t("driver.offerCard.newRequest", { service: offer.service })}
        </Text>
        <Text className="text-xs text-general-200 dark:text-neutral-400">
          {offer.payment_status === "cash"
            ? t("driver.offerCard.cash")
            : t("driver.offerCard.card")}
        </Text>
      </View>

      <View className="flex-row items-center gap-x-2 mb-1">
        <Image source={icons.to} alt={t("driver.offerCard.fromAlt")} className="w-4 h-4" />
        <Text className="font-JakartaMedium text-black dark:text-white" numberOfLines={1}>
          {offer.origin_address}
        </Text>
      </View>
      <View className="flex-row items-center gap-x-2 mb-3">
        <Image source={icons.point} alt={t("driver.offerCard.toAlt")} className="w-4 h-4" />
        <Text className="font-JakartaMedium text-black dark:text-white" numberOfLines={1}>
          {offer.destination_address}
        </Text>
      </View>

      <View className="flex-row justify-between mb-3">
        <Text className="text-general-200 dark:text-neutral-400 text-xs">
          {t("driver.offerCard.tripTime")}
        </Text>
        <Text className="font-JakartaMedium text-xs text-black dark:text-white">
          {formatTime(offer.ride_time)}
        </Text>
      </View>
      <View className="flex-row justify-between mb-3">
        <Text className="text-general-200 dark:text-neutral-400 text-xs">
          {t("driver.offerCard.fare")}
        </Text>
        <Text className="font-JakartaMedium text-xs text-emerald-600 dark:text-emerald-400">
          ${(offer.fare_price / 100).toFixed(2)}
        </Text>
      </View>

      <View className="flex-row gap-3">
        <TouchableOpacity
          onPress={onDecline}
          disabled={busy}
          className="flex-1 rounded-full py-3 bg-neutral-200 dark:bg-neutral-800 items-center"
        >
          <Text className="font-JakartaBold text-neutral-700 dark:text-neutral-200">
            {t("driver.offerCard.decline")}
          </Text>
        </TouchableOpacity>
        <TouchableOpacity
          onPress={onAccept}
          disabled={busy}
          className="flex-1 rounded-full py-3 bg-emerald-500 items-center"
        >
          <Text className="font-JakartaBold text-white">
            {busy ? "…" : t("driver.offerCard.accept")}
          </Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};

// --- Active ride card -----------------------------------------------------

const ActiveRideCard = ({
  ride,
  busy,
  onAdvance,
}: {
  ride: ActiveRide;
  busy: boolean;
  onAdvance: (rideId: number, status: "en_route" | "completed") => void;
}) => {
  const t = useT();
  const statusLabel =
    ride.status === "accepted"
      ? t("driver.activeRide.headToPickup")
      : ride.status === "en_route"
        ? t("driver.activeRide.tripInProgress")
        : ride.status;

  return (
    <View className="bg-primary-500/10 border border-primary-500 rounded-2xl p-4 mb-4">
      <View className="flex-row items-center justify-between mb-2">
        <Text className="text-sm font-JakartaBold text-primary-500">
          ● {statusLabel}
        </Text>
        <Text className="text-xs text-general-200 dark:text-neutral-400">{ride.service}</Text>
      </View>

      {ride.rider_name ? (
        <Text className="font-JakartaBold mb-2 text-black dark:text-white">
          {t("driver.activeRide.rider", { name: ride.rider_name })}
        </Text>
      ) : null}

      <View className="flex-row items-center gap-x-2 mb-1">
        <Image source={icons.to} alt={t("driver.activeRide.fromAlt")} className="w-4 h-4" />
        <Text className="font-JakartaMedium text-black dark:text-white" numberOfLines={1}>
          {ride.origin_address}
        </Text>
      </View>
      <View className="flex-row items-center gap-x-2 mb-3">
        <Image source={icons.point} alt={t("driver.activeRide.toAlt")} className="w-4 h-4" />
        <Text className="font-JakartaMedium text-black dark:text-white" numberOfLines={1}>
          {ride.destination_address}
        </Text>
      </View>

      <View className="flex-row justify-between mb-4">
        <Text className="text-general-200 dark:text-neutral-400 text-xs">
          {t("driver.activeRide.fare")}
        </Text>
        <Text className="font-JakartaMedium text-xs text-emerald-600 dark:text-emerald-400">
          ${(ride.fare_price / 100).toFixed(2)}
        </Text>
      </View>

      {ride.status === "accepted" ? (
        <CustomButton
          title={busy ? "…" : t("driver.activeRide.startTrip")}
          bgVariant="success"
          onPress={() => onAdvance(ride.ride_id, "en_route")}
          className="mb-2"
        />
      ) : null}
      {ride.status === "en_route" ? (
        <CustomButton
          title={busy ? "…" : t("driver.activeRide.completeTrip")}
          bgVariant="success"
          onPress={() => onAdvance(ride.ride_id, "completed")}
        />
      ) : null}
    </View>
  );
};

export default DriverHome;