<?php

declare(strict_types=1);

namespace Admin\Controllers;

/**
 * Admin Offer Popup Controller
 *
 * Dedicated controller for managing the offer popup on the landing page.
 * Separate from general settings for easier management and debugging.
 */
class AdminOfferPopupController extends AdminController
{
    /**
     * Display the offer popup settings form.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function index(array $params = []): void
    {
        requireAdmin();

        // Fetch all offer_popup_* settings
        $settings = $this->getOfferPopupSettings();

        $this->adminView('offer_popup', [
            'title'       => 'Offer Popup',
            'currentPage' => 'offer-popup',
            'settings'    => $settings,
        ]);
    }

    /**
     * Update the offer popup settings.
     *
     * @param array<string, string> $params Route parameters
     * @return void
     */
    public function update(array $params = []): void
    {
        requireAdmin();
        $this->validateCsrf();

        $keys = [
            'offer_popup_enabled',
            'offer_popup_title',
            'offer_popup_description',
            'offer_popup_image',
            'offer_popup_link',
            'offer_popup_link_text',
        ];

        $fileKeys = ['offer_popup_image'];
        $updated = 0;

        foreach ($keys as $key) {
            // Handle file upload
            if (in_array($key, $fileKeys, true)) {
                $filePath = $this->handleImageUpload($key, 'settings');
                if ($filePath !== null) {
                    // Delete old image
                    $oldStmt = $this->db->prepare(
                        'SELECT `setting_value` FROM `settings` WHERE `setting_key` = :key LIMIT 1'
                    );
                    $oldStmt->execute([':key' => $key]);
                    $oldPath = $oldStmt->fetchColumn();
                    if ($oldPath && $oldPath !== $filePath) {
                        $this->deleteImageFile((string) $oldPath);
                    }

                    $this->upsertSetting($key, $filePath);
                    $updated++;
                }
                continue;
            }

            // For offer_popup_enabled (checkbox/select)
            if ($key === 'offer_popup_enabled') {
                // If the checkbox isn't checked, it won't be in POST — set to '0'
                $value = isset($_POST['offer_popup_enabled']) ? '1' : '0';
                $this->upsertSetting($key, $value);
                $updated++;
                continue;
            }

            // All other text fields
            if (!isset($_POST[$key])) {
                continue;
            }

            $value = sanitize($_POST[$key]);
            $this->upsertSetting($key, $value);
            $updated++;
        }

        flash('success', "Offer popup settings saved. ({$updated} fields updated)");
        redirect(BASE_PATH . '/admin/offer-popup');
    }

    /**
     * Insert or update a setting value.
     *
     * @param string $key The setting key
     * @param string $value The setting value
     * @return void
     */
    private function upsertSetting(string $key, string $value): void
    {
        // IMPORTANT: The settings table has DUAL unique columns:
        //   key_name (UNIQUE) + value (TEXT)  — old schema
        //   setting_key (UNIQUE) + setting_value (TEXT)  — new schema
        // We must write to BOTH pairs, otherwise the empty key_name=''
        // causes UNIQUE constraint collisions that corrupt data.
        $stmt = $this->db->prepare(
            'INSERT INTO `settings` (`key_name`, `value`, `setting_key`, `setting_value`)
             VALUES (:key, :value, :key2, :value2)
             ON DUPLICATE KEY UPDATE `setting_value` = :value3, `value` = :value4'
        );
        $stmt->execute([
            ':key'    => $key,
            ':value'  => $value,
            ':key2'   => $key,
            ':value2' => $value,
            ':value3' => $value,
            ':value4' => $value,
        ]);
    }

    /**
     * Get all offer popup settings as an associative array.
     *
     * @return array<string, string>
     */
    private function getOfferPopupSettings(): array
    {
        $defaults = [
            'offer_popup_enabled'     => '0',
            'offer_popup_title'       => '',
            'offer_popup_description' => '',
            'offer_popup_image'       => '',
            'offer_popup_link'        => '',
            'offer_popup_link_text'   => 'Learn More',
        ];

        try {
            // Try setting_key / setting_value first (new schema)
            $stmt = $this->db->prepare(
                'SELECT `setting_key`, `setting_value` FROM `settings` WHERE `setting_key` LIKE :pattern'
            );
            $stmt->execute([':pattern' => 'offer_popup_%']);
            $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC) ?: [];

            $settings = $defaults;
            foreach ($rows as $row) {
                if (!empty($row['setting_key'])) {
                    $settings[$row['setting_key']] = $row['setting_value'];
                }
            }

            // Also check key_name / value (old schema) for any missing values
            $stmt2 = $this->db->prepare(
                'SELECT `key_name`, `value` FROM `settings` WHERE `key_name` LIKE :pattern'
            );
            $stmt2->execute([':pattern' => 'offer_popup_%']);
            $rows2 = $stmt2->fetchAll(\PDO::FETCH_ASSOC) ?: [];
            foreach ($rows2 as $row) {
                $kn = $row['key_name'] ?? '';
                if (!empty($kn) && isset($defaults[$kn])) {
                    // Only use old schema value if new schema still has the default
                    if ($settings[$kn] === $defaults[$kn]) {
                        $settings[$kn] = $row['value'];
                    }
                }
            }

            return $settings;
        } catch (\Throwable $e) {
            error_log('AdminOfferPopupController::getOfferPopupSettings error: ' . $e->getMessage());
            return $defaults;
        }
    }
}
