<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ — NUCLEAR+++
// File: /includes/class-business-profile.php
// Description: Data access layer for amai_business_profile table - NUCLEAR+++
// Last Edited: 2026-04-11
// ==================================================

namespace AutoMarketerAI;

// No direct access
defined('ABSPATH') || exit;

final class BusinessProfile
{
    private const TABLE_SUFFIX = 'amai_business_profile';
    private const DEFAULT_TENANT = 'default';

    // Valid values for enum columns — used for input validation
    public const VALID_WEBSITE_STATUS   = ['has_website', 'no_website', 'declined_to_share'];
    public const VALID_TONE             = ['warm_personal', 'professional_informative', 'witty_light'];
    public const VALID_SELLS_ONLINE     = ['yes_store_ready', 'yes_wants_to', 'sells_services', 'no'];
    public const VALID_AGE_RANGE        = ['under_25', '25_to_40', '40_to_55', '55_plus', 'mixed'];
    public const VALID_POSTING_MODE     = ['approve_first', 'autopilot'];
    public const VALID_REVIEW_DAYS      = [0, 1, 2, 3, 4, 5, 6]; // 0=Sun … 6=Sat

    // Onboarding step constants — progression gates
    public const STEP_NOT_STARTED  = 0;
    public const STEP_BASICS       = 1; // website, category, tone
    public const STEP_AUDIENCE     = 2; // location, sells_online, customer descriptor
    public const STEP_VOICE        = 3; // differentiator, values
    public const STEP_COMPLETED    = 4;

    public const BUSINESS_CATEGORIES = [
        'restaurant_cafe'       => 'Restaurant / Café',
        'retail_shop'           => 'Retail Shop',
        'health_wellness'       => 'Health & Wellness',
        'beauty_salon'          => 'Beauty & Salon',
        'home_services'         => 'Home Services (plumber, electrician, etc.)',
        'professional_services' => 'Professional Services (legal, accounting, etc.)',
        'fitness_sports'        => 'Fitness & Sports',
        'automotive'            => 'Automotive',
        'real_estate'           => 'Real Estate',
        'education_training'    => 'Education & Training',
        'tech_software'         => 'Technology & Software',
        'creative_agency'       => 'Creative & Agency',
        'nonprofit'             => 'Non-Profit / Community',
        'hospitality_travel'    => 'Hospitality & Travel',
        'medical_dental'        => 'Medical & Dental',
        'pet_services'          => 'Pet Services',
        'events_entertainment'  => 'Events & Entertainment',
        'food_beverage_product' => 'Food & Beverage (product)',
        'construction_trades'   => 'Construction & Trades',
        'childcare_family'      => 'Childcare & Family Services',
        'ecommerce'             => 'eCommerce / Online Store',
        'other'                 => 'Other - I\'ll describe it',
    ];

    private string $table;

    public function __construct()
    {
        global $wpdb;
        $this->table = $wpdb->prefix . self::TABLE_SUFFIX;
    }

    // Returns the profile row for a tenant, or null if not yet created
    public function get(string $tenant_id = self::DEFAULT_TENANT): ?array
    {
        global $wpdb;

        $row = $wpdb->get_row(
            $wpdb->prepare(
                "SELECT * FROM `{$this->table}` WHERE tenant_id = %s LIMIT 1",
                $tenant_id
            ),
            ARRAY_A
        );

        if (!is_array($row)) {
            return null;
        }

        return $row;
    }

    // Creates the profile row with defaults if it does not exist
    // Returns the existing or newly created profile
    public function getOrCreate(string $tenant_id = self::DEFAULT_TENANT): array
    {
        $existing = $this->get($tenant_id);

        if ($existing !== null) {
            return $existing;
        }

        global $wpdb;

        $wpdb->insert(
            $this->table,
            [
                'tenant_id'      => $tenant_id,
                'onboarding_step' => self::STEP_NOT_STARTED,
            ],
            ['%s', '%d']
        );

        $profile = $this->get($tenant_id);

        if (!is_array($profile)) {
            // Should never happen — insert succeeded but get failed
            wp_die('[AutoMarketer AI] Failed to create business profile row.');
        }

        return $profile;
    }

    // Updates one or more fields on the profile row
    // Only whitelisted columns are accepted — everything else is silently ignored
    public function update(array $data, string $tenant_id = self::DEFAULT_TENANT): bool
    {
        global $wpdb;

        $clean = $this->sanitize($data);

        if (empty($clean)) {
            return false;
        }

        $result = $wpdb->update(
            $this->table,
            $clean,
            ['tenant_id' => $tenant_id]
        );

        return $result !== false;
    }

    // Advances the onboarding step if the new step is higher than current
    public function advanceStep(int $step, string $tenant_id = self::DEFAULT_TENANT): bool
    {
        global $wpdb;

        if ($step < self::STEP_NOT_STARTED || $step > self::STEP_COMPLETED) {
            return false;
        }

        $result = $wpdb->query(
            $wpdb->prepare(
                "UPDATE `{$this->table}`
                 SET onboarding_step = %d,
                     onboarding_completed_at = CASE WHEN %d = %d THEN NOW() ELSE onboarding_completed_at END
                 WHERE tenant_id = %s
                   AND onboarding_step < %d",
                $step,
                $step,
                self::STEP_COMPLETED,
                $tenant_id,
                $step
            )
        );

        return $result !== false;
    }

    // Returns true if the onboarding flow is complete
    public function isOnboardingComplete(string $tenant_id = self::DEFAULT_TENANT): bool
    {
        global $wpdb;

        $step = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT onboarding_step FROM `{$this->table}` WHERE tenant_id = %s LIMIT 1",
                $tenant_id
            )
        );

        return (int) $step === self::STEP_COMPLETED;
    }

    // Sanitizes and validates the incoming data map against the allowed column whitelist
    private function sanitize(array $data): array
    {
        $clean = [];

        $string_cols = [
            'website_url', 'business_category', 'business_category_other',
            'customer_descriptor', 'differentiator', 'values_and_causes',
        ];

        $int_cols = [
            'has_physical_location', 'website_lead_captured',
            'post_time_hour', 'draft_review_day', 'onboarding_step',
        ];

        $enum_cols = [
            'website_status'  => self::VALID_WEBSITE_STATUS,
            'business_tone'   => self::VALID_TONE,
            'sells_online'    => self::VALID_SELLS_ONLINE,
            'customer_age_range' => self::VALID_AGE_RANGE,
            'posting_mode'    => self::VALID_POSTING_MODE,
        ];

        foreach ($string_cols as $col) {
            if (!array_key_exists($col, $data)) {
                continue;
            }
            $val = sanitize_text_field((string) $data[$col]);
            if ($col === 'website_url') {
                $val = esc_url_raw($val);
            }
            $clean[$col] = $val;
        }

        foreach ($int_cols as $col) {
            if (!array_key_exists($col, $data)) {
                continue;
            }
            $val = (int) $data[$col];

            if ($col === 'post_time_hour' && ($val < 0 || $val > 23)) {
                continue;
            }
            if ($col === 'draft_review_day' && !in_array($val, self::VALID_REVIEW_DAYS, true)) {
                continue;
            }
            if ($col === 'onboarding_step' && ($val < 0 || $val > self::STEP_COMPLETED)) {
                continue;
            }

            $clean[$col] = $val;
        }

        foreach ($enum_cols as $col => $valid) {
            if (!array_key_exists($col, $data)) {
                continue;
            }
            $val = (string) $data[$col];
            if (in_array($val, $valid, true)) {
                $clean[$col] = $val;
            }
        }

        // differentiator and values_and_causes allow longer text
        if (array_key_exists('differentiator', $data)) {
            $clean['differentiator'] = sanitize_textarea_field((string) $data['differentiator']);
        }
        if (array_key_exists('values_and_causes', $data)) {
            $clean['values_and_causes'] = sanitize_textarea_field((string) $data['values_and_causes']);
        }

        // facebook_bio — long text, textarea sanitize
        if (array_key_exists('facebook_bio', $data)) {
            $clean['facebook_bio'] = sanitize_textarea_field((string) $data['facebook_bio']);
        }

        return $clean;
    }
}