import React from "react";
import {
  View,
  Text,
  FlatList,
  Image,
  ScrollView,
  TouchableOpacity,
} from "react-native";
import { router } from "expo-router";
import { ROUTES } from "~/lib/routes";
import TransactionCard from "~/components/ui/transactionCard";
import { useAuthWithProfile } from "~/lib/hooks/useAuthWithProfile";
import { useTransactions } from "~/lib/hooks/useTransactions";
import ScreenWrapper from "~/components/ui/ScreenWrapper";
import { Icons } from "~/assets/icons";
import { Input } from "~/components/ui/input";
import Skeleton from "~/components/ui/skeleton";
import BottomSheet from "~/components/ui/bottomSheet";
import ModalToast from "~/components/ui/toast";
import { useTranslation } from "react-i18next";
import BackButton from "~/components/ui/backButton";

type TransactionTypeFilter = "all" | "incoming" | "outgoing";

interface DateRange {
  startDate: Date | null;
  endDate: Date | null;
}

const daysOfWeek = ["S", "M", "T", "W", "T", "F", "S"];

const stripTime = (date: Date) => {
  const d = new Date(date);
  d.setHours(0, 0, 0, 0);
  return d;
};

const isSameDay = (a: Date | null, b: Date | null) => {
  if (!a || !b) return false;
  return (
    a.getFullYear() === b.getFullYear() &&
    a.getMonth() === b.getMonth() &&
    a.getDate() === b.getDate()
  );
};

const SimpleCalendarRange: React.FC<{
  value: DateRange;
  onChange: (range: DateRange) => void;
}> = ({ value, onChange }) => {
  const initialBase = value.startDate || new Date();
  const [currentMonth, setCurrentMonth] = React.useState(
    () => new Date(initialBase.getFullYear(), initialBase.getMonth(), 1)
  );

  const monthLabel = currentMonth.toLocaleString("default", {
    month: "short",
    year: "numeric",
  });

  const days: (Date | null)[] = React.useMemo(() => {
    const year = currentMonth.getFullYear();
    const month = currentMonth.getMonth();
    const firstDayOfMonth = new Date(year, month, 1);
    const firstWeekday = firstDayOfMonth.getDay();
    const numDays = new Date(year, month + 1, 0).getDate();

    const arr: (Date | null)[] = [];
    for (let i = 0; i < firstWeekday; i++) {
      arr.push(null);
    }
    for (let d = 1; d <= numDays; d++) {
      arr.push(new Date(year, month, d));
    }
    return arr;
  }, [currentMonth]);

  const handleSelectDay = (day: Date) => {
    const { startDate, endDate } = value;

    if (!startDate || (startDate && endDate)) {
      onChange({ startDate: stripTime(day), endDate: null });
      return;
    }

    const start = stripTime(startDate);
    const selected = stripTime(day);

    if (selected < start) {
      onChange({ startDate: selected, endDate: start });
    } else {
      onChange({ startDate: start, endDate: selected });
    }
  };

  const inRange = (day: Date) => {
    const { startDate, endDate } = value;
    if (!startDate || !endDate) return false;
    const d = stripTime(day);
    const s = stripTime(startDate);
    const e = stripTime(endDate);
    return d > s && d < e;
  };

  const goMonth = (offset: number) => {
    setCurrentMonth(
      (prev) => new Date(prev.getFullYear(), prev.getMonth() + offset, 1)
    );
  };

  return (
    <View className="mt-3">
      <View className="flex-row justify-between items-center mb-3">
        <TouchableOpacity
          onPress={() => goMonth(-1)}
          className="w-10 h-10 rounded-full bg-white items-center justify-center"
        >
          <Text className="text-sm font-dmsans">{"<"}</Text>
        </TouchableOpacity>
        <Text className="text-sm font-dmsans-medium text-black">
          {monthLabel}
        </Text>
        <TouchableOpacity
          onPress={() => goMonth(1)}
          className="w-10 h-10 rounded-full bg-white items-center justify-center"
        >
          <Text className="text-sm font-dmsans">{">"}</Text>
        </TouchableOpacity>
      </View>

      <View className="flex-row mb-1">
        {daysOfWeek.map((d, idx) => (
          <View
            key={`${d}-${idx}`}
            style={{ width: `${100 / 7}%` }}
            className="items-center"
          >
            <Text className="text-[10px] text-gray-400 font-dmsans">{d}</Text>
          </View>
        ))}
      </View>

      <View className="flex-row flex-wrap">
        {days.map((day, index) => {
          if (!day) {
            return (
              <View
                key={index}
                style={{ width: `${100 / 7}%`, aspectRatio: 1 }}
              />
            );
          }

          const selectedStart = isSameDay(day, value.startDate);
          const selectedEnd = isSameDay(day, value.endDate);
          const between = inRange(day);

          const isSelected = selectedStart || selectedEnd;
          const bgColor = isSelected
            ? "#0F7B4A"
            : between
            ? "rgba(15,123,74,0.08)"
            : "transparent";
          const textColor = isSelected ? "#ffffff" : "#111827";

          return (
            <TouchableOpacity
              key={index}
              onPress={() => handleSelectDay(day)}
              style={{ width: `${100 / 7}%`, aspectRatio: 1 }}
              className="items-center justify-center"
            >
              <View
                style={{
                  width: 32,
                  height: 32,
                  borderRadius: 16,
                  backgroundColor: bgColor,
                  alignItems: "center",
                  justifyContent: "center",
                }}
              >
                <Text
                  style={{ color: textColor, fontSize: 12 }}
                  className="font-dmsans"
                >
                  {day.getDate()}
                </Text>
              </View>
            </TouchableOpacity>
          );
        })}
      </View>
    </View>
  );
};

export default function History() {
  const { user } = useAuthWithProfile();
  const {
    transactions,
    loading: transactionsLoading,
    error: transactionsError,
  } = useTransactions(user?.uid);
  const { t } = useTranslation();
  const [searchQuery, setSearchQuery] = React.useState("");
  const [filterVisible, setFilterVisible] = React.useState(false);
  const [dateRange, setDateRange] = React.useState<DateRange>({
    startDate: null,
    endDate: null,
  });
  const [typeFilter, setTypeFilter] =
    React.useState<TransactionTypeFilter>("all");

  const [toastVisible, setToastVisible] = React.useState(false);
  const [toastTitle, setToastTitle] = React.useState("");
  const [toastDescription, setToastDescription] = React.useState<
    string | undefined
  >(undefined);
  const [toastVariant, setToastVariant] = React.useState<
    "success" | "error" | "warning" | "info"
  >("info");
  const toastTimeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(
    null
  );

  const showToast = (
    title: string,
    description?: string,
    variant: "success" | "error" | "warning" | "info" = "info"
  ) => {
    if (toastTimeoutRef.current) {
      clearTimeout(toastTimeoutRef.current);
    }

    setToastTitle(title);
    setToastDescription(description);
    setToastVariant(variant);
    setToastVisible(true);

    toastTimeoutRef.current = setTimeout(() => {
      setToastVisible(false);
      toastTimeoutRef.current = null;
    }, 2500);
  };

  React.useEffect(() => {
    return () => {
      if (toastTimeoutRef.current) {
        clearTimeout(toastTimeoutRef.current);
      }
    };
  }, []);

  React.useEffect(() => {
    if (transactionsError) {
      showToast(
        t("history.toastErrorTitle"),
        transactionsError || t("history.errorTitle"),
        "error"
      );
    }
  }, [transactionsError, t]);

  const filteredTransactions = React.useMemo(() => {
    let data = transactions || [];

    const query = searchQuery.trim().toLowerCase();
    if (query) {
      data = data.filter((t) => {
        const parts: string[] = [];
        if ((t as any).recipientName)
          parts.push(String((t as any).recipientName));
        if ((t as any).senderName) parts.push(String((t as any).senderName));
        if ((t as any).note) parts.push(String((t as any).note));
        parts.push(String(t.type));
        const haystack = parts.join(" ").toLowerCase();
        return haystack.includes(query);
      });
    }

    if (dateRange.startDate || dateRange.endDate) {
      const start = dateRange.startDate ? stripTime(dateRange.startDate) : null;
      const end = dateRange.endDate ? stripTime(dateRange.endDate) : null;

      data = data.filter((t) => {
        const created =
          t.createdAt instanceof Date
            ? stripTime(t.createdAt)
            : stripTime(new Date(t.createdAt));

        if (start && created < start) return false;
        if (end && created > end) return false;
        return true;
      });
    }

    if (typeFilter !== "all") {
      data = data.filter((t) => {
        const txType = t.type;
        const isOutgoing = txType === "send" || txType === "cash_out";
        const isIncoming = txType === "receive" || txType === "add_cash";

        if (typeFilter === "outgoing") return isOutgoing;
        if (typeFilter === "incoming") return isIncoming;
        return true;
      });
    }

    return data;
  }, [transactions, searchQuery, dateRange, typeFilter]);

  return (
    <ScreenWrapper edges={["bottom"]}>
      <View className="flex items-center h-full w-full ">
        {transactionsLoading ? (
          <View className="flex items-center justify-center w-full">
            <View className=" ">
              <BackButton />
            </View>
            <View className="flex px-5 space-y-3 w-full">
              <View className="flex flex-col space-y-1 items-left">
                <Text className="text-xl font-dmsans text-primary">
                  {t("history.title")}
                </Text>
                <Text className="text-base font-dmsans text-gray-400">
                  {t("history.subtitle")}
                </Text>
              </View>
              <View className="flex flex-col gap-4 py-4">
                {Array.from({ length: 5 }).map((_, index) => (
                  <View key={index} className="w-full">
                    <Skeleton width="100%" height={72} radius={12} />
                  </View>
                ))}
              </View>
            </View>
          </View>
        ) : transactionsError ? (
          <View className="flex items-center justify-center w-full">
            <View className="">
              <BackButton />
            </View>
            <View className="flex px-5 space-y-3 w-full">
              <View className="flex flex-col space-y-1 py-5 items-left">
                <Text className="text-xl font-dmsans text-primary">
                  {t("history.title")}
                </Text>
                <Text className="text-base font-dmsans text-gray-400">
                  {t("history.subtitle")}
                </Text>
              </View>
              <View className="flex items-center justify-center py-8">
                <Text className="text-red-500 font-dmsans">
                  {t("history.errorTitle")}
                </Text>
                <Text className="text-gray-400 font-dmsans-medium text-sm mt-1 text-center px-4">
                  {transactionsError}
                </Text>
              </View>
            </View>
          </View>
        ) : (
          <>
            <FlatList
              className=""
              data={filteredTransactions}
              keyExtractor={(item) => item.id}
              contentContainerStyle={{ paddingBottom: 30 }}
              ListHeaderComponent={
                <>
                  <View className="w-full mb-2">
                    <BackButton />
                  </View>
                  <View className="flex px-5 space-y-3 w-full pb-6">
                    <View className="flex flex-col space-y-1 py-5 items-left">
                      <Text className="text-xl font-dmsans text-primary">
                        {t("history.title")}
                      </Text>
                      <Text className="text-base font-dmsans text-gray-400">
                        {t("history.subtitle")}
                      </Text>
                    </View>
                    <View className="w-full">
                      <Input
                        value={searchQuery}
                        onChangeText={setSearchQuery}
                        placeholderText={t("history.searchPlaceholder")}
                        containerClassName="w-full"
                        borderClassName="border-[#D9DBE9] bg-white"
                        placeholderColor="#7E7E7E"
                        textClassName="text-[#000] text-sm"
                        rightIcon={
                          <TouchableOpacity
                            onPress={() => setFilterVisible(true)}
                            className="p-1"
                          >
                            <Image
                              source={Icons.filterIcon}
                              style={{
                                width: 25,
                                height: 25,
                                tintColor: "#0F7B4A",
                              }}
                              resizeMode="contain"
                            />
                          </TouchableOpacity>
                        }
                      />
                    </View>
                  </View>
                </>
              }
              ListEmptyComponent={
                <View className="flex items-center justify-center pb-8">
                  <Text className="text-gray-500 font-dmsans">
                    {t("history.emptyTitle")}
                  </Text>
                  <Text className="text-gray-400 font-dmsans-medium text-sm mt-1 text-center px-4">
                    {t("history.emptySubtitle")}
                  </Text>
                </View>
              }
              renderItem={({ item: transaction }) => (
                <View className="px-5">
                  <TransactionCard
                    transaction={transaction}
                    onPress={() => {
                      router.push({
                        pathname: ROUTES.TRANSACTION_DETAIL,
                        params: {
                          transactionId: transaction.id,
                          amount: transaction.amount.toString(),
                          type: transaction.type,
                          recipientName:
                            transaction.type === "send"
                              ? transaction.recipientName
                              : transaction.type === "receive"
                              ? transaction.senderName
                              : transaction.type === "add_cash"
                              ? "Card"
                              : "Bank",
                          date: transaction.createdAt.toISOString(),
                          status: transaction.status,
                          //@ts-ignore
                          note: transaction?.note || "",
                          fromHistory: "true",
                        },
                      });
                    }}
                  />
                </View>
              )}
            />
          </>
        )}
      </View>

      <BottomSheet
        visible={filterVisible}
        onClose={() => setFilterVisible(false)}
        maxHeightRatio={0.9}
      >
        <Text className="text-lg font-dmsans-bold text-black mb-1">
          {t("history.filterTitle")}
        </Text>
        <Text className="text-xs font-dmsans text-gray-500 mb-4">
          {t("history.filterSubtitle")}
        </Text>

        {/* Date range */}
        <Text className="text-base font-dmsans-medium text-black mb-2">
          {t("history.dateRangeLabel")}
        </Text>
        <View className="flex-row justify-between mb-2">
          <View className="flex-1 mr-2">
            <Text className="text-[14px] text-gray-500 font-dmsans mb-1">
              {t("history.fromLabel")}
            </Text>
            <View className="h-9 rounded-[4px] bg-gray-100 px-3 justify-center">
              <Text className="text-xs font-dmsans text-gray-800">
                {dateRange.startDate
                  ? dateRange.startDate.toLocaleDateString()
                  : t("history.selectStart")}
              </Text>
            </View>
          </View>
          <View className="flex-1 ml-2">
            <Text className="text-[14px] text-gray-500 font-dmsans mb-1">
              {t("history.toLabel")}
            </Text>
            <View className="h-9 rounded-[4px] bg-gray-100 px-3 justify-center">
              <Text className="text-xs font-dmsans text-gray-800">
                {dateRange.endDate
                  ? dateRange.endDate.toLocaleDateString()
                  : t("history.selectEnd")}
              </Text>
            </View>
          </View>
        </View>

        <SimpleCalendarRange value={dateRange} onChange={setDateRange} />

        <View className="flex-row justify-end mt-2 mb-4">
          <TouchableOpacity
            onPress={() => setDateRange({ startDate: null, endDate: null })}
          >
            <Text className="text-[14px] text-primary font-dmsans">
              {t("history.clearDates")}
            </Text>
          </TouchableOpacity>
        </View>

        {/* Type filter */}
        <Text className="text-base font-dmsans-medium text-black mb-4 mt-2">
          {t("history.typeLabel")}
        </Text>
        <View className="flex-row mb-6">
          {(
            [
              { label: t("history.typeAll"), value: "all" },
              { label: t("history.typeIncoming"), value: "incoming" },
              { label: t("history.typeOutgoing"), value: "outgoing" },
            ] as { label: string; value: TransactionTypeFilter }[]
          ).map((option) => {
            const active = typeFilter === option.value;
            return (
              <TouchableOpacity
                key={option.value}
                onPress={() => setTypeFilter(option.value)}
                className={`px-4 py-2 rounded-[4px] mr-2 border ${
                  active
                    ? "bg-primary border-primary"
                    : "bg-white border-gray-200"
                }`}
              >
                <Text
                  className={`text-sm font-dmsans-medium ${
                    active ? "text-white" : "text-gray-700"
                  }`}
                >
                  {option.label}
                </Text>
              </TouchableOpacity>
            );
          })}
        </View>

        <View className="w-full mt-2">
          <TouchableOpacity
            onPress={() => setFilterVisible(false)}
            className="h-11 rounded-3xl bg-[#FFB668] items-center justify-center"
          >
            <Text className="text-white font-dmsans-bold text-sm">
              {t("history.applyFilters")}
            </Text>
          </TouchableOpacity>
        </View>
      </BottomSheet>
      <ModalToast
        visible={toastVisible}
        title={toastTitle}
        description={toastDescription}
        variant={toastVariant}
      />
    </ScreenWrapper>
  );
}
