<?php

namespace App\Controllers;

use App\Models\RegistrationModel;
use CodeIgniter\API\ResponseTrait;

class Checkout extends BaseController
{
    use ResponseTrait;

    public function enroll()
    {
        // Ensure this is a POST request
        if (!$this->request->is('post')) {
            return $this->fail('Invalid request method', 400);
        }

        $rules = [
            'name'     => 'required|min_length[3]|max_length[100]',
            'email'    => 'required|valid_email',
            'phone'    => 'required|regex_match[/^[0-9]{10}$/]',
            'password' => 'required|min_length[8]',
            'course'   => 'required|in_list[digital_marketing_foundational,web_development_foundational,ai_python_fullstack,digital_marketing_expert]',
        ];

        $messages = [
            'name' => [
                'required'   => 'Please enter your full name.',
                'min_length' => 'Name must be at least 3 characters long.',
            ],
            'email' => [
                'required'    => 'Please enter your email address.',
                'valid_email' => 'Please enter a valid email address.',
            ],
            'phone' => [
                'required'    => 'Please enter your phone number.',
                'regex_match' => 'Please enter a valid 10-digit mobile number.',
            ],
            'password' => [
                'required'   => 'Please enter a password.',
                'min_length' => 'Password must be at least 8 characters long.',
            ],
            'course' => [
                'required' => 'Please select a course.',
                'in_list'  => 'Invalid course selection.',
            ],
        ];

        if (!$this->validate($rules, $messages)) {
            return $this->respond([
                'status' => 'error',
                'errors' => $this->validator->getErrors()
            ]);
        }

        $course = $this->request->getPost('course');
        
        // Define price and display names dynamically to prevent user tampering from client-side
        $prices = [
            'digital_marketing_foundational' => 99.00,
            'web_development_foundational'   => 149.00,
            'ai_python_fullstack'            => 45000.00,
            'digital_marketing_expert'       => 45000.00
        ];

        $titles = [
            'digital_marketing_foundational' => 'Digital Marketing Foundational Course',
            'web_development_foundational'   => 'Web Development Foundational Course',
            'ai_python_fullstack'            => 'AI Python Full Stack Course',
            'digital_marketing_expert'       => 'Digital Marketing Expert Course'
        ];

        if (!isset($prices[$course])) {
            return $this->respond([
                'status' => 'error',
                'errors' => ['course' => 'Invalid course selection.']
            ]);
        }

        $amount      = $prices[$course];
        $courseTitle = $titles[$course];
        $email       = $this->request->getPost('email');

        $model = new RegistrationModel();

        // Check if student is already fully enrolled in this course
        $existing = $model->where('email', $email)
                          ->where('course', $course)
                          ->where('status', 'completed')
                          ->first();
        if ($existing) {
            return $this->respond([
                'status' => 'error',
                'errors' => ['email' => 'You are already enrolled in this course. Please sign in to access it.']
            ]);
        }

        // Setup credentials config
        $keyId     = env('razorpay.keyId');
        $keySecret = env('razorpay.keySecret');

        // Check if keys are default placeholders or empty to run in developer-mock mode
        $isMock = false;
        if (empty($keyId) || $keyId === 'rzp_test_YOUR_KEY_ID' || empty($keySecret) || $keySecret === 'YOUR_KEY_SECRET') {
            $isMock = true;
        }

        $orderId = '';
        if ($isMock) {
            // Mock Order creation
            $orderId = 'order_mock_' . bin2hex(random_bytes(8));
        } else {
            // API call to Razorpay
            $amountInPaisa = (int)($amount * 100);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'https://api.razorpay.com/v1/orders');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
                'amount'   => $amountInPaisa,
                'currency' => 'INR',
                'receipt'  => 'rcpt_' . time(),
            ]));
            curl_setopt($ch, CURLOPT_USERPWD, $keyId . ':' . $keySecret);
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
            curl_setopt($ch, CURLOPT_TIMEOUT, 10);
            
            $response = curl_exec($ch);
            $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            if ($httpcode === 200) {
                $orderData = json_decode($response, true);
                if (isset($orderData['id'])) {
                    $orderId = $orderData['id'];
                }
            }

            if (empty($orderId)) {
                return $this->respond([
                    'status' => 'error',
                    'errors' => ['payment' => 'Failed to initialize payment gateway. Please check Razorpay keys in .env.']
                ], 500);
            }
        }

        $passwordHash = password_hash($this->request->getPost('password'), PASSWORD_DEFAULT);

        $data = [
            'name'              => $this->request->getPost('name'),
            'email'             => $email,
            'phone'             => $this->request->getPost('phone'),
            'password'          => $passwordHash,
            'course'            => $course,
            'amount'            => $amount,
            'status'            => 'pending',
            'razorpay_order_id' => $orderId,
        ];

        if ($insertId = $model->insert($data)) {
            return $this->respond([
                'status'       => 'success_pending',
                'name'         => $data['name'],
                'email'        => $data['email'],
                'phone'        => $data['phone'],
                'amount'       => $amount,
                'course_title' => $courseTitle,
                'order_id'     => $orderId,
                'key_id'       => $isMock ? 'mock_key' : $keyId,
                'is_mock'      => $isMock,
            ]);
        }

        return $this->respond([
            'status' => 'error',
            'errors' => ['database' => 'Failed to save pending registration. Please try again.']
        ], 500);
    }

    public function enrollVerify()
    {
        // Ensure this is a POST request
        if (!$this->request->is('post')) {
            return $this->fail('Invalid request method', 400);
        }

        $orderId   = $this->request->getPost('razorpay_order_id');
        $paymentId = $this->request->getPost('razorpay_payment_id');
        $signature = $this->request->getPost('razorpay_signature');
        $isMock    = $this->request->getPost('is_mock') === 'true';

        $model = new RegistrationModel();
        
        // Find matching pending registration
        $registration = $model->where('razorpay_order_id', $orderId)
                              ->where('status', 'pending')
                              ->first();

        if (!$registration) {
            return $this->respond([
                'status' => 'error',
                'errors' => ['payment' => 'Registration record not found or already completed.']
            ], 404);
        }

        $verified = false;

        if ($isMock) {
            // Verify mock signature
            $expectedSignature = hash('sha256', $orderId . '|' . $paymentId . '|mock_secret');
            if ($signature === $expectedSignature) {
                $verified = true;
            }
        } else {
            $keySecret = env('razorpay.keySecret');
            $expectedSignature = hash_hmac('sha256', $orderId . '|' . $paymentId, $keySecret);
            if (hash_equals($expectedSignature, $signature)) {
                $verified = true;
            }
        }

        if ($verified) {
            // Update status and save payment reference
            $model->update($registration['id'], [
                'status'              => 'completed',
                'razorpay_payment_id' => $paymentId,
                'razorpay_signature'  => $signature,
            ]);

            // Set login session details
            $session = session();
            $session->set([
                'student_logged_in' => true,
                'student_id'        => $registration['id'],
                'student_name'      => $registration['name'],
                'student_email'     => $registration['email'],
                'student_course'    => $registration['course'],
            ]);

            $titles = [
                'digital_marketing_foundational' => 'Digital Marketing Foundational Course',
                'web_development_foundational'   => 'Web Development Foundational Course',
                'ai_python_fullstack'            => 'AI Python Full Stack Course',
                'digital_marketing_expert'       => 'Digital Marketing Expert Course'
            ];
            $courseTitle = $titles[$registration['course']] ?? 'Course';

            return $this->respond([
                'status'       => 'success',
                'name'         => $registration['name'],
                'amount'       => $registration['amount'],
                'course_title' => $courseTitle,
                'redirect_url' => site_url('student/dashboard'),
                'message'      => 'Congratulations! Your enrollment in ' . $courseTitle . ' was successful.'
            ]);
        }

        return $this->respond([
            'status' => 'error',
            'errors' => ['payment' => 'Payment verification failed. Signature mismatch.']
        ], 400);
    }

    public function razorpayWebhook()
    {
        $signature = $this->request->getHeaderLine('X-Razorpay-Signature');
        $rawPayload = $this->request->getBody();

        // Decode JSON payload
        $data = json_decode($rawPayload, true);
        if (json_last_error() !== JSON_ERROR_NONE || empty($data)) {
            return $this->response->setStatusCode(400)->setBody('Invalid JSON payload');
        }

        // Webhook Secret verification if configured
        $webhookSecret = env('razorpay.webhookSecret');
        if (!empty($webhookSecret) && $webhookSecret !== 'YOUR_WEBHOOK_SECRET') {
            if (empty($signature)) {
                return $this->response->setStatusCode(401)->setBody('Missing signature');
            }
            $expectedSignature = hash_hmac('sha256', $rawPayload, $webhookSecret);
            if (!hash_equals($expectedSignature, $signature)) {
                return $this->response->setStatusCode(401)->setBody('Signature verification failed');
            }
        }

        // Handle relevant events
        $event = $data['event'] ?? '';
        if ($event === 'order.paid' || $event === 'payment.captured') {
            // Locate order ID and payment ID
            $orderId   = '';
            $paymentId = '';

            if (isset($data['payload']['payment']['entity'])) {
                $paymentEntity = $data['payload']['payment']['entity'];
                $orderId       = $paymentEntity['order_id'] ?? '';
                $paymentId     = $paymentEntity['id'] ?? '';
            } elseif (isset($data['payload']['order']['entity'])) {
                $orderEntity = $data['payload']['order']['entity'];
                $orderId     = $orderEntity['id'] ?? '';
            }

            if (!empty($orderId)) {
                $model = new RegistrationModel();
                $registration = $model->where('razorpay_order_id', $orderId)
                                      ->where('status', 'pending')
                                      ->first();

                if ($registration) {
                    $model->update($registration['id'], [
                        'status'              => 'completed',
                        'razorpay_payment_id' => $paymentId ?: 'webhook_completed',
                        'razorpay_signature'  => $signature ?: 'webhook_verified',
                    ]);
                    
                    log_message('info', 'Razorpay Webhook: Enrollment completed successfully for Order ID: ' . $orderId);
                    return $this->response->setStatusCode(200)->setBody('Enrollment completed successfully');
                }
            }
        }

        return $this->response->setStatusCode(200)->setBody('Webhook received and processed');
    }
}
