<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Mail\PaymentConfirmedMail;
use App\Models\Investment;
use App\Services\DocumentService;
use App\Services\InvestorService;
use App\Services\PaystackService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;

class PaymentController extends Controller
{
    public function __construct(
        protected PaystackService $paystackService,
        protected DocumentService $documentService,
        protected InvestorService $investorService
    ) {}

    /**
     * Initialize payment
     * POST /api/payments/initialize
     */
    public function initialize(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'investment_id' => 'required|uuid|exists:investments,id',
        ]);

        $investment = Investment::findOrFail($validated['investment_id']);

        // Check if already paid
        if ($investment->payment_status === 'confirmed') {
            return response()->json([
                'error' => true,
                'message' => 'This investment has already been paid',
                'code' => 'ALREADY_PAID',
            ], 400);
        }

        // Check compliance checkboxes
        if (!$investment->isComplianceComplete()) {
            return response()->json([
                'error' => true,
                'message' => 'All compliance checkboxes must be accepted before payment',
                'code' => 'COMPLIANCE_INCOMPLETE',
            ], 400);
        }

        // Initialize Paystack transaction
        $result = $this->paystackService->initializeTransaction($investment);

        if (!$result['success']) {
            return response()->json([
                'error' => true,
                'message' => $result['message'],
                'code' => 'PAYMENT_INIT_FAILED',
            ], 400);
        }

        return response()->json([
            'success' => true,
            'data' => [
                'authorization_url' => $result['authorization_url'],
                'access_code' => $result['access_code'],
                'reference' => $result['reference'],
                'investment_reference' => $investment->reference,
            ],
            'meta' => [
                'timestamp' => now()->toIso8601String(),
                'request_id' => $investment->reference,
            ],
        ]);
    }

    /**
     * Verify payment
     * POST /api/payments/verify
     */
    public function verify(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'reference' => 'required|string',
        ]);

        $result = $this->paystackService->verifyTransaction($validated['reference']);

        if (!$result['success']) {
            return response()->json([
                'error' => true,
                'message' => $result['message'],
                'code' => 'VERIFICATION_FAILED',
            ], 400);
        }

        $investment = $result['investment'];

        // Trigger post-payment workflows
        $this->triggerPostPaymentWorkflows($investment);

        return response()->json([
            'success' => true,
            'data' => [
                'investment_id' => $investment->id,
                'investment_reference' => $investment->reference,
                'amount' => $investment->investment_amount,
                'currency' => $investment->currency,
                'status' => $investment->status,
                'payment_status' => $investment->payment_status,
            ],
            'meta' => [
                'timestamp' => now()->toIso8601String(),
            ],
        ]);
    }

    /**
     * Handle Paystack webhook
     * POST /webhooks/paystack
     */
    public function handleWebhook(Request $request): JsonResponse
    {
        $payload = $request->getContent();
        $signature = $request->header('X-Paystack-Signature');

        // Validate webhook signature
        if (!$this->paystackService->validateWebhookSignature($payload, $signature ?? '')) {
            Log::warning('Invalid Paystack webhook signature', [
                'ip' => $request->ip(),
            ]);

            return response()->json([
                'error' => true,
                'message' => 'Invalid signature',
            ], 400);
        }

        $event = json_decode($payload, true);

        Log::info('Paystack webhook received', [
            'event' => $event['event'] ?? 'unknown',
            'reference' => $event['data']['reference'] ?? null,
        ]);

        switch ($event['event'] ?? '') {
            case 'charge.success':
                $this->handleChargeSuccess($event['data']);
                break;

            case 'transfer.success':
                $this->handleTransferSuccess($event['data']);
                break;

            case 'charge.dispute.create':
            case 'charge.dispute.remind':
                $this->handleDispute($event['data']);
                break;

            case 'refund.processed':
                $this->handleRefund($event['data']);
                break;

            default:
                Log::info('Unhandled webhook event', ['event' => $event['event']]);
        }

        return response()->json(['received' => true]);
    }

    /**
     * Handle successful charge
     */
    protected function handleChargeSuccess(array $data): void
    {
        $reference = $data['reference'] ?? null;
        
        if (!$reference) {
            return;
        }

        $this->paystackService->verifyTransaction($reference);

        // Find investment and trigger workflows
        $investment = Investment::where('payment_reference', $reference)->first();
        
        if ($investment) {
            $this->triggerPostPaymentWorkflows($investment);
        }
    }

    /**
     * Handle successful transfer (dividend payment)
     */
    protected function handleTransferSuccess(array $data): void
    {
        Log::info('Transfer successful', ['data' => $data]);
        // Handle dividend payment confirmation
    }

    /**
     * Handle payment dispute
     */
    protected function handleDispute(array $data): void
    {
        Log::warning('Payment dispute', ['data' => $data]);
        // Notify finance team
    }

    /**
     * Handle refund
     */
    protected function handleRefund(array $data): void
    {
        Log::info('Refund processed', ['data' => $data]);
    }

    /**
     * Trigger post-payment workflows
     */
    protected function triggerPostPaymentWorkflows(Investment $investment): void
    {
        // Send payment confirmation email
        try {
            Mail::to($investment->email)->send(new PaymentConfirmedMail($investment));
        } catch (\Exception $e) {
            Log::error('Failed to send payment confirmation email', [
                'investment_id' => $investment->id,
                'error' => $e->getMessage(),
            ]);
        }

        // Generate investment agreement
        try {
            $this->documentService->generateInvestmentAgreement($investment);
        } catch (\Exception $e) {
            Log::error('Failed to generate investment agreement', [
                'investment_id' => $investment->id,
                'error' => $e->getMessage(),
            ]);
        }

        // Update status to agreement pending
        $investment->update(['status' => 'agreement_pending']);
    }
}
