<?php
if (!defined('ABSPATH')) exit;

class AIIO_Backup {

    public static function uploads_dir() {
        $dir = aiio_backup_root('pewit-ai-image-optimizer');
        self::protect_dir($dir);
        return $dir;
    }

    public static function backup_dir_for($attachment_id) {
        $attachment_id = intval($attachment_id);
        $dir = trailingslashit(self::uploads_dir()) . $attachment_id . '/';
        if (!file_exists($dir)) {
            wp_mkdir_p($dir);
        }
        return $dir;
    }

    public static function has_backup($attachment_id) {
        $meta = self::get_backup_meta($attachment_id);
        if (empty($meta['file']) || !is_file($meta['file'])) {
            return false;
        }
        return true;
    }

    /**
     * @return array|WP_Error
     */
    public static function backup($attachment_id) {

        $attachment_id = intval($attachment_id);
        if (!$attachment_id || get_post_type($attachment_id) !== 'attachment') {
            return new WP_Error('aiio_backup_invalid', __('Invalid attachment.', 'pewit-ai-image-optimizer'));
        }

        $source = get_attached_file($attachment_id);
        if (!$source || !is_file($source)) {
            return new WP_Error('aiio_backup_missing', __('Original file not found.', 'pewit-ai-image-optimizer'));
        }

        $dir = self::backup_dir_for($attachment_id);
        $dest = $dir . 'original-' . sanitize_file_name(basename($source));
        if (!@copy($source, $dest)) {
            return new WP_Error('aiio_backup_copy', __('Could not create backup copy.', 'pewit-ai-image-optimizer'));
        }

        $meta = [
            'attachment_id' => $attachment_id,
            'file' => wp_normalize_path($dest),
            'original_path' => wp_normalize_path($source),
            'mime' => get_post_mime_type($attachment_id),
            'metadata' => wp_get_attachment_metadata($attachment_id),
            'stored_file' => get_post_meta($attachment_id, '_wp_attached_file', true),
            'webp_file' => get_post_meta($attachment_id, '_aiio_webp_file', true),
            'avif_file' => get_post_meta($attachment_id, '_aiio_avif_file', true),
            'av1_webm_file' => get_post_meta($attachment_id, '_aiio_av1_webm_file', true),
            'created_at' => current_time('mysql'),
            'created_ts' => time(),
        ];

        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents -- Local backup metadata in private uploads dir.
        file_put_contents($dir . 'meta.json', wp_json_encode($meta, JSON_PRETTY_PRINT));
        update_post_meta($attachment_id, '_aiio_backup_file', $dest);
        update_post_meta($attachment_id, '_aiio_backup_at', current_time('mysql'));

        return [
            'attachment_id' => $attachment_id,
            'backup_file' => $dest,
            'dir' => $dir,
        ];
    }

    /**
     * @return array|WP_Error
     */
    public static function rollback($attachment_id) {

        $attachment_id = intval($attachment_id);
        $meta = self::get_backup_meta($attachment_id);
        if (empty($meta['file']) || !is_file($meta['file'])) {
            return new WP_Error('aiio_rollback_missing', __('No backup found for this image.', 'pewit-ai-image-optimizer'));
        }

        $target = get_attached_file($attachment_id);
        if (!$target) {
            return new WP_Error('aiio_rollback_target', __('Could not resolve attachment path.', 'pewit-ai-image-optimizer'));
        }

        if (!@copy($meta['file'], $target)) {
            return new WP_Error('aiio_rollback_copy', __('Could not restore backup file.', 'pewit-ai-image-optimizer'));
        }

        if (!empty($meta['metadata']) && is_array($meta['metadata'])) {
            wp_update_attachment_metadata($attachment_id, $meta['metadata']);
        }
        if (!empty($meta['stored_file'])) {
            update_post_meta($attachment_id, '_wp_attached_file', $meta['stored_file']);
        }

        $webp = get_post_meta($attachment_id, '_aiio_webp_file', true);
        if ($webp && is_file($webp)) {
            wp_delete_file($webp);
        }
        delete_post_meta($attachment_id, '_aiio_webp_file');
        delete_post_meta($attachment_id, '_aiio_webp_url');

        $avif = get_post_meta($attachment_id, '_aiio_avif_file', true);
        if ($avif && is_file($avif)) {
            wp_delete_file($avif);
        }
        delete_post_meta($attachment_id, '_aiio_avif_file');
        delete_post_meta($attachment_id, '_aiio_avif_url');

        if (class_exists('AIIO_Video_Optimizer')) {
            AIIO_Video_Optimizer::remove_sidecar($attachment_id);
        }

        delete_post_meta($attachment_id, '_aiio_last_optimized');
        delete_post_meta($attachment_id, '_aiio_saved_bytes');

        $regenerated = wp_generate_attachment_metadata($attachment_id, $target);
        if (!is_wp_error($regenerated) && !empty($regenerated)) {
            wp_update_attachment_metadata($attachment_id, $regenerated);
        }

        return [
            'attachment_id' => $attachment_id,
            'restored_bytes' => filesize($target),
            'message' => __('Image restored from backup.', 'pewit-ai-image-optimizer'),
        ];
    }

    public static function get_backup_meta($attachment_id) {
        $attachment_id = intval($attachment_id);
        $dir = self::backup_dir_for($attachment_id);
        $json = $dir . 'meta.json';
        if (is_file($json)) {
            // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_get_contents -- Local backup metadata in private uploads dir.
            $data = json_decode(file_get_contents($json), true);
            if (is_array($data)) {
                return $data;
            }
        }

        $file = get_post_meta($attachment_id, '_aiio_backup_file', true);
        if ($file && is_file($file)) {
            return [
                'attachment_id' => $attachment_id,
                'file' => $file,
                'original_path' => get_attached_file($attachment_id),
                'created_at' => get_post_meta($attachment_id, '_aiio_backup_at', true),
            ];
        }

        return [];
    }

    private static function protect_dir($dir) {
        $htaccess = trailingslashit($dir) . '.htaccess';
        if (!file_exists($htaccess)) {
            // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents -- Directory hardening for private uploads dir.
            file_put_contents($htaccess, "Options -Indexes\n<FilesMatch \"\\.(php|phtml|php3|php4|php5|phps|cgi|pl|exe)$\">\nDeny from all\n</FilesMatch>\n");
        }
        $index = trailingslashit($dir) . 'index.html';
        if (!file_exists($index)) {
            // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents -- Directory hardening for private uploads dir.
            file_put_contents($index, '');
        }
    }
}
