<?php

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

class AIEO_Event_Importer {

    
    const MAX_ROWS = 20000;

    
    public static function parse_file($path, $ext) {
        $ext  = strtolower((string) $ext);
        $rows = ($ext === 'csv') ? self::read_csv($path) : self::read_xlsx($path);

        if (!is_array($rows) || count($rows) === 0) {
            return new WP_Error('aieo_events_parse', __('Could not read the file, or it has no rows. Upload a .xlsx or .csv that has a header row and at least one participant.', 'ai-eshop-optimizer'));
        }

        
        $header     = array();
        $header_idx = -1;
        foreach ($rows as $idx => $r) {
            if (self::row_is_empty($r)) { continue; }
            $header     = $r;
            $header_idx = $idx;
            break;
        }
        if ($header_idx < 0) {
            return new WP_Error('aieo_events_empty', __('The file has no data rows.', 'ai-eshop-optimizer'));
        }

        $map = self::map_headers($header);
        if (!isset($map['email'])) {
            return new WP_Error('aieo_events_noemail', __('No “Email” column was found. Add a header row with an Email column. Other recognised columns: Salutation, Title, Name, Surname, Department, Organization, Phone.', 'ai-eshop-optimizer'));
        }

        $data = array();
        foreach ($rows as $idx => $r) {
            if ($idx <= $header_idx || self::row_is_empty($r)) { continue; }
            if (count($data) >= self::MAX_ROWS) { break; }
            $assoc = array('_rownum' => $idx + 1); 
            foreach ($map as $key => $col) {
                $assoc[$key] = isset($r[$col]) ? trim((string) $r[$col]) : '';
            }
            $data[] = $assoc;
        }
        return $data;
    }

    
    public static function run_import($event_id, array $rows, $mode, $user_id) {
        global $wpdb;
        $summary  = array('total' => 0, 'inserted' => 0, 'updated' => 0, 'removed' => 0, 'skipped' => 0, 'errors' => array());
        $event_id = (int) $event_id;
        $user_id  = (int) $user_id;
        $mode     = ($mode === 'overwrite') ? 'overwrite' : 'update';

        if ($event_id <= 0 || !class_exists('AIEO_Event_Participants')) {
            $summary['errors'][] = __('Invalid event or participants store unavailable.', 'ai-eshop-optimizer');
            return $summary;
        }
        $tbl = AIEO_Event_Participants::table();

        
        $batch = substr(gmdate('YmdHis') . '_' . $user_id, 0, 32);

        $upserted_ids = array();
        foreach ($rows as $r) {
            $summary['total']++;
            $rownum = isset($r['_rownum']) ? (int) $r['_rownum'] : ($summary['total'] + 1);
            $email  = isset($r['email']) ? strtolower(trim((string) $r['email'])) : '';

            if ($email === '' || !is_email($email)) {
                $summary['skipped']++;
                $summary['errors'][] = ($email === '')
                    ? sprintf(__('Row %d: missing email — skipped.', 'ai-eshop-optimizer'), $rownum)
                    : sprintf(__('Row %1$d: invalid email “%2$s” — skipped.', 'ai-eshop-optimizer'), $rownum, $email);
                continue;
            }

            $existing = (int) $wpdb->get_var($wpdb->prepare(
                "SELECT participant_id FROM {$tbl} WHERE event_id = %d AND email = %s LIMIT 1",
                $event_id, $email
            ));

            $pid = AIEO_Event_Participants::upsert(
                $event_id,
                array(
                    'title'        => isset($r['title'])        ? $r['title']        : '',
                    'salutation'   => isset($r['salutation'])   ? $r['salutation']   : '',
                    'first_name'   => isset($r['first_name'])   ? $r['first_name']   : '',
                    'last_name'    => isset($r['last_name'])    ? $r['last_name']    : '',
                    'department'   => isset($r['department'])   ? $r['department']   : '',
                    'organization' => isset($r['organization']) ? $r['organization'] : '',
                    'email'        => $email,
                    'phone'        => isset($r['phone'])        ? $r['phone']        : '',
                ),
                'imported',
                $user_id,
                $batch
            );

            if ($pid <= 0) {
                $summary['skipped']++;
                $summary['errors'][] = sprintf(__('Row %1$d: could not save “%2$s”.', 'ai-eshop-optimizer'), $rownum, $email);
                continue;
            }
            if ($existing > 0) { $summary['updated']++; } else { $summary['inserted']++; }
            $upserted_ids[] = (int) $pid;
        }

        
        if ($mode === 'overwrite' && !empty($upserted_ids)) {
            $ph     = implode(',', array_fill(0, count($upserted_ids), '%d'));
            $params = array_merge(array($event_id, $user_id), $upserted_ids);
            $removed = $wpdb->query($wpdb->prepare(
                "DELETE FROM {$tbl}
                  WHERE event_id = %d AND imported_by = %d AND source = 'imported'
                    AND participant_id NOT IN ($ph)",
                ...$params
            ));
            $summary['removed'] = max(0, (int) $removed);
        }

        return $summary;
    }

    

    private static function read_xlsx($path) {
        if (!class_exists('AIEO_DMM_XLSX_Reader') && defined('AIEO_DIR')) {
            $f = AIEO_DIR . 'includes/dmm/services/class-aieo-dmm-xlsx-reader.php';
            if (file_exists($f)) { require_once $f; }
        }
        return class_exists('AIEO_DMM_XLSX_Reader') ? AIEO_DMM_XLSX_Reader::read($path) : null;
    }

    
    private static function read_csv($path) {
        if (!is_readable($path)) { return null; }
        $fh = fopen($path, 'r');
        if (!$fh) { return null; }

        
        $bom = fread($fh, 3);
        if ($bom !== "\xEF\xBB\xBF") { rewind($fh); }

        
        $pos   = ftell($fh);
        $first = (string) fgets($fh);
        if ($pos !== false) { fseek($fh, $pos); }
        $delim = (substr_count($first, ';') > substr_count($first, ',')) ? ';' : ',';

        $rows = array();
        while (($data = fgetcsv($fh, 0, $delim)) !== false) {
            $rows[] = array_map(static function ($v) { return (string) $v; }, (array) $data);
        }
        fclose($fh);
        return $rows;
    }

    

    private static function row_is_empty($row) {
        foreach ((array) $row as $v) {
            if (trim((string) $v) !== '') { return false; }
        }
        return true;
    }

    private static function map_headers($header_row) {
        $aliases = self::header_aliases();
        $map     = array();
        foreach ((array) $header_row as $col => $label) {
            $norm = self::normalize_header($label);
            if ($norm === '') { continue; }
            foreach ($aliases as $key => $list) {
                if (isset($map[$key])) { continue; } 
                if (in_array($norm, $list, true)) { $map[$key] = (int) $col; break; }
            }
        }
        return $map;
    }

    
    private static function normalize_header($s) {
        $s = (string) $s;
        $s = function_exists('mb_strtolower') ? mb_strtolower($s, 'UTF-8') : strtolower($s);
        $s = strtr($s, array(
            'ά' => 'α', 'έ' => 'ε', 'ή' => 'η', 'ί' => 'ι', 'ό' => 'ο', 'ύ' => 'υ', 'ώ' => 'ω',
            'ϊ' => 'ι', 'ϋ' => 'υ', 'ΐ' => 'ι', 'ΰ' => 'υ', 'ς' => 'σ',
        ));
        $s = preg_replace('/[^\p{L}\p{N}]+/u', ' ', $s);
        $s = trim((string) preg_replace('/\s+/u', ' ', $s));
        return $s;
    }

    
    private static function header_aliases() {
        return array(
            'salutation'   => array('salutation', 'prosfonisi', 'προσφωνηση', 'greeting', 'χαιρετισμοσ'),
            'title'        => array('title', 'τιτλοσ', 'honorific', 'mr mrs', 'mr mrs dr', 'mr', 'mrs', 'dr'),
            'first_name'   => array('name', 'first name', 'firstname', 'first', 'given name', 'onoma', 'ονομα', 'μικρο ονομα'),
            'last_name'    => array('surname', 'last name', 'lastname', 'last', 'family name', 'eponymo', 'επωνυμο'),
            'department'   => array('department', 'dept', 'tmima', 'τμημα', 'υπηρεσια', 'service', 'position', 'θεση'),
            'organization' => array('organization', 'organisation', 'company', 'org', 'organismos', 'οργανισμοσ', 'εταιρεια', 'etaireia', 'φορεασ', 'foreas'),
            'email'        => array('email', 'e mail', 'mail', 'email address', 'e mail address', 'ηλεκτρονικο ταχυδρομειο'),
            'phone'        => array('phone', 'telephone', 'tel', 'τηλ', 'tilefono', 'τηλεφωνο', 'mobile', 'kinito', 'κινητο', 'phone number', 'telephone number', 'contact', 'επικοινωνια'),
        );
    }
}
