import Stripe from 'stripe';

export default {
  // 1. Create or fetch Stripe Customer & generate SetupIntent
  async createSetupIntent(ctx: any) {
    const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string);
    const user = ctx.state.user;

    if (!user) return ctx.unauthorized();

    try {
      let customerId = (user as any).stripeCustomerId;

      if (!customerId) {
        const customer = await stripe.customers.create({
          email: user.email,
          name: user.username || user.email,
          metadata: {
            strapiUserId: String(user.id),
          },
        });
        customerId = customer.id;

        await strapi.documents('plugin::users-permissions.user').update({
          documentId: user.documentId || user.id,
          data: {
            stripeCustomerId: customerId,
          } as any,
          status: 'published',
        });
      }

      const setupIntent = await stripe.setupIntents.create({
        customer: customerId,
        payment_method_types: ['card'],
        usage: 'off_session',
        metadata: {
          userId: String(user.id),
          userEmail: user.email || '',
        },
      });

      return ctx.send({ 
        clientSecret: setupIntent.client_secret,
        customerId: customerId 
      });
    } catch (err: any) {
      console.error('SetupIntent error:', err);
      return ctx.badRequest(err.message);
    }
  },

  // 2. Host Approval: Charge Full Amount into Escrow
  async approveAndCharge(ctx: any) {
    const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string);
    const { documentId } = ctx.params;
    const user = ctx.state.user;

    if (!user) return ctx.unauthorized();

    const booking: any = await strapi.documents('api::booking.booking').findOne({
      documentId,
      populate: ['vehicle', 'vehicle.users_permissions_user', 'users_permissions_user'] as any,
    });

    if (!booking) return ctx.notFound('Booking not found');

    if (booking.vehicle?.users_permissions_user?.id !== user.id) {
      return ctx.unauthorized('Only the vehicle host can approve this booking');
    }

    if (!booking.stripePaymentMethodId) {
      return ctx.badRequest('No payment method attached to this booking');
    }

    try {
      const renter: any = booking.users_permissions_user;
      const amountInCents = Math.round(Number(booking.totalAmount) * 100);

      // Charge the pre-authorized card attached to customer
      const paymentIntent = await stripe.paymentIntents.create({
        amount: amountInCents,
        currency: 'aed', // or 'usd'
        customer: renter?.stripeCustomerId || undefined,
        payment_method: booking.stripePaymentMethodId,
        confirm: true,
        off_session: true,
        receipt_email: renter?.email ?? undefined,
        description: `Escrow for ${booking.vehicle?.year || ''} ${booking.vehicle?.make || ''} ${booking.vehicle?.model || ''}`,
        metadata: {
          bookingDocumentId: booking.documentId || '',
          renterId: renter?.id ? String(renter.id) : '',
        },
      });

      // Update and PUBLISH the booking status
      const updated = await strapi.documents('api::booking.booking').update({
        documentId,
        data: {
          approval_status: 'Approved',
          paymentStatus: 'in_escrow',
          stripePaymentIntentId: paymentIntent.id,
        } as any,
        status: 'published',
      });

      return ctx.send({ success: true, booking: updated });
    } catch (err: any) {
      console.error('PaymentIntent capture error:', err);
      return ctx.badRequest(`Payment failed: ${err.message}`);
    }
  },

  // 3. Post-Trip Return & Release Insurance Deposit
  async releaseDeposit(ctx: any) {
    const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string);
    const { documentId } = ctx.params;
    const user = ctx.state.user;

    if (!user) return ctx.unauthorized();

    const booking: any = await strapi.documents('api::booking.booking').findOne({
      documentId,
      populate: ['vehicle', 'vehicle.users_permissions_user'] as any,
    });

    if (!booking) return ctx.notFound('Booking not found');
    if (booking.vehicle?.users_permissions_user?.id !== user.id) {
      return ctx.unauthorized('Only the host can release the security deposit');
    }

    if (!booking.stripePaymentIntentId) {
      return ctx.badRequest('No payment intent found for this booking');
    }

    try {
      const depositAmountInCents = Math.round(Number(booking.insuranceDepositAmount || 0) * 100);

      if (depositAmountInCents > 0) {
        await stripe.refunds.create({
          payment_intent: booking.stripePaymentIntentId,
          amount: depositAmountInCents,
          reason: 'requested_by_customer',
        });
      }

      // Update and PUBLISH the completed status
      const updated = await strapi.documents('api::booking.booking').update({
        documentId,
        data: {
          approval_status: 'Completed',
          paymentStatus: 'deposit_refunded',
          depositRefunded: true,
        } as any,
        status: 'published',
      });

      return ctx.send({ success: true, booking: updated });
    } catch (err: any) {
      console.error('Deposit release error:', err);
      return ctx.badRequest(`Refund release failed: ${err.message}`);
    }
  },
};
