import {
  View,
  TextInput,
  Alert,
  Text,
  ScrollView,
  TouchableOpacity,
  ActivityIndicator,
} from "react-native";
import React, { useState } from "react";
import { PaymentProps, PaymentProviderProps, TCard } from "./Payment.types";
import {
  StripeProvider,
  useStripe,
  CardForm,
  CardFormView,
} from "@stripe/stripe-react-native";

import { paymentStyles } from "./Payment.styles";

const PaymentProvider = ({
  children,
  stripePublishableKey,
}: PaymentProviderProps) => {
  return (
    <StripeProvider publishableKey={stripePublishableKey}>
      {children}
    </StripeProvider>
  );
};

const Payment = (Props: PaymentProps) => {
  const [card, setCard] = useState<TCard>();
  const [loading, setLoading] = useState(false);
  const stripe = useStripe();

  const handlePayment = async () => {
    try {
      if (!stripe) {
        throw new Error("Stripe initialization failed");
      }
      setLoading(true);
      if (!Props.createPaymentIntent) {
        throw new Error("Please pass the required fields");
      }

      if (card === undefined) {
        throw new Error("Please fill all the fields");
      }

      const { paymentMethod, error: paymentMethodError } =
        await stripe.createPaymentMethod({
          paymentMethodType: "Card",
        });

      if (paymentMethodError) {
        throw paymentMethodError;
      }

      const { clientSecret } = await Props.createPaymentIntent({
        card,
        paymentMethod,
      });

      const { error: confirmPaymentError, paymentIntent } =
        await stripe.confirmPayment(clientSecret, {
          paymentMethodType: "Card",
        });

      if (confirmPaymentError) {
        throw confirmPaymentError;
      }

      if (Props.onPaymentSuccess) {
        Props.onPaymentSuccess(paymentIntent);
      }
      setCard(undefined);
    } catch (error) {
      Alert.alert("Stripe payment error", "Please contact support");
      console.log(error);
    } finally {
      setLoading(false);
    }
  };

  const handleCardFormUpdate = (cardData: CardFormView.Details) => {
    const { country, postalCode } = cardData;
    setCard(
      (prev) =>
        ({
          ...prev,
          ...(country && { country }),
          ...(postalCode && { postalCode: Number(postalCode) }),
        } as TCard)
    );
  };

  const isCardComplete = () => {
    let complete = false;

    if (
      card?.name &&
      card?.email &&
      card?.country &&
      card?.postalCode &&
      card?.city &&
      card?.state &&
      card?.line1 &&
      card?.line2
    ) {
      complete = true;
    }

    return complete;
  };

  const onBack = () => {
    if (Props.onBack) {
      Props.onBack();
    }
  };

  return (
    <View style={paymentStyles.main}>
      <ScrollView>
        <PaymentProvider stripePublishableKey={Props.stripePublishableKey}>
          <View style={paymentStyles.headerViewStyle}>
            <TouchableOpacity
              onPress={onBack}
              style={paymentStyles.backButtonStyle}
            >
              <Text style={{ color: "white" }}>Back</Text>
            </TouchableOpacity>
            <Text style={paymentStyles.heading}>Payment</Text>
          </View>

          <TextInput
            placeholder="Card holder's name"
            style={[
              paymentStyles.textInput,
              { borderTopWidth: 1.2, borderBottomWidth: 1.2 },
            ]}
            placeholderTextColor="silver"
            value={card?.name || ""}
            onChangeText={(name) => {
              setCard((prev) => ({ ...prev, name } as TCard));
            }}
          />
          <TextInput
            placeholder="Card holder's email"
            keyboardType="email-address"
            style={[paymentStyles.textInput, { borderBottomWidth: 1.2 }]}
            placeholderTextColor="silver"
            value={card?.email || ""}
            onChangeText={(email) => {
              setCard((prev) => ({ ...prev, email } as TCard));
            }}
          />
          <CardForm
            style={{ height: 250 }}
            onFormComplete={handleCardFormUpdate}
          />
          <View style={{ flexDirection: "row" }}>
            <TextInput
              placeholder="City"
              style={[
                paymentStyles.textInput,
                {
                  borderTopWidth: 1.2,
                  borderRightWidth: 1.2,
                  flex: 1,
                },
              ]}
              placeholderTextColor="silver"
              value={card?.city || ""}
              onChangeText={(city) => {
                setCard((prev) => ({ ...prev, city } as TCard));
              }}
            />
            <TextInput
              placeholder="State"
              style={[
                paymentStyles.textInput,
                {
                  borderTopWidth: 1.2,
                  flex: 1,
                },
              ]}
              placeholderTextColor="silver"
              value={card?.state || ""}
              onChangeText={(state) => {
                setCard((prev) => ({ ...prev, state } as TCard));
              }}
            />
          </View>
          <View style={{ flexDirection: "row", marginBottom: 10 }}>
            <TextInput
              placeholder="Line 1"
              style={[
                paymentStyles.textInput,
                {
                  borderTopWidth: 1.2,
                  borderRightWidth: 1.2,
                  borderBottomWidth: 1.2,
                  flex: 1,
                },
              ]}
              placeholderTextColor="silver"
              value={card?.line1 || ""}
              onChangeText={(line1) => {
                setCard((prev) => ({ ...prev, line1 } as TCard));
              }}
            />
            <TextInput
              placeholder="Line 2"
              style={[
                paymentStyles.textInput,
                {
                  borderTopWidth: 1.2,
                  borderBottomWidth: 1.2,
                  flex: 1,
                },
              ]}
              placeholderTextColor="silver"
              value={card?.line2 || ""}
              onChangeText={(line2) => {
                setCard((prev) => ({ ...prev, line2 } as TCard));
              }}
            />
          </View>
          <TouchableOpacity
            style={[
              paymentStyles.continueButton,
              (!isCardComplete() || loading) && { backgroundColor: "silver" },
            ]}
            disabled={!isCardComplete() || loading}
            onPress={handlePayment}
          >
            {loading ? (
              <ActivityIndicator color="black" />
            ) : (
              <Text
                style={[
                  paymentStyles.continueButtonText,
                  !isCardComplete() && { color: "grey" },
                ]}
              >
                Continue
              </Text>
            )}
          </TouchableOpacity>
        </PaymentProvider>
      </ScrollView>
    </View>
  );
};

export default Payment;
