<?php
namespace infozone\ads\controller;

class advertise_controller
{
    protected $db;
    protected $template;
    protected $request;
    protected $user;
    protected $config;
    protected $helper;
    protected $language;
    protected $root_path;
    protected $php_ext;

    public function __construct($db, $template, $request, $user, $config, $helper, $language, $root_path, $php_ext)
    {
        $this->db = $db;
        $this->template = $template;
        $this->request = $request;
        $this->user = $user;
        $this->config = $config;
        $this->helper = $helper;
        $this->language = $language;
        $this->root_path = $root_path;
        $this->php_ext = $php_ext;
    }

    public function handle()
    {
        $this->language->add_lang('advertise', 'infozone/ads');

        $submit = $this->request->is_set_post('submit');
        if ($submit)
        {
            $fullname = $this->request->variable('fullname', '', true);
            $email    = $this->request->variable('email', '', true);
            $phone    = $this->request->variable('phone', '', true);
            $company  = $this->request->variable('company', '', true);
            $target   = $this->request->variable('target_url', '', true);
            $slots    = $this->request->variable('slots', '', true);
            $duration = $this->request->variable('duration_days', 7);
            $ad_type  = $this->request->variable('ad_type', 'image');
            $html     = $this->request->variable('html_code', '', true);
            $notes    = $this->request->variable('notes', '', true);

            // Upload (optional) - simple: expects a URL in this version
            $image_path = $this->request->variable('image_url', '', true);

            $amount_kobo = (int) $this->config['infozone_ads_default_amount_kobo'];
            $currency = $this->config['infozone_ads_currency'] ?: 'NGN';

            $sql_ary = [
                'created_at' => time(),
                'status' => 'pending',
                'fullname' => $fullname,
                'email' => $email,
                'phone' => $phone,
                'company' => $company,
                'target_url' => $target,
                'slots' => $slots,
                'duration_days' => max(1, (int)$duration),
                'ad_type' => $ad_type,
                'image_path' => $image_path,
                'html_code' => $html,
                'notes' => $notes,
                'amount_kobo' => $amount_kobo,
                'currency' => $currency,
            ];

            $sql = 'INSERT INTO ' . $this->db->get_table_prefix() . 'infozone_ad_requests' . ' ' . $this->db->sql_build_array('INSERT', $sql_ary);
            $this->db->sql_query($sql);
            $request_id = (int) $this->db->sql_nextid();

            // Redirect to payment init
            return $this->helper->route('infozone_ads_advertise_pay', ['id' => $request_id]);
        }

        $this->template->assign_vars([
            'S_ADVERTISE_ACTION' => $this->helper->route('infozone_ads_advertise'),
            'IZ_DEFAULT_AMOUNT' => (int) $this->config['infozone_ads_default_amount_kobo'],
            'IZ_CURRENCY' => $this->config['infozone_ads_currency'] ?: 'NGN',
        ]);

        return $this->helper->render('advertise_form.html', $this->user->lang('IZ_ADVERTISE_TITLE'));
    }

    public function pay($id = 0)
    {
        $this->language->add_lang('advertise', 'infozone/ads');

        $id = (int) $this->request->variable('id', 0);
        if (!$id) { trigger_error('NO_REQUEST'); }

        $public = trim((string) $this->config['infozone_ads_paystack_public']);
        $secret = trim((string) $this->config['infozone_ads_paystack_secret']);

        // If Paystack not configured, show message
        if ($public === '' || $secret === '')
        {
            $this->template->assign_vars([
                'MESSAGE_TITLE' => $this->user->lang('INFORMATION'),
                'MESSAGE_TEXT'  => $this->user->lang('IZ_ADVERTISE_PAYMENT_DISABLED'),
            ]);
            return $this->helper->render('message_body.html', $this->user->lang('INFORMATION'));
        }

        // Load request
        $sql = 'SELECT * FROM ' . $this->db->get_table_prefix() . 'infozone_ad_requests' . ' WHERE id = ' . $id;
        $result = $this->db->sql_query($sql);
        $row = $this->db->sql_fetchrow($result);
        $this->db->sql_freeresult($result);
        if (!$row) { trigger_error('NO_REQUEST'); }

        // Initialize Paystack transaction
        $callback = generate_board_url() . '/app.php/advertise/callback?id=' . $id;

        $payload = json_encode([
            'email' => $row['email'],
            'amount' => (int)$row['amount_kobo'],
            'currency' => $row['currency'],
            'callback_url' => $callback,
            'metadata' => ['request_id' => $id],
        ]);

        $ch = curl_init('https://api.paystack.co/transaction/initialize');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $secret,
            'Content-Type: application/json',
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
        $resp = curl_exec($ch);
        $err = curl_error($ch);
        curl_close($ch);

        if ($resp === false)
        {
            trigger_error('PAYMENT_ERROR: ' . htmlspecialchars($err));
        }

        $data = json_decode($resp, true);
        if (!is_array($data) || empty($data['status']))
        {
            trigger_error('PAYMENT_ERROR');
        }

        if (!$data['status'])
        {
            $msg = !empty($data['message']) ? $data['message'] : 'Payment error';
            trigger_error(htmlspecialchars($msg));
        }

        $auth_url = $data['data']['authorization_url'];
        redirect($auth_url);
    }

    public function callback()
    {
        $this->language->add_lang('advertise', 'infozone/ads');

        $id = (int) $this->request->variable('id', 0);
        $reference = $this->request->variable('reference', '', true);

        if (!$id || $reference === '')
        {
            trigger_error('INVALID_REQUEST');
        }

        $secret = trim((string) $this->config['infozone_ads_paystack_secret']);
        if ($secret === '') { trigger_error('PAYMENT_ERROR'); }

        // Verify Paystack transaction
        $ch = curl_init('https://api.paystack.co/transaction/verify/' . rawurlencode($reference));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $secret,
        ]);
        $resp = curl_exec($ch);
        curl_close($ch);

        $data = json_decode($resp, true);
        if (!is_array($data) || empty($data['status']) || !$data['status'])
        {
            trigger_error('PAYMENT_ERROR');
        }

        $status = $data['data']['status'] ?? '';
        if ($status !== 'success')
        {
            trigger_error('PAYMENT_NOT_SUCCESSFUL');
        }

        // Mark as paid
        $sql = 'UPDATE ' . $this->db->get_table_prefix() . 'infozone_ad_requests' . "
                SET status = 'paid', payment_ref = '" . $this->db->sql_escape($reference) . "'
                WHERE id = " . $id;
        $this->db->sql_query($sql);

        // Show success
        $this->template->assign_vars([
            'MESSAGE_TITLE' => $this->user->lang('INFORMATION'),
            'MESSAGE_TEXT'  => $this->user->lang('IZ_ADVERTISE_SUCCESS'),
        ]);

        return $this->helper->render('message_body.html', $this->user->lang('INFORMATION'));
    }
}
