import Stripe from "stripe";
import ConnectAccount from "../../DB/Model/payment/connect-account.model.js";
import { checkUserConnectAccount } from "../../Utils/Stripe/index.js";
import User from "../../DB/Model/user.model.js";
import envVars from "../../Config/env-vars.js";
import CustomError from "../../Utils/ResponseHandler/CustomError.js";
import constants from "../../Utils/constants.js";



const stripe = new Stripe(envVars.stripeSecretKey);

const createStripeAccount = async (req, res, next) => {
  try {
    const { user } = req;

    let account;
    if (!user.stripe_id) {
      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 }, // ❌ by default false
        { new: true }
      );
      await ConnectAccount.create({ user: user._id, connect_account_id: account.id });
    } else {
      try {
        account = await stripe.accounts.retrieve(user.stripe_id);
      } catch (err) {
        console.log("Stripe account not found, creating 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 }, // ❌ default false until verified
          { new: true }
        );
        await ConnectAccount.findOneAndUpdate(
          { user: user._id },
          { connect_account_id: account.id },
          { upsert: true, new: true }
        );
      }
    }

    // ✅ Check onboarding / requirements
    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: `${process.env.FRONTEND_URL}`,
        return_url: `${process.env.FRONTEND_URL}`,
        type: "account_onboarding",
      });

      return res.status(constants.OK).json({
        success: false,
        message: "Onboarding incomplete, please continue",
        data: { account_id: account.id, onboarding_url: accountLink.url },
      });
    }

    // ✅ Check bank account linked
    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 res.status(constants.OK).json({
        success: false,
        message: "No bank account linked, please complete onboarding",
        data: { account_id: account.id, onboarding_url: accountLink.url },
      });
    }

    // ✅ Fully active
    if (account.charges_enabled && account.payouts_enabled) {
      await User.findByIdAndUpdate(user._id, { stripe_connected: true });
      return res.status(constants.OK).json({
        success: true,
        message: "Stripe account is fully verified",
        data: { account_id: account.id },
      });
    }

    await User.findByIdAndUpdate(user._id, { stripe_connected: false });
    return res.status(constants.OK).json({
      success: false,
      message: "Stripe account exists but is not fully active",
      data: { account_id: account.id },
    });
  } catch (e) {
    console.log("Stripe Account Error:", e);
    return next(CustomError.badRequest(e.message));
  }
};


const getUserConnectAccount = async (req, res, next) => {
  try {
    const { user } = req;
    const fetchConnectAccount = await ConnectAccount.findOne({
      userId: user._id,
    });
    if (!fetchConnectAccount) {
      return next(CustomError.badRequest("You Do not have Connect Account"));
    }

    return res.status(200).send({
      success: true,
      message: "Your Connect Account Details fetch Successfully",
      data: fetchConnectAccount,
    });
  } catch (e) {
    console.log(e);
    return res.status(400).send(e);
  }
};

const connectController = {
  createStripeAccount,
  getUserConnectAccount
};

export default connectController; 