<?php
/**
 * Plugin Name: NewCap Leasing Calculator
 * Description: Leasing calculator with tiered factor rules (new vs existing) + clean backend settings.
 * Version: 2.0.0
 * Author: Bowden Works
 * Author URI: https://bowdenworks.com
 * License: GPLv2 or later
 */

if ( ! defined('ABSPATH') ) exit;

class NewCap_Leasing_Calculator_v2 {
    const OPT_KEY          = 'newcap_leasing_calc_v2';
    const HANDLE_JS        = 'newcap-leasing-v2-js';
    const HANDLE_CSS       = 'newcap-leasing-v2-css';
    const HANDLE_ADMIN_CSS = 'newcap-leasing-admin-css'; // <-- new
    const NONCE            = 'nc_lease_v2_nonce';
    const SHORTCODE        = 'newcap_leasing_calculator';

    public function __construct() {
        // Admin
        add_action('admin_menu',            [$this, 'add_menu']);
        add_action('admin_init',            [$this, 'register_settings']);
        add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']);

        // Front
        add_action('wp_enqueue_scripts',    [$this, 'register_assets']);
        add_shortcode(self::SHORTCODE,      [$this, 'shortcode_ui']);

        // AJAX
        add_action('wp_ajax_nc_calc_v2_compute',        [$this, 'ajax_compute']);
        add_action('wp_ajax_nopriv_nc_calc_v2_compute', [$this, 'ajax_compute']);
    }

    /** Load CSS only on this plugin's settings page */
    public function enqueue_admin_assets($hook) {
        // The hook for "Settings → NewCap Calculator" is:
        // 'settings_page_newcap-leasing-calculator-v2'
        if ($hook !== 'settings_page_newcap-leasing-calculator-v2') return;

        $url  = plugin_dir_url(__FILE__) . 'assets/admin.css';
        $path = plugin_dir_path(__FILE__) . 'assets/admin.css';

        // Use filemtime for cache-busting when editing
        wp_enqueue_style(self::HANDLE_ADMIN_CSS, $url, [], @filemtime($path) ?: '1.0.0');
    }

    /** Defaults exactly as per the table you provided */
    public static function defaults() {
        return [
            'currency'      => '$',
            'thousands_sep' => ',',
            'decimal_sep'   => '.',
            'contact_url'   => '', // can be left empty
            'max_amount'    => 75000, // > 75k → "Contact us for quote"
            'labels'        => [
                'title'       => 'NewCap Leasing Calculator',
                'amount'      => 'Equipment Cost',
                'business'    => 'Business Type',
                'old_label'   => 'Established (2+ years)',
                'new_label'   => 'New Business',
                'term'        => 'Term',
                'calculate'   => 'Calculate',
                'reset'       => 'Reset',
                'result'      => 'Your estimated monthly payment is:',
                'quote'       => 'Contact us for quote',
                'na'          => 'N/A'
            ],
            // FACTOR TABLES (editable in Settings)
            'factors' => [
                'new' => [
                    // New business: 24/36 only
                    [
                        'range' => ['min' => 0, 'max' => 9999.99], // lcost < 10,000
                        'terms' => [
                            '24' => 0.0515,
                            '36' => 0.0378,
                        ],
                        'label' => '< 10,000'
                    ],
                    [
                        'range' => ['min' => 10000, 'max' => 75000], // 10,000 ≤ lcost ≤ 75,000
                        'terms' => [
                            '24' => 0.0514,
                            '36' => 0.0375,
                        ],
                        'label' => '10,000 – 75,000'
                    ],
                ],
                'old' => [
                    [
                        'range' => ['min' => 0, 'max' => 9998.99], // lcost < 9,999
                        'terms' => [
                            '24' => 0.0490,
                            '36' => 0.0345,
                            '48' => 0.0270,
                            '60' => 0.0226,
                        ],
                        'label' => '< 9,999'
                    ],
                    [
                        'range' => ['min' => 9999, 'max' => 39999.99], // 9,999 ≤ lcost < 40,000
                        'terms' => [
                            '24' => 0.0480,
                            '36' => 0.0340,
                            '48' => 0.0261,
                            '60' => 0.0220,
                        ],
                        'label' => '9,999 – 39,999'
                    ],
                    [
                        'range' => ['min' => 40000, 'max' => 75000], // 40,000 ≤ lcost ≤ 75,000
                        'terms' => [
                            '24' => 0.0475,
                            '36' => 0.0335,
                            '48' => 0.0264,
                            '60' => 0.0218,
                        ],
                        'label' => '40,000 – 75,000'
                    ],
                ],
            ],
        ];
    }

    private function settings() {
        $saved = get_option(self::OPT_KEY, []);
        return wp_parse_args($saved, self::defaults());
    }

    /* ---------------- Admin Settings ---------------- */

    public function add_menu() {
        add_options_page(
            'NewCap Leasing Calculator',
            'NewCap Calculator',
            'manage_options',
            'newcap-leasing-calculator-v2',
            [$this, 'render_settings']
        );
    }

    public function register_settings() {
        register_setting(self::OPT_KEY, self::OPT_KEY, [
            'type'              => 'array',
            'sanitize_callback' => [$this, 'sanitize_settings'],
            'default'           => self::defaults(),
        ]);

        add_settings_section('ncv2_main', 'Calculator Settings', function(){
            echo '<p>Configure currency, number separators, and the factor tables per tier. Use a dot for decimals.</p>';
        }, self::OPT_KEY);

        add_settings_field('currency', 'Currency & Separators', function(){
            $s = $this->settings();
            printf(
                '<label>Currency <input type="text" name="%1$s[currency]" value="%2$s" style="width:80px"></label> &nbsp; '.
                '<label>Thousands <input type="text" name="%1$s[thousands_sep]" value="%3$s" style="width:60px"></label> &nbsp; '.
                '<label>Decimal <input type="text" name="%1$s[decimal_sep]" value="%4$s" style="width:60px"></label>',
                esc_attr(self::OPT_KEY),
                esc_attr($s['currency']),
                esc_attr($s['thousands_sep']),
                esc_attr($s['decimal_sep'])
            );
        }, self::OPT_KEY, 'ncv2_main');

        add_settings_field('max_amount', 'Max Amount (contact quote if above)', function(){
            $s = $this->settings();
            printf('<input type="number" step="0.01" name="%1$s[max_amount]" value="%2$s" style="width:140px"> %3$s',
                esc_attr(self::OPT_KEY),
                esc_attr($s['max_amount']),
                esc_html($s['currency'])
            );
        }, self::OPT_KEY, 'ncv2_main');

        add_settings_field('factors_new', 'Factors: New Business (24/36 only)', function(){
            $s  = $this->settings();
            $fs = $s['factors']['new'];
            echo '<table class="widefat striped nc-admin-factors" style="max-width:1080px">';
            echo '<thead><tr><th style="width:160px">Tier</th><th style="width:220px">Range (min – max)</th><th>24</th><th>36</th></tr></thead><tbody>';
            foreach ($fs as $i => $row) {
                printf(
                    '<tr>
                        <td><input name="%1$s[factors][new][%2$d][label]" value="%3$s" style="width:150px"></td>
                        <td>
                            <input type="number" step="0.01" name="%1$s[factors][new][%2$d][range][min]" value="%4$s" style="width:100px"> – 
                            <input type="number" step="0.01" name="%1$s[factors][new][%2$d][range][max]" value="%5$s" style="width:100px">
                        </td>
                        <td><input type="number" step="0.0001" name="%1$s[factors][new][%2$d][terms][24]" value="%6$s" style="width:120px"></td>
                        <td><input type="number" step="0.0001" name="%1$s[factors][new][%2$d][terms][36]" value="%7$s" style="width:120px"></td>
                    </tr>',
                    esc_attr(self::OPT_KEY), $i,
                    esc_attr($row['label']),
                    esc_attr($row['range']['min']),
                    esc_attr($row['range']['max']),
                    esc_attr($row['terms']['24']),
                    esc_attr($row['terms']['36'])
                );
            }
            echo '</tbody></table>';
            echo '<p class="description">New business has no 48/60. If forced on the front-end → N/A.</p>';
        }, self::OPT_KEY, 'ncv2_main');

        add_settings_field('factors_old', 'Factors: Existing Business (24/36/48/60)', function(){
            $s  = $this->settings();
            $fs = $s['factors']['old'];
            echo '<table class="widefat striped nc-admin-factors" style="max-width:1080px">';
            echo '<thead><tr><th style="width:160px">Tier</th><th style="width:240px">Range (min – max)</th><th>24</th><th>36</th><th>48</th><th>60</th></tr></thead><tbody>';
            foreach ($fs as $i => $row) {
                printf(
                    '<tr>
                        <td><input name="%1$s[factors][old][%2$d][label]" value="%3$s" style="width:150px"></td>
                        <td>
                            <input type="number" step="0.01" name="%1$s[factors][old][%2$d][range][min]" value="%4$s" style="width:100px"> – 
                            <input type="number" step="0.01" name="%1$s[factors][old][%2$d][range][max]" value="%5$s" style="width:100px">
                        </td>
                        <td><input type="number" step="0.0001" name="%1$s[factors][old][%2$d][terms][24]" value="%6$s" style="width:100px"></td>
                        <td><input type="number" step="0.0001" name="%1$s[factors][old][%2$d][terms][36]" value="%7$s" style="width:100px"></td>
                        <td><input type="number" step="0.0001" name="%1$s[factors][old][%2$d][terms][48]" value="%8$s" style="width:100px"></td>
                        <td><input type="number" step="0.0001" name="%1$s[factors][old][%2$d][terms][60]" value="%9$s" style="width:100px"></td>
                    </tr>',
                    esc_attr(self::OPT_KEY), $i,
                    esc_attr($row['label']),
                    esc_attr($row['range']['min']),
                    esc_attr($row['range']['max']),
                    esc_attr($row['terms']['24']),
                    esc_attr($row['terms']['36']),
                    esc_attr($row['terms']['48']),
                    esc_attr($row['terms']['60'])
                );
            }
            echo '</tbody></table>';
        }, self::OPT_KEY, 'ncv2_main');
        
        add_settings_field('contact_url', 'Contact Us Page URL', function(){
            $s = $this->settings();
            printf(
                '<input type="url" name="%1$s[contact_url]" value="%2$s" style="width:420px" placeholder="https://example.com/contact-us">',
                esc_attr(self::OPT_KEY),
                esc_attr(isset($s['contact_url']) ? $s['contact_url'] : '')
            );
            echo '<p class="description">URL of the “Contact Us” page to link to when the value exceeds the 75,000 threshold.</p>';
        }, self::OPT_KEY, 'ncv2_main');
    }

    public function sanitize_settings($input) {
        $d = self::defaults();
        $out = $d;

        $out['currency']      = isset($input['currency']) ? sanitize_text_field($input['currency']) : $d['currency'];
        $out['thousands_sep'] = isset($input['thousands_sep']) ? sanitize_text_field($input['thousands_sep']) : $d['thousands_sep'];
        $out['decimal_sep']   = isset($input['decimal_sep']) ? sanitize_text_field($input['decimal_sep']) : $d['decimal_sep'];
        $out['max_amount']    = isset($input['max_amount']) ? floatval($input['max_amount']) : $d['max_amount'];
        // ⬅️ Add this line so the URL is saved
        $out['contact_url']   = isset($input['contact_url']) ? esc_url_raw($input['contact_url']) : '';

        // Factors (new/old)
        foreach (['new','old'] as $biz) {
            if (!empty($input['factors'][$biz]) && is_array($input['factors'][$biz])) {
                $rows = [];
                foreach ($input['factors'][$biz] as $row) {
                    $label = isset($row['label']) ? sanitize_text_field($row['label']) : '';
                    $min   = isset($row['range']['min']) ? floatval($row['range']['min']) : 0;
                    $max   = isset($row['range']['max']) ? floatval($row['range']['max']) : 0;
                    $terms = isset($row['terms']) && is_array($row['terms']) ? $row['terms'] : [];

                    $clean_terms = [];
                    foreach ($terms as $t => $v) {
                        $clean_terms[(string)intval($t)] = floatval(str_replace(',', '.', $v));
                    }
                    if ($max >= $min) {
                        $rows[] = [
                            'label' => $label,
                            'range' => ['min'=>$min,'max'=>$max],
                            'terms' => $clean_terms
                        ];
                    }
                }
                // sort by min
                usort($rows, function($a,$b){ return $a['range']['min'] <=> $b['range']['min']; });
                $out['factors'][$biz] = $rows;
            }
        }
        return $out;
    }

    public function render_settings() {
        ?>
        <div class="wrap">
            <h1>NewCap Leasing Calculator</h1>
            <form method="post" action="options.php">
                <?php
                settings_fields(self::OPT_KEY);
                do_settings_sections(self::OPT_KEY);
                submit_button();
                ?>
            </form>
        </div>
        <?php
    }

    /* ---------------- Frontend ---------------- */

    public function register_assets() {
        $url = plugin_dir_url(__FILE__) . 'assets/';
        wp_register_style(self::HANDLE_CSS, $url.'calculator.css', [], '2.0.0');
        wp_register_script(self::HANDLE_JS,  $url.'calculator.js',  [], '2.0.0', true);

        $s = $this->settings();
        wp_localize_script(self::HANDLE_JS, 'NewcapCalcV2', [
            'ajaxUrl'      => admin_url('admin-ajax.php'),
            'nonce'        => wp_create_nonce(self::NONCE),
            'currency'     => $s['currency'],
            'thousandsSep' => $s['thousands_sep'],
            'decimalSep'   => $s['decimal_sep'],
            'maxAmount'    => floatval($s['max_amount']),
            'labels'       => $s['labels'],
        ]);
    }

    public function shortcode_ui($atts = []) {
        wp_enqueue_style(self::HANDLE_CSS);
        wp_enqueue_script(self::HANDLE_JS);

        $s   = $this->settings();
        $lbl = $s['labels'];

        ob_start(); ?>
        <div class="nc-calc" data-currency="<?php echo esc_attr($s['currency']); ?>">
            <form class="nc-calc__form" onsubmit="return false;">
                <div class="nc-calc__title"><?php echo esc_html($lbl['title']); ?></div>

                <!-- Field names as requested -->
                <label class="nc-calc__label" for="nc-lcost"><?php echo esc_html($lbl['amount']); ?></label>
                <!-- <input type="text" inputmode="decimal" id="nc-lcost" name="lcost" class="nc-calc__input" placeholder="e.g. $40,000.00"> -->
                <input type="number" id="nc-lcost" name="lcost"
                    class="nc-calc__input"
                    placeholder="e.g. 40000.00"
                    inputmode="decimal"
                    step="0.01"
                    min="0">

                <div class="nc-calc__group">
                    <div class="nc-calc__label"><?php echo esc_html($lbl['business']); ?></div>
                    <label class="nc-calc__radio">
                        <input type="radio" name="chk" value="old" checked> <?php echo esc_html($lbl['old_label']); ?>
                    </label>
                    <label class="nc-calc__radio">
                        <input type="radio" name="chk" value="new"> <?php echo esc_html($lbl['new_label']); ?>
                    </label>
                </div>

                <label class="nc-calc__label" for="describe"><?php echo esc_html($lbl['term']); ?></label>
                <select id="describe" class="nc-calc__select">
                    <!-- default existing: 24/36/48/60 -->
                    <option value="24" selected>24 months</option>
                    <option value="36">36 months</option>
                    <option value="48">48 months</option>
                    <option value="60">60 months</option>
                </select>

                <div class="nc-calc__actions">
                    <button type="button" class="nc-calc__btn" id="nc-calc-btn"><?php echo esc_html($lbl['calculate']); ?></button>
                    <button type="button" class="nc-calc__btn nc-calc__btn--ghost" id="nc-reset-btn"><?php echo esc_html($lbl['reset']); ?></button>
                </div>

                <div class="nc-calc__result" aria-live="polite">
                    <div class="nc-calc__result-row">
                        <span class="nc-calc__result-label"><?php echo esc_html($lbl['result']); ?></span>
                        <span class="nc-calc__result-value" id="nc-result"><?php echo esc_html($s['currency']); ?>0.00</span>
                    </div>
                    
                    <!-- Extra disclaimer -->
                    <div class="nc-calc__disclaimer">
                        *Numbers based on approved credit. For equipment over $75,000, please contact us for a custom quote.
                    </div>
                </div>
            </form>
        </div>
        <?php
        return ob_get_clean();
    }

    /* ---------------- AJAX ---------------- */

    public function ajax_compute() {
        check_ajax_referer(self::NONCE, 'nonce');

        $s = $this->settings();

        $raw_amount = isset($_POST['lcost']) ? (string) $_POST['lcost'] : '';
        $biz        = isset($_POST['chk']) ? sanitize_text_field($_POST['chk']) : 'old'; // 'old' | 'new'
        $term       = isset($_POST['term']) ? (string) intval($_POST['term']) : '24';

        // Normalize number: drop thousands, convert decimal to dot
        $amt = $this->normalize_amount($raw_amount, $s['thousands_sep'], $s['decimal_sep']);

        if (!is_finite($amt) || $amt <= 0) {
            wp_send_json_success(['status' => 'na', 'display' => $s['labels']['na']]);
        }

        // Rule: above max_amount → contact us
        if ($amt > floatval($s['max_amount'])) {
            $quote = $s['labels']['quote'];
            if (!empty($s['contact_url'])) {
                $quote = '<a href="' . esc_url($s['contact_url']) . '" class="nc-calc__quote-link" target="_blank" rel="noopener">' . esc_html($quote) . '</a>';
            }
            wp_send_json_success(['status' => 'quote', 'display' => $quote]);
        }

        // Validate allowed terms by business type
        if ($biz === 'new' && !in_array($term, ['24','36'], true)) {
            wp_send_json_success(['status' => 'na', 'display' => $s['labels']['na']]);
        }
        if ($biz === 'old' && !in_array($term, ['24','36','48','60'], true)) {
            wp_send_json_success(['status' => 'na', 'display' => $s['labels']['na']]);
        }

        // Find factor by tier
        $factor = $this->find_factor($s['factors'][$biz], $amt, $term);
        if ($factor === null) {
            // No tier/term found → N/A
            wp_send_json_success(['status' => 'na', 'display' => $s['labels']['na']]);
        }

        // monthlyPayment = lcost * termPercent
        $payment = $amt * $factor;
        $formatted = $this->format_money($payment, $s['currency'], $s['thousands_sep'], $s['decimal_sep']);

        wp_send_json_success([
            'status'   => 'ok',
            'payment'  => round($payment, 2),
            'display'  => $formatted
        ]);
    }

    private function normalize_amount($str, $thou, $dec) {
        $s = trim((string)$str);
        if ($thou) $s = str_replace($thou, '', $s);
        if ($dec && $dec !== '.') $s = str_replace($dec, '.', $s);
        $n = floatval($s);
        return is_finite($n) ? $n : 0;
    }

    private function find_factor($rows, $amount, $term) {
        foreach ($rows as $row) {
            $min = floatval($row['range']['min']);
            $max = floatval($row['range']['max']);
            if ($amount >= $min && $amount <= $max) {
                if (isset($row['terms'][$term])) {
                    return floatval($row['terms'][$term]);
                }
            }
        }
        return null;
    }

    private function format_money($num, $currency, $thou, $dec) {
        return $currency . number_format((float)$num, 2, $dec, $thou);
    }
}

new NewCap_Leasing_Calculator_v2();
