import Stripe from "stripe";
import Wallet from "../../DB/Model/payment/wallet.js";
import envVars from "../../Config/env-vars.js";
import constants from "../constants.js";
import User from "../../DB/Model/user.model.js";

const stripe = new Stripe(envVars.stripeSecretKey);

// Check user connect account status or return account session to completed strip onboarding
export const checkUserConnectAccount = async (account_id, user) => {
  try {
    let account;

    if (!account_id) {
      console.log("No account_id found, creating a new Stripe account...");

      account = await stripe.accounts.create({
        type: "express",
        country: "US",
        email: user.email,
        metadata: {
          user_id: user._id.toString(),
          user_type: user.userType,
        },
        capabilities: {
          card_payments: { requested: true },
          transfers: { requested: true },
        },
      });

      await User.findByIdAndUpdate(user._id, { stripe_id: account.id, stripe_connected: false });

      const accountLink = await stripe.accountLinks.create({
        account: account.id,
        refresh_url: "https://neighborly.thesuitchstaging2.com/",
        return_url: "https://neighborly.thesuitchstaging2.com/",
        type: "account_onboarding",
      });

      return {
        success: false,
        message: "New Stripe account created, onboarding required",
        onboarding_url: accountLink.url,
        account_id: account.id,
      };
    }

    try {
      account = await stripe.accounts.retrieve(account_id);
    } catch (err) {
      console.log("Stripe account not found, creating a new one...");

      account = await stripe.accounts.create({
        type: "express",
        country: "US",
        email: user.email,
        metadata: {
          user_id: user._id.toString(),
          user_type: user.userType,
        },
        capabilities: {
          card_payments: { requested: true },
          transfers: { requested: true },
        },
      });

      await User.findByIdAndUpdate(user._id, { stripe_id: account.id, stripe_connected: false });

      const accountLink = await stripe.accountLinks.create({
        account: account.id,
        refresh_url: "https://neighborly.thesuitchstaging2.com/",
        return_url: "https://neighborly.thesuitchstaging2.com/",
        type: "account_onboarding",
      });

      return {
        success: false,
        message: "Old Stripe account invalid, new account created. Onboarding required",
        onboarding_url: accountLink.url,
        account_id: account.id,
      };
    }

    console.log("Stripe account status:", account);

    if (account.requirements?.currently_due?.length > 0) {
      await User.findByIdAndUpdate(user._id, { stripe_connected: false });

      const accountLink = await stripe.accountLinks.create({
        account: account.id,
        refresh_url: "https://neighborly.thesuitchstaging2.com/",
        return_url: "https://neighborly.thesuitchstaging2.com/",
        type: "account_onboarding",
      });

      return {
        success: false,
        message: "Onboarding incomplete, please continue",
        onboarding_url: accountLink.url,
        account_id: account.id,
      };
    }

    if (!account.external_accounts || account.external_accounts.data.length === 0) {
      await User.findByIdAndUpdate(user._id, { stripe_connected: false });

      const accountLink = await stripe.accountLinks.create({
        account: account.id,
        refresh_url: `${process.env.FRONTEND_URL}`,
        return_url: `${process.env.FRONTEND_URL}`,
        type: "account_onboarding",
      });

      return {
        success: false,
        message: "No bank account linked, please complete onboarding",
        onboarding_url: accountLink.url,
        account_id: account.id,
      };
    }

    if (account.charges_enabled && account.payouts_enabled) {
      await User.findByIdAndUpdate(user._id, { stripe_connected: true });
      return {
        success: true,
        message: "Stripe account is fully verified",
        account_id: account.id,
      };
    }

    await User.findByIdAndUpdate(user._id, { stripe_connected: false });
    return {
      success: false,
      message: "Stripe account exists but is not fully active",
      account_id: account.id,
    };
  } catch (error) {
    console.error("Stripe Error:", error);
    return {
      success: false,
      message: error.message || "Error checking Stripe account",
    };
  }
};


// Create a test payment card
export const createCardPaymentMethod = async (
  user_id,
  stripe_card_test_token
) => {
  return new Promise(async (resolve, reject) => {
    try {
      const userWallet = await Wallet.findOne({ user: user_id });
      if (!userWallet) {
        reject({ message: "Wallet Does'nt Exists", success: false });
      }
      const newPaymentMethod = await stripe.paymentMethods.create({
        type: "card",
        card: {
          // exp_month: card.exp_month,
          // exp_year: card.exp_year,
          // number: card.card_number,
          // cvc: card.cvc,
          token: stripe_card_test_token,
        },
      });
      await stripe.paymentMethods.attach(newPaymentMethod.id, {
        customer: userWallet.customer_id,
      });
      resolve({
        message: "Payment Method Created",
        success: true,
        data: { pm_id: newPaymentMethod.id },
      });
    } catch (e) {
      console.log(e);
      reject(e);
    }
  });
};

// Attach Payment Method to Customer
export const attachPaymentMethod = async (req, res) => {
  try {
    const { user } = req;
    const { payment_method_id } = req.body;
    const userWallet = await Wallet.findOne({ user: user._id });
    if (!userWallet) {
      res
        .status(constants.BAD_REQUEST)
        .json({ message: "Wallet Does'nt Exists", success: false });
    }
    await stripe.paymentMethods.attach(payment_method_id, {
      customer: userWallet.customer_id,
    });
    res.status(constants.OK).json({
      message: "Payment Method Attach to Customer",
      success: true,
    });
  } catch (e) {
    console.log(e);
  }
};

// get the list of paymentMethods attach to customer
export const getPaymentMethod = async (req, res) => {
  const { user } = req;
  const userWallet = await Wallet.findOne({ user: user._id });

  if (!userWallet) {
    res
      .status(constants.BAD_REQUEST)
      .json({ message: "Wallet Does'nt Exists", success: false });
  }
  try {
    const paymentMethod = await stripe.customers.listPaymentMethods(
      userWallet.customer_id,
      {}
    );
    res.status(constants.OK).json({
      data: paymentMethod.data,
      message: "Payment Methods List",
      success: false,
    });
  } catch (e) {
    console.log(e);
  }
};

// Create payment intent
export const createPaymentIntent = (booking_id, user_id, amount) => {
  return new Promise(async (resolve, reject) => {
    try {
      const userWallet = await Wallet.findOne({ user: user_id }).populate("user", "name email");

      if (!userWallet) {
        return reject({ success: false, message: "Wallet doesn't exist" });
      }

      if (!userWallet.customer_id) {
        const customer = await stripe.customers.create({
          name: userWallet.user?.name || "Unnamed User",
          email: userWallet.user?.email || undefined,
        });

        userWallet.customer_id = customer.id;
        await userWallet.save();
      }
      const paymentIntent = await stripe.paymentIntents.create({
        amount: parseInt(amount) * 100,
        currency: "usd",
        automatic_payment_methods: { enabled: true },
        customer: userWallet.customer_id,
        metadata: {
          booking_id: booking_id.toString(),
          user_id: user_id.toString(),
          integration_check: "accept_a_payment",
        },
      });

      return resolve({
        success: true,
        client_secret: paymentIntent.client_secret,
        payment_intent_id: paymentIntent.id,
      });
    } catch (e) {
      console.error("Stripe PaymentIntent Error:", e);
      reject({ success: false, message: e.message });
    }
  });
};

// export const stripeWebhook = async (req, res) => {
//   console.log("WebHook init :>> ".red);
//   const sig = req.headers["stripe-signature"];
//   const body = req.body;

//   console.log("🚀 ~ stripeWebhook ~ sig:", sig)
//   let event = null;

//   try {
//     event = stripe.webhooks.constructEvent(
//       req.body,
//       sig,
//       "whsec_ab37f620f8b0ab6e24c97982cac7e9b2290af7b1e20844668ea91797c724aefb"
//     );
//   } catch (err) {
//     console.log("🚀 ~ stripeWebhook ~ err:", err)
//     // invalid signature
//     res.status(400).end();
//     return;
//   }

//   let intent = null;
//   switch (event["type"]) {
//     case "payment_intent.created":
//       intent = event.data.object;
//       console.log("Succeeded:", intent.id);
//       break;
//     case "payment_intent.succeeded":
//       intent = event.data.object;
//       console.log("Succeeded:", intent.id);
//       break;
//     case "payment_intent.payment_failed":
//       intent = event.data.object;
//       const message =
//         intent.last_payment_error && intent.last_payment_error.message;
//       console.log("Failed:", intent.id, message);
//       break;
//   }

//   res.status(constants.OK);
// };

const createOnboardingLink = async (accountId) => {
  return await stripe.accountLinks.create({
    account: accountId,
    refresh_url: "http://localhost:3090/api/v1/stripe/onboarding/refresh",
    return_url: "http://localhost:3090/api/v1/stripe/onboarding/return",
    type: "account_onboarding",
  });
};