<?php
namespace Components\Models;

/**
 * Coupons model supporting multiple platforms.
 * - Table structure differs on Zen Cart vs. other systems.
 * - We ignore Zen Cart–only fields when MH_PLATFORM != 'zencart' to avoid DB errors.
 */
class Coupon extends BaseModel
{
    protected static string $table = 'TABLE_COUPONS';
    protected static string $primaryKey = 'coupon_id';

    // Optional model-level blueprint (resolved by CrudController)
    protected static string $blueprint = 'coupon.yaml';

    /**
     * List of columns that exist only on Zen Cart installations.
     * These will be stripped on save when MH_PLATFORM != 'zencart'.
     */
    protected static array $zenCartOnly = [
        'restrict_to_products', // varchar(255) in zencart vs text in others — keep key but safe to strip if platform mismatch
        'restrict_to_categories', // varchar(255) in zencart vs text in others
        'restrict_to_customers', // text exists in both; kept here for safety if schema differences
        'coupon_zone_restriction',
        'coupon_calc_base',
        'coupon_order_limit',
        'coupon_is_valid_for_sales',
        'coupon_product_count',
    ];

    /**
     * Hook to sanitize data before saving.
     * - On non-ZenCart platforms, remove ZenCart-only columns from the payload.
     * - Also coerce date defaults to platform expectations when fields are empty.
     * - Strip i18n fields that belong to coupons_description when present in form payload.
     */
    protected function filterAttributesForSave(array $data): array
    {
        $platform = function_exists('mh_cfg') ? (string) mh_cfg('MH_PLATFORM', '') : '';
        $isZen = strtolower($platform) === 'zencart';

        if (!$isZen) {
            foreach (self::$zenCartOnly as $col) {
                if (array_key_exists($col, $data)) {
                    unset($data[$col]);
                }
            }
        }

        // Remove translation arrays from main table payload
        foreach (['coupon_name','coupon_description'] as $tx) {
            if (array_key_exists($tx, $data)) { unset($data[$tx]); }
        }

        // Map UI helper fields to canonical coupon_amount based on coupon_type
        $type = strtoupper(trim((string)($data['coupon_type'] ?? '')));
        $amtPercent = isset($data['coupon_amount_percent']) ? (string)$data['coupon_amount_percent'] : '';
        $amtFixed = isset($data['coupon_amount_fixed']) ? (string)$data['coupon_amount_fixed'] : '';
        $setAmount = null;
        if ($type === 'P') {
            // percentage as-is (e.g., 10 => 10%)
            if ($amtPercent === '' && isset($data['coupon_amount'])) { $amtPercent = (string)$data['coupon_amount']; }
            if ($amtPercent !== '') {
                $num = is_numeric($amtPercent) ? (float)$amtPercent : (float)preg_replace('/[^0-9.\-]/', '', $amtPercent);
                $setAmount = number_format($num, 4, '.', '');
            } else {
                $setAmount = '0.0000';
            }
        } elseif ($type === 'F') {
            // fixed currency amount
            if ($amtFixed === '' && isset($data['coupon_amount'])) { $amtFixed = (string)$data['coupon_amount']; }
            if ($amtFixed !== '') {
                $num = is_numeric($amtFixed) ? (float)$amtFixed : (float)preg_replace('/[^0-9.\-]/', '', $amtFixed);
                $setAmount = number_format($num, 4, '.', '');
            } else {
                $setAmount = '0.0000';
            }
        } elseif ($type === 'S') {
            // free shipping -> amount not used
            $setAmount = '0.0000';
        }
        if ($setAmount !== null) {
            $data['coupon_amount'] = $setAmount;
        }
        // Drop UI-only fields
        unset($data['coupon_amount_percent'], $data['coupon_amount_fixed']);

        // Normalize date defaults if empty
        // ZenCart uses '0001-01-01 00:00:00', others often use '0000-00-00 00:00:00'
        $dateZeroOther = '0000-00-00 00:00:00';
        $dateZeroZen = '0001-01-01 00:00:00';
        $startKey = 'coupon_start_date';
        $endKey = 'coupon_expire_date';
        $createdKey = 'date_created';
        $modifiedKey = 'date_modified';

        foreach ([$startKey, $endKey, $createdKey, $modifiedKey] as $k) {
            if (!array_key_exists($k, $data) || $data[$k] === '' || $data[$k] === null) {
                $data[$k] = $isZen ? $dateZeroZen : $dateZeroOther;
            }
        }

        return $data;
    }

    public function icon() {
        switch ($this->attributes['coupon_type']) {
            case 'F':
                return ['svg' => \Components\Base::SVG_OUTLINE_MONEY, 'color' => self::getCouponTypeColor('F'), 'size' => 'sm'];
            case 'P':
                return ['svg' => \Components\Base::SVG_VOUCHER, 'color' => self::getCouponTypeColor('P'), 'size' => 'sm'];
            case 'S':
                default:
                return ['svg' => \Components\Base::SVG_OUTLINE_TRUCK, 'color' => self::getCouponTypeColor('S'), 'size' => 'sm'];
        }
    }

    static public function getCouponTypeColor($type) {
        $map = [
            'F' => 'green',
            'P' => 'orange',
            'S' => 'blue',
        ];
        return $map[$type] ?? 'gray';
    }

    /**
     * Augment form values with i18n translations from coupons_description so they can be edited in the same dialog.
     * @param array $values
     * @return array
     */
    public function augmentFormValues(array $values): array
    {
        $id = (int)($values[static::$primaryKey] ?? $this->{static::$primaryKey} ?? 0);
        if ($id > 0) {
            try {
                $all = CouponDescription::forCoupon($id);
                $names = [];
                $descs = [];
                foreach ($all as $lid => $row) {
                    $names[$lid] = (string)($row['coupon_name'] ?? '');
                    $descs[$lid] = (string)($row['coupon_description'] ?? '');
                }
                $values['coupon_name'] = $names;
                $values['coupon_description'] = $descs;
            } catch (\Throwable $e) { /* ignore */ }
        }
        // Prefill UI helper fields for amount based on coupon_type
        try {
            $type = strtoupper(trim((string)($values['coupon_type'] ?? $this->coupon_type ?? '')));
            $amt = (string)($values['coupon_amount'] ?? $this->coupon_amount ?? '');
            if ($amt !== '') {
                if ($type === 'P') {
                    $values['coupon_amount_percent'] = $amt;
                } elseif ($type === 'F') {
                    $values['coupon_amount_fixed'] = $amt;
                }
            }
        } catch (\Throwable $e) { /* ignore */ }
        return $values;
    }

    /**
     * Persist translations posted as coupon_name[langId] and coupon_description[langId].
     */
    public function afterSave(array $post): void
    {
        $id = (int)($this->{static::$primaryKey} ?? 0);
        if ($id <= 0) return;
        $names = isset($post['coupon_name']) && is_array($post['coupon_name']) ? $post['coupon_name'] : [];
        $descs = isset($post['coupon_description']) && is_array($post['coupon_description']) ? $post['coupon_description'] : [];
        $map = [];
        // Prefer live env language list for stable ids
        $langIds = [];
        if (function_exists('mh_get_language_list')) {
            try {
                foreach ((array)\mh_get_language_list() as $lg) {
                    if (is_array($lg) && isset($lg['id'])) { $langIds[] = (int)$lg['id']; }
                }
            } catch (\Throwable $e) { $langIds = []; }
        }
        // If not available, derive from submitted keys
        if (empty($langIds)) {
            $langIds = array_unique(array_map('intval', array_merge(array_keys($names), array_keys($descs))));
        }
        foreach ($langIds as $lid) {
            $lid = (int)$lid; if ($lid <= 0) continue;
            $nm = isset($names[$lid]) ? trim((string)$names[$lid]) : '';
            $dc = isset($descs[$lid]) ? (string)$descs[$lid] : '';
            if ($nm === '' && $dc === '') continue; // nothing to store
            $map[$lid] = [ 'coupon_name' => $nm, 'coupon_description' => $dc ];
        }
        if (!empty($map)) {
            try { CouponDescription::syncForCoupon($id, $map); } catch (\Throwable $e) { /* ignore */ }
        }
    }
}
