<?php

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

class AIEO_TRS_CSV {

    const COLUMNS = array(
        'shipping_method_id',
        'rate_class',
        'rate_condition',
        'rate_min',
        'rate_max',
        'rate_cost',
        'rate_cost_per_item',
        'rate_cost_per_weight_unit',
        'rate_cost_percent',
        'rate_label',
        'rate_priority',
        'rate_order',
        'rate_abort',
        'rate_abort_reason',
        'enabled',
    );

    
    public static function export($shipping_method_id = null) {
        global $wpdb;
        $table = $wpdb->prefix . 'aieo_dmm_shipping_rates';
        $cols  = '`' . implode('`,`', self::COLUMNS) . '`';

        if ($shipping_method_id === null) {
            $rows = $wpdb->get_results("SELECT $cols FROM {$table} ORDER BY shipping_method_id ASC, rate_order ASC, id ASC", ARRAY_A);
        } else {
            $rows = $wpdb->get_results(
                $wpdb->prepare("SELECT $cols FROM {$table} WHERE shipping_method_id = %d ORDER BY rate_order ASC, id ASC", (int) $shipping_method_id),
                ARRAY_A
            );
        }
        $rows = is_array($rows) ? $rows : array();

        $fp = fopen('php://temp', 'w+');
        fputcsv($fp, self::COLUMNS);
        foreach ($rows as $row) {
            $line = array();
            foreach (self::COLUMNS as $c) {
                $line[] = $row[$c] === null ? '' : (string) $row[$c];
            }
            fputcsv($fp, $line);
        }
        rewind($fp);
        $csv = stream_get_contents($fp);
        fclose($fp);
        return $csv;
    }

    
    public static function import($csv_body, $default_method_id = 0) {
        $result = array('ok' => true, 'inserted' => 0, 'updated' => 0, 'skipped' => 0, 'errors' => array());
        if (!is_string($csv_body) || $csv_body === '') {
            $result['ok'] = false;
            $result['errors'][] = __('Empty CSV body.', 'ai-eshop-optimizer');
            return $result;
        }

        $fp = fopen('php://temp', 'w+');
        fwrite($fp, $csv_body);
        rewind($fp);

        $header = fgetcsv($fp);
        if (!is_array($header)) {
            fclose($fp);
            $result['ok'] = false;
            $result['errors'][] = __('CSV header row could not be parsed.', 'ai-eshop-optimizer');
            return $result;
        }
        $header = array_map(static function ($h) { return strtolower(trim((string) $h)); }, $header);
        $col_idx = array_flip($header);

        
        
        
        foreach (array('rate_class', 'rate_condition', 'rate_cost') as $req) {
            if (!isset($col_idx[$req])) {
                fclose($fp);
                $result['ok'] = false;
                $result['errors'][] = sprintf(
                    
                    __('CSV is missing required column: %s', 'ai-eshop-optimizer'),
                    $req
                );
                return $result;
            }
        }

        $line_no = 1;
        while (($row = fgetcsv($fp)) !== false) {
            $line_no++;
            if (empty(array_filter($row, static function ($v) { return $v !== '' && $v !== null; }))) {
                continue; 
            }

            $data = array();
            foreach ($header as $i => $col) {
                $data[$col] = $row[$i] ?? '';
            }
            if (empty($data['shipping_method_id']) && $default_method_id > 0) {
                $data['shipping_method_id'] = $default_method_id;
            }

            $check = AIEO_TRS_Validator::validate($data);
            if (empty($check['ok'])) {
                $result['skipped']++;
                $result['errors'][] = sprintf(
                    
                    __('Line %1$d: %2$s', 'ai-eshop-optimizer'),
                    $line_no,
                    implode('; ', $check['errors'])
                );
                continue;
            }
            $clean = $check['data'];

            
            
            $existing_id = self::find_match_id(
                (int)    $clean['shipping_method_id'],
                (string) $clean['rate_class'],
                (string) $clean['rate_condition'],
                $clean['rate_min'],
                $clean['rate_max']
            );

            if ($existing_id > 0) {
                $r = AIEO_TRS_Rules::update($existing_id, $clean);
                if (!empty($r['ok'])) {
                    $result['updated']++;
                } else {
                    $result['skipped']++;
                    $result['errors'][] = sprintf(
                        
                        __('Line %1$d update failed: %2$s', 'ai-eshop-optimizer'),
                        $line_no,
                        (string) ($r['error'] ?? 'unknown')
                    );
                }
            } else {
                $r = AIEO_TRS_Rules::create($clean);
                if (!empty($r['ok'])) {
                    $result['inserted']++;
                } else {
                    $result['skipped']++;
                    $result['errors'][] = sprintf(
                        
                        __('Line %1$d insert failed: %2$s', 'ai-eshop-optimizer'),
                        $line_no,
                        (string) ($r['error'] ?? 'unknown')
                    );
                }
            }
        }

        fclose($fp);
        $result['ok'] = empty($result['errors']) || ($result['inserted'] + $result['updated']) > 0;
        return $result;
    }

    
    private static function find_match_id($method_id, $class, $condition, $min, $max) {
        global $wpdb;
        $table = $wpdb->prefix . 'aieo_dmm_shipping_rates';

        $where  = array('shipping_method_id = %d', 'rate_class = %s', 'rate_condition = %s');
        $params = array((int) $method_id, (string) $class, (string) $condition);

        $where[] = ($min === null) ? 'rate_min IS NULL' : 'rate_min = %f';
        if ($min !== null) { $params[] = (float) $min; }

        $where[] = ($max === null) ? 'rate_max IS NULL' : 'rate_max = %f';
        if ($max !== null) { $params[] = (float) $max; }

        $sql = "SELECT id FROM {$table} WHERE " . implode(' AND ', $where) . ' LIMIT 1';
        return (int) $wpdb->get_var($wpdb->prepare($sql, ...$params));
    }
}
