import React, { useState } from "react";
import {
  View,
  ScrollView,
  Pressable,
  PermissionsAndroid,
  Platform,
  ActivityIndicator,
} from "react-native";
import { Text } from "@/components/ui/text";
import { Card } from "@/components/ui/card";
import { ScreenWrapper } from "@/components/ScreenWrapper";
import { toast } from "@/lib/toast-store";
import { ArrowLeft, MessageSquare, RefreshCw } from "@/lib/icons";
import { useColorScheme } from "nativewind";
import { useSirouRouter } from "@sirou/react-native";
import { AppRoutes } from "@/lib/routes";

// Installed via: npm install react-native-get-sms-android --legacy-peer-deps
// Android only — iOS does not permit reading SMS
let SmsAndroid: any = null;
try {
  const smsModule = require("react-native-get-sms-android");
  SmsAndroid = smsModule.default || smsModule;
} catch (e) {
  console.log("[SMS] Module require failed:", e);
}

// Keywords to match Ethiopian banking SMS messages
const BANK_KEYWORDS = ["CBE", "DashenBank", "Dashen", "127", "telebirr"];

interface SmsMessage {
  _id: string;
  address: string;
  body: string;
  date: number;
  date_sent: number;
}

interface ParsedPayment {
  smsId: string;
  bank: string;
  amount: string;
  ref: string;
  date: number;
  body: string;
  sender: string;
}

export default function SmsScanScreen() {
  const nav = useSirouRouter<AppRoutes>();
  const { colorScheme } = useColorScheme();
  const isDark = colorScheme === "dark";
  const [messages, setMessages] = useState<SmsMessage[]>([]);
  const [loading, setLoading] = useState(false);
  const [scanned, setScanned] = useState(false);

  const scanSms = async () => {
    if (Platform.OS !== "android") {
      toast.error("Android Only", "SMS reading is only supported on Android.");
      return;
    }

    if (!SmsAndroid) {
      toast.error(
        "Native Module Error",
        "SMS scanning requires a Development Build. Expo Go does not support this package.",
      );
      return;
    }

    setLoading(true);

    try {
      // Request SMS permission
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.READ_SMS,
        {
          title: "SMS Access Required",
          message:
            "Yaltopia needs access to read your banking SMS messages to match payments.",
          buttonPositive: "Allow",
          buttonNegative: "Deny",
        },
      );

      if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
        toast.error("Permission Denied", "SMS access was not granted.");
        return;
      }

      // Only look at messages from the past 20 minutes
      const fiveMinutesAgo = Date.now() - 20 * 60 * 1000;

      const filter = {
        box: "inbox",
        minDate: fiveMinutesAgo,
        maxCount: 50,
      };

      SmsAndroid.list(
        JSON.stringify(filter),
        (fail: string) => {
          console.error("[SMS] Failed to read:", fail);
          toast.error("Read Failed", "Could not read SMS messages.");
          setLoading(false);
        },
        (count: number, smsList: string) => {
          const allMessages: SmsMessage[] = JSON.parse(smsList);

          // Filter for banking messages only
          const bankMessages = allMessages.filter((sms) => {
            const body = sms.body?.toUpperCase() || "";
            const address = sms.address?.toUpperCase() || "";
            return BANK_KEYWORDS.some(
              (kw) =>
                body.includes(kw.toUpperCase()) ||
                address.includes(kw.toUpperCase()),
            );
          });

          setMessages(bankMessages);
          setScanned(true);
          setLoading(false);

          if (bankMessages.length === 0) {
            toast.info(
              "No Matches",
              "No banking SMS found in the last 5 minutes.",
            );
          } else {
            toast.success(
              "Found!",
              `${bankMessages.length} banking message(s) detected.`,
            );
          }
        },
      );
    } catch (err: any) {
      console.error("[SMS] Error:", err);
      toast.error("Error", err.message);
      setLoading(false);
    }
  };

  const formatTime = (timestamp: number) => {
    const date = new Date(timestamp);
    return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
  };

  const parseMessage = (sms: SmsMessage): ParsedPayment | null => {
    const body = sms.body;
    const addr = sms.address.toUpperCase();
    const text = (body + addr).toUpperCase();

    let bank = "Unknown";
    let amount = "";
    let ref = "";

    // CBE Patterns
    if (text.includes("CBE") || addr === "CBE") {
      bank = "CBE";
      // Pattern: "ETB 1,234.56" or "ETB 1,234"
      const amtMatch = body.match(/ETB\s*([\d,.]+)/i);
      if (amtMatch) amount = amMatch[1];

      // Pattern: "Ref: 123456789"
      const refMatch = body.match(/Ref:?\s*(\w+)/i);
      if (refMatch) ref = refMatch[1];
    }
    // Telebirr Patterns
    else if (text.includes("TELEBIRR") || addr === "TELEBIRR") {
      bank = "Telebirr";
      // Pattern: "Birr 1,234.56"
      const amtMatch = body.match(/Birr\s*([\d,.]+)/i);
      if (amtMatch) amount = amtMatch[1];

      // Pattern: "Trans ID: 12345678"
      const refMatch = body.match(/Trans ID:?\s*(\w+)/i);
      if (refMatch) ref = refMatch[1];
    }
    // Dashen Patterns
    else if (text.includes("DASHEN") || addr === "DASHEN") {
      bank = "Dashen";
      // Pattern: "ET,234.56"
      const amtMatch = body.match(/ETB\s*([\d,.]+)/i);
      if (amtMatch) amount = amtMatch[1];

      // Pattern: "Reference No: 12345678"
      const refMatch = body.match(/(?:Ref(?:erence)?(?:\s*No)?):?\s*(\w+)/i);
      if (refMatch) ref = refMatch[1];
    }

    if (bank === "Unknown") return null;

    return {
      smsId: sms._id,
      bank,
      amount,
      ref,
      date: sms.date,
      body: sms.body,
      sender: sms.address,
    };
  };

  const getBankColor = (bank: string) => {
    switch (bank) {
      case "CBE":
        return "#16a34a";
      case "Telebirr":
        return "#7c3aed";
      case "Dashen":
        return "#1d4ed8";
      default:
        return "#ea580c";
    }
  };

  return (
    <ScreenWrapper className="bg-background">
      {/* Header */}
      <View className="px-6 pt-4 flex-row justify-between items-center">
        <Pressable
          onPress={() => nav.back()}
          className="h-10 w-10 rounded-[10px] bg-card items-center justify-center border border-border"
        >
          <ArrowLeft color={isDark ? "#fff" : "#0f172a"} size={20} />
        </Pressable>
        <Text variant="h4" className="text-foreground font-sans-semibold">
          Scan SMS
        </Text>
        <View className="w-10" /> {/* Spacer */}
      </View>
      <View className="px-5 pt-6 pb-4">
        <Text variant="h3" className="text-foreground font-sans-bold">
          Scan SMS
        </Text>
        <Text variant="muted" className="mt-1">
          Finds banking messages from the last 5 minutes
        </Text>
      </View>

      {/* Scan Button */}
      <View className="px-5 mb-4">
        <Pressable
          onPress={scanSms}
          disabled={loading}
          className="h-12 rounded-[10px] bg-primary items-center justify-center flex-row gap-2"
        >
          {loading ? (
            <ActivityIndicator color="white" />
          ) : (
            <>
              <RefreshCw color="white" size={16} />
              <Text className="text-white font-sans-bold uppercase tracking-widest text-xs">
                {scanned ? "Scan Again" : "Scan Now"}
              </Text>
            </>
          )}
        </Pressable>
      </View>

      <ScrollView
        className="flex-1 px-5"
        contentContainerStyle={{ paddingBottom: 150 }}
        showsVerticalScrollIndicator={false}
      >
        {!scanned && !loading && (
          <View className="flex-1 items-center justify-center py-20 gap-4">
            <View className="bg-primary/10 p-6 rounded-[24px]">
              <MessageSquare
                size={40}
                className="text-primary"
                color="#ea580c"
                strokeWidth={1.5}
              />
            </View>
            <Text variant="muted" className="text-center px-10">
              Tap "Scan Now" to search for CBE, Dashen Bank, and Telebirr
              messages from the last 5 minutes.
            </Text>
          </View>
        )}

        {scanned && messages.length === 0 && (
          <View className="flex-1 items-center justify-center py-20 gap-4">
            <Text variant="muted" className="text-center">
              No banking messages found in the last 5 minutes.
            </Text>
          </View>
        )}

        <View className="gap-4">
          {messages.map((sms) => {
            const parsed = parseMessage(sms);
            if (!parsed) return null;

            const bankColor = getBankColor(parsed.bank);

            return (
              <Card
                key={sms._id}
                className="rounded-[16px] bg-card p-4 border border-border/40"
              >
                <View className="flex-row items-center justify-between mb-3">
                  <View
                    className="px-3 py-1 rounded-full"
                    style={{ backgroundColor: bankColor + "15" }}
                  >
                    <Text
                      className="text-xs font-sans-bold uppercase tracking-wider"
                      style={{ color: bankColor }}
                    >
                      {parsed.bank}
                    </Text>
                  </View>
                  <Text variant="muted" className="text-xs">
                    {formatTime(sms.date)}
                  </Text>
                </View>

                {/* Extracted Data */}
                <View className="flex-row gap-4 mb-3">
                  {parsed.amount ? (
                    <View className="flex-1 bg-muted/30 p-2 rounded-[8px]">
                      <Text
                        variant="muted"
                        className="text-[10px] uppercase font-sans-bold"
                      >
                        Amount
                      </Text>
                      <Text className="text-foreground font-sans-bold text-sm">
                        ETB {parsed.amount}
                      </Text>
                    </View>
                  ) : null}
                  {parsed.ref ? (
                    <View className="flex-1 bg-muted/30 p-2 rounded-[8px]">
                      <Text
                        variant="muted"
                        className="text-[10px] uppercase font-sans-bold"
                      >
                        Reference
                      </Text>
                      <Text
                        className="text-foreground font-sans-bold text-sm"
                        numberOfLines={1}
                      >
                        {parsed.ref}
                      </Text>
                    </View>
                  ) : null}
                </View>

                <Text className="text-foreground/70 text-xs leading-relaxed italic">
                  "{sms.body}"
                </Text>
              </Card>
            );
          })}
        </View>
      </ScrollView>
    </ScreenWrapper>
  );
}
