import { router } from "expo-router";
import * as WebBrowser from "expo-web-browser";
import { useState } from "react";
import { Alert, Image, Text, TouchableOpacity, View } from "react-native";
import ReactNativeModal from "react-native-modal";

import { images } from "@/constants";
import { fetchAPI } from "@/lib/fetch";
import { formatLBP } from "@/lib/pricing";
import { useLocationStore } from "@/store";
import type { PaymentProps } from "@/types/type";

import { CustomButton } from "./custom-button";

type PaymentMethod = "cash" | "card";

export const Payment = ({
  fullName,
  email,
  amount,
  driverId,
  rideTime,
}: PaymentProps) => {
  const {
    userAddress,
    userLongitude,
    userLatitude,
    destinationLatitude,
    destinationAddress,
    destinationLongitude,
  } = useLocationStore();
  const [method, setMethod] = useState<PaymentMethod>("cash");
  const [success, setSuccess] = useState(false);
  const [processing, setProcessing] = useState(false);

  const recordRide = async (paymentStatus: string) => {
    await fetchAPI("/(api)/ride/create", {
      method: "POST",
      headers: {
        "Content-type": "application/json",
      },
      body: JSON.stringify({
        origin_address: userAddress,
        destination_address: destinationAddress,
        origin_latitude: userLatitude,
        origin_longitude: userLongitude,
        destination_latitude: destinationLatitude,
        destination_longitude: destinationLongitude,
        ride_time: rideTime.toFixed(0),
        fare_price: Math.round(parseFloat(amount) * 100), // in cents
        payment_status: paymentStatus,
        driver_id: driverId,
      }),
    });
  };

  // Cash is settled directly with the driver at drop-off.
  const payWithCash = async () => {
    setProcessing(true);
    try {
      await recordRide("cash");
      setSuccess(true);
    } catch (err) {
      console.log("[PAYMENT]: ", err);
      Alert.alert(
        "Error",
        "Something went wrong while booking your ride. Please try again.",
      );
    } finally {
      setProcessing(false);
    }
  };

  const payWithCard = async () => {
    setProcessing(true);

    try {
      // 1. Create an Areeba checkout session on our server.
      const { orderId, checkoutUrl, successIndicator, error } = await fetchAPI(
        "/(api)/(areeba)/create",
        {
          method: "POST",
          headers: {
            "Content-type": "application/json",
          },
          body: JSON.stringify({
            name: fullName || email,
            email,
            amount,
          }),
        },
      );

      if (error || !checkoutUrl) throw new Error(error || "No checkout URL");

      // 2. Open Areeba's hosted payment page. After payment the gateway
      //    redirects back to the app (waseel://book-ride).
      const browserResult = await WebBrowser.openAuthSessionAsync(
        checkoutUrl,
        "waseel://book-ride",
      );

      let resultIndicator: string | undefined;
      if (browserResult.type === "success" && browserResult.url) {
        resultIndicator = new URL(browserResult.url).searchParams.get(
          "resultIndicator",
        ) as string;
      }

      // 3. Verify the payment server-side before recording the ride.
      const verification = await fetchAPI("/(api)/(areeba)/verify", {
        method: "POST",
        headers: {
          "Content-type": "application/json",
        },
        body: JSON.stringify({ orderId, resultIndicator, successIndicator }),
      });

      if (verification.success) {
        await recordRide("paid");
        setSuccess(true);
      } else {
        Alert.alert(
          "Payment not completed",
          "Your payment was cancelled or could not be verified. Please try again.",
        );
      }
    } catch (err) {
      console.log("[PAYMENT]: ", err);
      Alert.alert(
        "Error",
        "Something went wrong while processing your payment. Please try again.",
      );
    } finally {
      setProcessing(false);
    }
  };

  const confirm = () =>
    method === "cash"
      ? payWithCash()
      : Alert.alert("Pay by card", `Your card will be charged $${amount}.`, [
          { text: "Cancel", style: "cancel" },
          { text: "Continue", onPress: () => void payWithCard() },
        ]);

  return (
    <>
      <Text className="text-lg font-JakartaSemiBold mt-4 mb-2">
        Payment Method
      </Text>

      <View className="flex flex-row gap-x-3">
        <TouchableOpacity
          onPress={() => setMethod("cash")}
          className={`flex-1 items-center py-3 rounded-xl border ${
            method === "cash"
              ? "bg-general-600 border-primary-500"
              : "bg-white border-general-700"
          }`}
        >
          <Text
            className={`font-JakartaMedium ${
              method === "cash" ? "text-white" : "text-black"
            }`}
          >
            💵 Cash
          </Text>
        </TouchableOpacity>

        <TouchableOpacity
          onPress={() => setMethod("card")}
          className={`flex-1 items-center py-3 rounded-xl border ${
            method === "card"
              ? "bg-general-600 border-primary-500"
              : "bg-white border-general-700"
          }`}
        >
          <Text
            className={`font-JakartaMedium ${
              method === "card" ? "text-white" : "text-black"
            }`}
          >
            💳 Card
          </Text>
        </TouchableOpacity>
      </View>

      <CustomButton
        title={
          processing
            ? "Processing..."
            : method === "cash"
              ? "Book ride · Pay cash to driver"
              : "Confirm & Pay by Card"
        }
        className="my-2 mt-4"
        onPress={confirm}
        disabled={processing}
      />

      <ReactNativeModal
        isVisible={success}
        onBackdropPress={() => setSuccess(false)}
      >
        <View className="flex flex-col items-center justify-center bg-white p-7 rounded-2xl">
          <Image source={images.check} alt="Check" className="w-28 h-28 mt-5" />

          <Text className="text-2xl text-center font-JakartaBold mt-5">
            Ride Booked!
          </Text>

          <Text className="text-base text-general-200 text-JakartaMedium text-center mt-3">
            Thank you for your booking.{"\n"} Your reservation has been placed.
            {"\n"}
            {method === "cash"
              ? `Please have ${formatLBP(parseFloat(amount))} ready.`
              : null}
          </Text>

          <CustomButton
            title="Back Home"
            onPress={() => {
              setSuccess(false);
              router.push("/(root)/(tabs)/home");
            }}
            className="mt-5"
          />
        </View>
      </ReactNativeModal>
    </>
  );
};
