<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}
function drop_print_run_update() {
    $current_version = defined( 'DROP_PRINT_VERSION' )
        ? DROP_PRINT_VERSION
        : '0.0.0';
    $installed_version = get_option( 'drop_print_client_version', false );
    if ( $installed_version !== false ) {
        if ( version_compare( $installed_version, '1.1.3', '<' ) ) {
            drop_print_migrate_113();
            $installed_version = '1.1.3';
        }
        if ( version_compare( $installed_version, '1.1.5', '<' ) ) {
            drop_print_migrate_115();
            $installed_version = '1.1.5';
        }
        if ( version_compare( $installed_version, '2.0', '<' ) ) {
            $migration_complete = drop_print_migrate_20();
            if ( $migration_complete ) {
                $installed_version = '2.0';
            }
        }
    } else {
        $installed_version = $current_version;
        update_option( 'drop_print_20_migration_complete', 1, false );
    }
    if ( ! get_option( 'drop_print_204_sku_case_migration_complete' ) ) {
        $migration_complete = drop_print_migrate_204();
        if ( $migration_complete && version_compare( $installed_version, '2.0.4', '<' ) ) {
            $installed_version = '2.0.4';
        }
    }
    if ( ! get_option( 'drop_print_205_exif_dimension_migration_v2_complete' ) ) {
        $migration_complete = drop_print_migrate_205();
        if ( $migration_complete && version_compare( $installed_version, '2.0.5', '<' ) ) {
            $installed_version = '2.0.5';
        }
    }
    update_option(
        'drop_print_client_version',
        $installed_version,
        false
    );
}
function drop_print_migrate_113() {
    $user_ids = get_users(
        array(
            'fields' => 'ids',
        )
    );
    foreach ( $user_ids as $user_id ) {
        $settings = get_user_meta(
            $user_id,
            'drop_print_user_settings',
            true
        );
        if ( ! is_array( $settings ) ) {
            continue;
        }
        if ( ! array_key_exists( 'encryption', $settings ) ) {
            $settings['encryption'] = true;
            update_user_meta(
                $user_id,
                'drop_print_user_settings',
                $settings
            );
        }
    }
}
function drop_print_migrate_115() {
    if ( ! function_exists( 'drop_print_files_normalize_raw' ) ) {
        return;
    }
    $index = drop_print_files_normalize_raw( get_option( 'drop_print_files', array() ) );
    $product_ids = get_posts(
        array(
            'post_type'              => 'product',
            'post_status'            => 'any',
            'posts_per_page'         => -1,
            'fields'                 => 'ids',
            'no_found_rows'          => true,
            'update_post_meta_cache' => false,
            'update_post_term_cache' => false,
            'meta_key'               => '_drop_print_meta',
        )
    );
    foreach ( $product_ids as $product_id ) {
        $product_id = absint( $product_id );
        $meta       = get_post_meta( $product_id, '_drop_print_meta', true );
        if ( ! is_array( $meta ) || empty( $meta['file'] ) ) {
            continue;
        }
        $key = drop_print_files_canonical_key( (string) $meta['file'] );
        if ( '' === $key ) {
            continue;
        }
        if ( ! isset( $index['files'][ $key ] ) || ! is_array( $index['files'][ $key ] ) ) {
            $index['files'][ $key ] = array( 'product_ids' => array() );
        }
        if ( ! in_array( $product_id, $index['files'][ $key ]['product_ids'], true ) ) {
            $index['files'][ $key ]['product_ids'][] = $product_id;
        }
        if ( ! empty( $meta['source_sha256'] ) && is_string( $meta['source_sha256'] ) ) {
            if ( empty( $index['files'][ $key ]['source_sha256'] ) ) {
                $index['files'][ $key ]['source_sha256']    = sanitize_text_field( $meta['source_sha256'] );
                $index['files'][ $key ]['sha256_provenance'] = 'upload';
            }
            unset( $meta['source_sha256'] );
            update_post_meta( $product_id, '_drop_print_meta', $meta );
        }
    }
    $base_dir = defined( 'DROP_PRINT_UPLOAD_BASE_DIR' )
        ? DROP_PRINT_UPLOAD_BASE_DIR
        : trailingslashit( wp_upload_dir()['basedir'] ) . 'drop-print';
    foreach ( $index['files'] as $key => $record ) {
        $container_path = function_exists( 'drop_print_container_path' )
            ? drop_print_container_path( $base_dir, (string) $key )
            : trailingslashit( $base_dir ) . $key . '.afp';
        if ( ! file_exists( $container_path ) ) {
            $index['files'][ $key ]['missing_on_disk'] = true;
            continue;
        }
        unset( $index['files'][ $key ]['missing_on_disk'] );
        if ( empty( $record['file_size'] ) ) {
            $index['files'][ $key ]['file_size'] = (int) filesize( $container_path );
        }
        if ( empty( $record['created_at'] ) ) {
            $index['files'][ $key ]['created_at'] = (int) filemtime( $container_path );
        }
        if ( empty( $record['container_sha256'] ) ) {
            $container_hash = hash_file( 'sha256', $container_path );
            if ( false !== $container_hash ) {
                $index['files'][ $key ]['container_sha256'] = $container_hash;
            }
        }
        if ( ! isset( $record['encrypted'] ) || empty( $record['source_sha256'] ) ) {
            $header = function_exists( 'drop_print_files_parse_container_header' ) ? drop_print_files_parse_container_header( $container_path ) : null;
            if ( is_array( $header ) ) {
                if ( ! isset( $record['encrypted'] ) ) {
                    $index['files'][ $key ]['encrypted'] = (bool) $header['encrypted'];
                }
                if ( empty( $record['source_sha256'] ) && ! empty( $header['source_sha256'] ) ) {
                    $index['files'][ $key ]['source_sha256']    = $header['source_sha256'];
                    $index['files'][ $key ]['sha256_provenance'] = 'backfilled_from_header';
                }
            }
        }
    }
    $index['schema_version'] = 2;
    delete_option( 'drop_print_files' );
    add_option( 'drop_print_files', $index, '', 'no' );
}
function drop_print_migrate_20() {
    if ( ! function_exists( 'drop_print_files_get_index' ) ) {
        update_option( 'drop_print_20_migration_complete', 1, false );
        return true;
    }
    $base_dir = defined( 'DROP_PRINT_UPLOAD_BASE_DIR' )
        ? DROP_PRINT_UPLOAD_BASE_DIR
        : trailingslashit( wp_upload_dir()['basedir'] ) . 'drop-print';
    $legacy_exts = array( '.afp' );
    if ( defined( 'DROP_PRINT_LEGACY_CONTAINER_EXTS' ) ) {
        $legacy_exts = array();
        foreach ( explode( ',', DROP_PRINT_LEGACY_CONTAINER_EXTS ) as $legacy_ext ) {
            $legacy_ext = trim( $legacy_ext );
            if ( '' !== $legacy_ext ) {
                $legacy_exts[] = $legacy_ext;
            }
        }
    }
    $new_ext = defined( 'DROP_PRINT_CONTAINER_EXT' ) ? DROP_PRINT_CONTAINER_EXT : '.drop';
    $index = drop_print_files_get_index();
    $files = isset( $index['files'] ) && is_array( $index['files'] ) ? $index['files'] : array();
    $report = array(
        'started_at' => time(),
        'renamed'    => 0,
        'already'    => 0,
        'missing'    => 0,
        'failed'     => 0,
        'failures'   => array(),
    );
    $pending = false;
    foreach ( $files as $key => $record ) {
        $key = (string) $key;
        if ( '' === $key ) {
            continue;
        }
        $new_path = trailingslashit( $base_dir ) . $key . $new_ext;
        if ( file_exists( $new_path ) ) {
            ++$report['already'];
            continue;
        }
        $legacy_path = '';
        foreach ( $legacy_exts as $legacy_ext ) {
            $candidate = trailingslashit( $base_dir ) . $key . $legacy_ext;
            if ( file_exists( $candidate ) ) {
                $legacy_path = $candidate;
                break;
            }
        }
        if ( '' === $legacy_path ) {
            ++$report['missing'];
            continue;
        }
        if ( @rename( $legacy_path, $new_path ) ) {
            ++$report['renamed'];
        } else {
            ++$report['failed'];
            $pending = true;
            if ( count( $report['failures'] ) < 50 ) {
                $report['failures'][] = $key;
            }
            error_log( '[DropPrint Client migrate_20] Failed to rename ' . $legacy_path . ' -> ' . $new_path );
        }
    }
    $report['finished_at'] = time();
    $report['complete']    = ! $pending;
    update_option( 'drop_print_20_migration_report', $report, false );
    if ( $pending ) {
        return false;
    }
    update_option( 'drop_print_20_migration_complete', 1, false );
    return true;
}
function drop_print_migrate_204() {
    $batch_size = 200;
    $offset     = (int) get_option( 'drop_print_204_migration_offset', 0 );
    $product_ids = get_posts(
        array(
            'post_type'              => 'product',
            'post_status'            => 'any',
            'posts_per_page'         => $batch_size,
            'offset'                 => $offset,
            'orderby'                => 'ID',
            'order'                  => 'ASC',
            'fields'                 => 'ids',
            'no_found_rows'          => true,
            'update_post_meta_cache' => false,
            'update_post_term_cache' => false,
            'meta_key'               => '_drop_print_meta',
        )
    );
    if ( empty( $product_ids ) ) {
        delete_option( 'drop_print_204_migration_offset' );
        update_option( 'drop_print_204_migration_complete', 1, false );
        update_option( 'drop_print_204_sku_case_migration_complete', 1, false );
        return true;
    }
    $prefix_pattern = '/^ALDEN-/';
    foreach ( $product_ids as $product_id ) {
        $product_id = absint( $product_id );
        $meta = get_post_meta( $product_id, '_drop_print_meta', true );
        if ( is_array( $meta ) && ! empty( $meta['variations'] ) && is_array( $meta['variations'] ) ) {
            $meta_changed = false;
            foreach ( $meta['variations'] as $key => $variation ) {
                if ( ! empty( $variation['sku'] ) && is_string( $variation['sku'] ) && preg_match( $prefix_pattern, $variation['sku'] ) ) {
                    $meta['variations'][ $key ]['sku'] = preg_replace( $prefix_pattern, 'alden-', $variation['sku'] );
                    $meta_changed                       = true;
                }
            }
            if ( $meta_changed ) {
                update_post_meta( $product_id, '_drop_print_meta', $meta );
            }
        }
        $product = wc_get_product( $product_id );
        if ( ! $product || ! $product->is_type( 'variable' ) ) {
            continue;
        }
        foreach ( $product->get_children() as $variation_id ) {
            $sku = get_post_meta( $variation_id, '_drop_print_sku', true );
            if ( is_string( $sku ) && preg_match( $prefix_pattern, $sku ) ) {
                update_post_meta( $variation_id, '_drop_print_sku', preg_replace( $prefix_pattern, 'alden-', $sku ) );
            }
        }
    }
    update_option( 'drop_print_204_migration_offset', $offset + count( $product_ids ), false );
    return false;
}
function drop_print_migrate_205() {
    $batch_size = 200;
    $offset     = (int) get_option( 'drop_print_205_migration_v2_offset', 0 );
    $product_ids = get_posts(
        array(
            'post_type'              => 'product',
            'post_status'            => 'any',
            'posts_per_page'         => $batch_size,
            'offset'                 => $offset,
            'orderby'                => 'ID',
            'order'                  => 'ASC',
            'fields'                 => 'ids',
            'no_found_rows'          => true,
            'update_post_meta_cache' => false,
            'update_post_term_cache' => false,
            'meta_key'               => '_drop_print_meta',
        )
    );
    if ( empty( $product_ids ) ) {
        delete_option( 'drop_print_205_migration_v2_offset' );
        update_option( 'drop_print_205_exif_dimension_migration_complete', 1, false );
        update_option( 'drop_print_205_exif_dimension_migration_v2_complete', 1, false );
        return true;
    }
    foreach ( $product_ids as $product_id ) {
        $product_id = absint( $product_id );
        $meta       = get_post_meta( $product_id, '_drop_print_meta', true );
        if ( ! is_array( $meta ) || empty( $meta['dimensions'] ) || ! is_array( $meta['dimensions'] ) ) {
            continue;
        }
        $stored_width  = absint( $meta['dimensions']['width'] ?? 0 );
        $stored_height = absint( $meta['dimensions']['height'] ?? 0 );
        if ( ! $stored_width || ! $stored_height ) {
            continue;
        }
        $preview_path = '';
        if ( ! empty( $meta['preview_path'] ) && is_string( $meta['preview_path'] ) && file_exists( $meta['preview_path'] ) ) {
            $preview_path = $meta['preview_path'];
        } elseif ( ! empty( $meta['preview_id'] ) ) {
            $attached = get_attached_file( absint( $meta['preview_id'] ) );
            if ( is_string( $attached ) && '' !== $attached && file_exists( $attached ) ) {
                $preview_path = $attached;
            }
        }
        if ( '' === $preview_path ) {
            continue;
        }
        $preview = @getimagesize( $preview_path );
        if ( false === $preview || empty( $preview[0] ) || empty( $preview[1] ) ) {
            continue;
        }
        $stored_ratio  = $stored_width / $stored_height;
        $preview_ratio = $preview[0] / $preview[1];
        if ( $preview_ratio <= 0 ) {
            continue;
        }
        $as_is      = abs( $stored_ratio - $preview_ratio );
        $transposed = abs( $stored_ratio - ( 1 / $preview_ratio ) );
        if ( $transposed >= $as_is || $transposed > ( 0.02 * $stored_ratio ) ) {
            continue;
        }
        $meta['dimensions'] = array(
            'width'  => $stored_height,
            'height' => $stored_width,
        );
        update_post_meta( $product_id, '_drop_print_meta', $meta );
    }
    update_option( 'drop_print_205_migration_v2_offset', $offset + count( $product_ids ), false );
    return false;
}
function drop_print_205_residual_migration_issues() {
    $cached = get_transient( 'drop_print_205_residual_check' );
    if ( false !== $cached ) {
        return $cached;
    }
    global $wpdb;
    $stale_skus = (int) $wpdb->get_var(
        "SELECT COUNT(*) FROM {$wpdb->postmeta} pm
         JOIN {$wpdb->posts} p ON p.ID = pm.post_id
         WHERE pm.meta_key = '_drop_print_sku'
           AND pm.meta_value LIKE BINARY 'ALDEN-%'
           AND p.post_status != 'trash'"
    );
    $result = array(
        'stale_sku_count' => $stale_skus,
    );
    set_transient( 'drop_print_205_residual_check', $result, 15 * MINUTE_IN_SECONDS );
    return $result;
}
function drop_print_205_residual_migration_notice() {
    if ( ! is_admin() || ! current_user_can( 'manage_options' ) || wp_doing_ajax() ) {
        return;
    }
    if ( ! get_option( 'drop_print_204_sku_case_migration_complete' ) ) {
        return; 
    }
    $issues = drop_print_205_residual_migration_issues();
    if ( empty( $issues['stale_sku_count'] ) ) {
        return;
    }
    ?>
    <div class="notice notice-error">
        <p>
            <?php
            printf(
                esc_html__( 'Drop Print: %d product variation(s) still carry the old-format SKU even though the background migration reported complete. This needs developer attention, not a manual review.', 'drop-print' ),
                (int) $issues['stale_sku_count']
            );
            ?>
        </p>
    </div>
    <?php
}
add_action( 'admin_notices', 'drop_print_205_residual_migration_notice' );
