<?php
/**
 * Export/Import REST API Controller
 *
 * @package VariationHub
 */

namespace VariationHub\API;

defined('ABSPATH') || exit;

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Writer\Csv;
use PhpOffice\PhpSpreadsheet\IOFactory;
use VariationHub\Core\License_Manager;

class Export_Import_Controller extends \WP_REST_Controller {

    /**
     * Namespace
     *
     * @var string
     */
    protected $namespace = 'variation-hub/v1';

    /**
     * Rest base
     *
     * @var string
     */
    protected $rest_base = 'export-import';

    /**
     * Register routes
     */
    public function register_routes() {
        // POST /export - Export variations to CSV/XLSX
        register_rest_route($this->namespace, '/' . $this->rest_base . '/export', [
            [
                'methods'             => \WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'export_variations'],
                'permission_callback' => [$this, 'export_permissions_check'],
                'args'                => $this->get_export_args(),
            ],
        ]);

        // POST /import - Import variations from CSV/XLSX
        register_rest_route($this->namespace, '/' . $this->rest_base . '/import', [
            [
                'methods'             => \WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'import_variations'],
                'permission_callback' => [$this, 'import_permissions_check'],
            ],
        ]);
    }

    /**
     * Export variations
     *
     * @param \WP_REST_Request $request Full request object.
     * @return \WP_REST_Response|\WP_Error
     */
    public function export_variations($request) {
        $params = $request->get_json_params();
        
        $format = isset($params['format']) ? $params['format'] : 'csv'; // csv or xlsx
        $variation_ids = isset($params['variation_ids']) ? $params['variation_ids'] : [];
        $all_variations = isset($params['all_variations']) ? $params['all_variations'] : false;

        // ✅ LICENSE CHECK 1: XLSX format (PRO only)
        if ($format === 'xlsx' && !License_Manager::has_feature('xlsx_export')) {
            return new \WP_Error(
                'variation_hub_xlsx_pro_only',
                __('XLSX export csak a Pro verzióban érhető el. Használj CSV formátumot vagy frissíts Pro verzióra!', 'variation-hub'),
                ['status' => 403]
            );
        }

        // Get variations
        if ($all_variations) {
            $variations = wc_get_products([
                'type' => 'variation',
                'limit' => -1,
                'status' => 'publish',
            ]);
        } else {
            $variations = array_map('wc_get_product', $variation_ids);
        }

        if (empty($variations)) {
            return new \WP_Error(
                'variation_hub_no_variations',
                __('Nincsenek exportálható variációk', 'variation-hub'),
                ['status' => 400]
            );
        }

        // ✅ LICENSE CHECK 2: CSV export limit (200 rows FREE)
        $csv_limit = License_Manager::get_limit('csv_export_limit');
        $original_count = count($variations);
        $is_limited = false;
        
        if ($csv_limit > 0 && $original_count > $csv_limit) {
            // Limit variations to FREE tier limit
            $variations = array_slice($variations, 0, $csv_limit);
            $is_limited = true;
        }

        try {
            // Create spreadsheet
            $spreadsheet = new Spreadsheet();
            $sheet = $spreadsheet->getActiveSheet();

        // Header row
        $headers = [
            'ID',
            'Szülő Termék',
            'SKU',
            'Kép URL',
            'Ár',
            'Akciós Ár',
            'Készlet',
            'Készlet Státusz',
            'Súly',
            'Hossz',
            'Szélesség',
            'Magasság',
        ];

        // Add attribute columns (collect all unique attributes)
        $all_attributes = [];
        foreach ($variations as $variation) {
            if ($variation) {
                $attributes = $variation->get_attributes();
                foreach ($attributes as $key => $value) {
                    if (!in_array($key, $all_attributes)) {
                        $all_attributes[] = $key;
                    }
                }
            }
        }

        foreach ($all_attributes as $attr) {
            $headers[] = 'Attribútum: ' . $attr;
        }

        // Write headers
        $col = 0;
        foreach ($headers as $header) {
            $colLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col + 1);
            $sheet->setCellValue($colLetter . '1', $header);
            $col++;
        }

        // Write data rows
        $row = 2;
        foreach ($variations as $variation) {
            if (!$variation) {
                continue;
            }

            $parent = wc_get_product($variation->get_parent_id());
            $image_id = $variation->get_image_id();

            $data = [
                $variation->get_id(),
                $parent ? $parent->get_name() : '',
                $variation->get_sku(),
                $image_id ? wp_get_attachment_image_url($image_id, 'full') : '',
                $variation->get_regular_price(),
                $variation->get_sale_price(),
                $variation->get_stock_quantity(),
                $variation->get_stock_status(),
                $variation->get_weight(),
                $variation->get_length(),
                $variation->get_width(),
                $variation->get_height(),
            ];

            // Add attribute values
            $attributes = $variation->get_attributes();
            foreach ($all_attributes as $attr) {
                $data[] = isset($attributes[$attr]) ? $attributes[$attr] : '';
            }

            // Write row
            $col = 0;
            foreach ($data as $value) {
                $colLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col + 1);
                $sheet->setCellValue($colLetter . $row, $value);
                $col++;
            }
            $row++;
        }

        // Generate file
        $timestamp = current_time('YmdHis');
        $filename = 'variations_export_' . $timestamp;

        if ($format === 'xlsx') {
            $writer = new Xlsx($spreadsheet);
            $filename .= '.xlsx';
            $content_type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
        } else {
            $writer = new Csv($spreadsheet);
            $filename .= '.csv';
            $content_type = 'text/csv';
        }

        // Write to temp file
        $temp_file = tempnam(sys_get_temp_dir(), 'varihu_export_');
        $writer->save($temp_file);

        // Read file content using WP_Filesystem
        require_once ABSPATH . 'wp-admin/includes/file.php';
        WP_Filesystem();
        global $wp_filesystem;
        $file_content = $wp_filesystem->get_contents($temp_file);
        wp_delete_file($temp_file);

        // Return file download response
        $response = [
            'success' => true,
            'filename' => $filename,
            'content' => base64_encode($file_content),
            'content_type' => $content_type,
            'count' => count($variations),
        ];

        // Add limit info if export was limited (frontend will format the message)
        if ($is_limited) {
            $response['limited'] = true;
            $response['exported'] = $csv_limit;
            $response['total'] = $original_count;
        }

        return new \WP_REST_Response($response, 200);
        
        } catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
            // ✅ IMPROVED ERROR HANDLING: Specific PhpSpreadsheet errors
            return new \WP_Error(
                'variation_hub_spreadsheet_error',
                sprintf(
                    /* translators: %s: error message */
                    __('Spreadsheet processing error: %s', 'variation-hub'),
                    $e->getMessage()
                ),
                ['status' => 500]
            );
        } catch (\Exception $e) {
            // ✅ IMPROVED ERROR HANDLING: Generic errors
            return new \WP_Error(
                'variation_hub_export_error',
                sprintf(
                    /* translators: %s: error message */
                    __('Export error: %s', 'variation-hub'),
                    $e->getMessage()
                ),
                ['status' => 500]
            );
        }
    }

    /**
     * Import variations
     *
     * @param \WP_REST_Request $request Full request object.
     * @return \WP_REST_Response|\WP_Error
     */
    public function import_variations($request) {
        $files = $request->get_file_params();

        if (!isset($files['file'])) {
            return new \WP_Error(
                'variation_hub_no_file',
                __('No file uploaded', 'variation-hub'),
                ['status' => 400]
            );
        }

        $file = $files['file'];
        $file_extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        
        // ✅ LICENSE CHECK 1: XLSX import (PRO only)
        if ($file_extension === 'xlsx' && !License_Manager::has_feature('xlsx_import')) {
            return new \WP_Error(
                'variation_hub_xlsx_import_pro',
                __('XLSX import csak a Pro verzióban érhető el. Használj CSV formátumot vagy frissíts Pro verzióra!', 'variation-hub'),
                ['status' => 403]
            );
        }
        
        // ✅ SECURITY FIX 1: File size limit (10MB)
        if ($file['size'] > 10 * 1024 * 1024) {
            return new \WP_Error(
                'variation_hub_file_too_large',
                __('File size exceeds 10MB limit', 'variation-hub'),
                ['status' => 400]
            );
        }
        
        // ✅ SECURITY FIX 2: Validate MIME type (not just extension)
        $allowed_mimes = [
            'text/csv',
            'text/plain', // CSV can be detected as text/plain
            'application/csv',
            'application/vnd.ms-excel', // CSV
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // XLSX
        ];
        
        $file_type = wp_check_filetype($file['name']);
        $mime_type = mime_content_type($file['tmp_name']);
        
        if (!in_array($mime_type, $allowed_mimes)) {
            return new \WP_Error(
                'variation_hub_invalid_mime',
                __('Invalid file type. Only CSV and XLSX files are allowed.', 'variation-hub'),
                ['status' => 400]
            );
        }
        
        // ✅ SECURITY FIX 3: Sanitize file path
        $file_path = realpath($file['tmp_name']);
        if ($file_path === false || !file_exists($file_path)) {
            return new \WP_Error(
                'variation_hub_invalid_path',
                __('Invalid file path', 'variation-hub'),
                ['status' => 400]
            );
        }
        
        $file_ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));

        if (!in_array($file_ext, ['csv', 'xlsx'])) {
            return new \WP_Error(
                'variation_hub_invalid_file',
                __('Invalid file format. Only CSV and XLSX supported.', 'variation-hub'),
                ['status' => 400]
            );
        }

        try {
            // Load spreadsheet
            $spreadsheet = IOFactory::load($file_path);
            $sheet = $spreadsheet->getActiveSheet();
            $rows = $sheet->toArray();

            if (empty($rows)) {
                return new \WP_Error(
                    'variation_hub_empty_file',
                    __('File is empty', 'variation-hub'),
                    ['status' => 400]
                );
            }

            // First row = headers
            $headers = array_shift($rows);
            
            // ✅ LICENSE CHECK 2: CSV import row limit (200 rows FREE)
            $import_limit = License_Manager::get_limit('csv_import_limit');
            $original_row_count = count($rows);
            
            if ($import_limit > 0 && $original_row_count > $import_limit) {
                $rows = array_slice($rows, 0, $import_limit);
                
                $limit_warning = sprintf(
                    /* translators: 1: imported count, 2: total count */
                    __('Ingyenes verzióban max %1$d sor importálható. %1$d / %2$d sor importálva. Frissíts Pro verzióra a teljes importhoz!', 'variation-hub'),
                    $import_limit,
                    $original_row_count
                );
            }
            
            $id_column = array_search('ID', $headers);
            $sku_column = array_search('SKU', $headers);
            $price_column = array_search('Ár', $headers);
            $sale_price_column = array_search('Akciós Ár', $headers);
            $stock_column = array_search('Készlet', $headers);

            $updated = 0;
            $errors = [];

            foreach ($rows as $index => $row) {
                $variation_id = $id_column !== false ? intval($row[$id_column]) : 0;

                if ($variation_id <= 0) {
                    continue; // Skip rows without valid ID
                }

                $variation = wc_get_product($variation_id);

                if (!$variation || $variation->get_type() !== 'variation') {
                    $errors[] = sprintf(
                        /* translators: 1: row number, 2: variation ID */
                        __('Row %1$d: Invalid variation ID (%2$d)', 'variation-hub'), 
                        $index + 2, 
                        $variation_id
                    );
                    continue;
                }
                
                // ✅ SECURITY FIX 4: Check permission to edit this specific variation
                $parent_id = $variation->get_parent_id();
                if (!current_user_can('edit_product', $parent_id) && !current_user_can('edit_post', $parent_id)) {
                    $errors[] = sprintf(
                        /* translators: 1: row number, 2: variation ID */
                        __('Row %1$d: You do not have permission to edit variation %2$d', 'variation-hub'),
                        $index + 2,
                        $variation_id
                    );
                    continue;
                }

                // Update fields (with proper sanitization)
                if ($sku_column !== false && !empty($row[$sku_column])) {
                    $variation->set_sku(sanitize_text_field($row[$sku_column]));
                }

                if ($price_column !== false && !empty($row[$price_column])) {
                    // ✅ SECURITY FIX 5: Validate price is positive number
                    $price = floatval($row[$price_column]);
                    if ($price >= 0) {
                        $variation->set_regular_price($price);
                    }
                }

                if ($sale_price_column !== false && !empty($row[$sale_price_column])) {
                    // ✅ SECURITY FIX 6: Validate sale price is positive number
                    $sale_price = floatval($row[$sale_price_column]);
                    if ($sale_price >= 0) {
                        $variation->set_sale_price($sale_price);
                    }
                }

                if ($stock_column !== false && isset($row[$stock_column]) && $row[$stock_column] !== '') {
                    // ✅ SECURITY FIX 7: Allow negative stock (backorders), but validate integer
                    $stock = intval($row[$stock_column]);
                    $variation->set_stock_quantity($stock);
                }

                $variation->save();
                $updated++;
            }

            $response = [
                'success' => true,
                'message' => sprintf(
                    /* translators: %d: number of variations updated */
                    __('%d variations updated successfully', 'variation-hub'), 
                    $updated
                ),
                'data' => [
                    'updated' => $updated,
                    'errors' => $errors,
                ],
            ];
            
            // Add limit warning if applicable
            if (isset($limit_warning)) {
                $response['warning'] = $limit_warning;
                $response['limited'] = true;
                $response['limit'] = $import_limit;
                $response['total'] = $original_row_count;
            }

            return rest_ensure_response($response);

        } catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
            // ✅ IMPROVED ERROR HANDLING: Specific PhpSpreadsheet errors
            return new \WP_Error(
                'variation_hub_spreadsheet_error',
                sprintf(
                    /* translators: %s: error message */
                    __('Spreadsheet processing error: %s', 'variation-hub'),
                    $e->getMessage()
                ),
                ['status' => 500]
            );
        } catch (\Exception $e) {
            // ✅ IMPROVED ERROR HANDLING: Generic errors
            return new \WP_Error(
                'variation_hub_import_error',
                sprintf(
                    /* translators: %s: error message */
                    __('Import error: %s', 'variation-hub'),
                    $e->getMessage()
                ),
                ['status' => 500]
            );
        }
    }

    /**
     * Check permissions for export
     *
     * @param \WP_REST_Request $request Full request object.
     * @return bool
     */
    public function export_permissions_check($request) {
        return current_user_can('manage_woocommerce');
    }

    /**
     * Check permissions for import
     *
     * @param \WP_REST_Request $request Full request object.
     * @return bool
     */
    public function import_permissions_check($request) {
        return current_user_can('manage_woocommerce');
    }

    /**
     * Get export args
     *
     * @return array
     */
    protected function get_export_args() {
        return [
            'format' => [
                'description' => __('Export format', 'variation-hub'),
                'type'        => 'string',
                'enum'        => ['csv', 'xlsx'],
                'default'     => 'csv',
            ],
            'variation_ids' => [
                'description' => __('Variáció ID-k tömbje', 'variation-hub'),
                'type'        => 'array',
                'items'       => ['type' => 'integer'],
            ],
            'all_variations' => [
                'description' => __('Összes variáció exportálása', 'variation-hub'),
                'type'        => 'boolean',
                'default'     => false,
            ],
        ];
    }
}
