<?php
namespace IMGPLTMain\Classes;

class ImagePilot
{
    private function ensureAuthorized()
    {
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( 'Unauthorized', 403 );
        }

        check_ajax_referer( 'imagepilot_admin_ajax', 'security' );
    }

    private function normalizeRelativeUploadPath( $relative_path )
    {
        $relative_path = rawurldecode( wp_normalize_path( trim( (string) $relative_path ) ) );
        if ( '' === $relative_path ) {
            return '';
        }

        $uploads = wp_upload_dir();
        $basedir = isset( $uploads['basedir'] ) ? wp_normalize_path( $uploads['basedir'] ) : '';
        $baseurl = isset( $uploads['baseurl'] ) ? wp_normalize_path( $uploads['baseurl'] ) : '';

        // Convert upload absolute paths or URLs to upload-relative paths.
        if ( '' !== $basedir && str_starts_with( $relative_path, $basedir ) ) {
            $relative_path = substr( $relative_path, strlen( $basedir ) );
        } elseif ( '' !== $baseurl && str_starts_with( $relative_path, $baseurl ) ) {
            $relative_path = substr( $relative_path, strlen( $baseurl ) );
        }

        $relative_path = ltrim( $relative_path, '/' );

        // Reject traversal and control chars.
        if ( preg_match( '/(^|\\/)\.\.(\\/|$)|[\x00-\x1F]/', $relative_path ) ) {
            return '';
        }

        $segments = array_filter(
            explode( '/', $relative_path ),
            static function ( $segment ) {
                return '' !== $segment && '.' !== $segment;
            }
        );

        return empty( $segments ) ? '' : '/' . implode( '/', $segments );
    }

    public function listMedia()
    {
        $this->ensureAuthorized();

        $query_images_args = array(
            'post_type'      => 'attachment',
            'post_mime_type' => 'image',
            'post_status'    => 'inherit',
            'posts_per_page' => -1,
        );
        $uploads  = wp_upload_dir();
        $dir_path = $uploads['basedir'];

        $query_images = new \WP_Query( $query_images_args );

        $images = array();
        foreach ( $query_images->posts as $image ) {
            $id   = $image->ID;
            $path = get_attached_file( $id );
            if ( empty( $path ) || ! file_exists( $path ) ) {
                continue;
            }

            $size     = intval( filesize( $path ) / 1024 );
            $fileName = basename( $path );

            $relative_path = str_replace( $dir_path, '', $path );
            $relative_path = str_replace( $fileName, '', $relative_path );

            $isSquooshed          = get_post_meta( $id, 'is_compressed', true );
            $image->size          = $size;
            $image->is_compressed = $isSquooshed;
            $image->url           = $uploads['baseurl'] . $relative_path . $fileName;
            $image->relativePath  = $relative_path;
            $image->fileName      = $fileName;
            $images[]             = $image;
        }

        wp_send_json( $images );
    }

    public function listFiles()
    {
        $this->ensureAuthorized();

        $uploads_dir      = wp_upload_dir();
        $dir_path         = $uploads_dir['basedir'];
        $dir_url          = $uploads_dir['baseurl'];
        $image_extensions = $this->getOptions()['imageFormats'];
        $image_files      = array();

        $iterator = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator( $dir_path ) );
        foreach ( $iterator as $file ) {
            if ( ! $file->isFile() ) {
                continue;
            }

            $extension = pathinfo( $file, PATHINFO_EXTENSION );
            if ( in_array( strtolower( $extension ), $image_extensions, true ) ) {
                $relative_path = str_replace( $dir_path, '', $file->getPathname() );
                $relative_path = str_replace( $file->getFilename(), '', $relative_path );
                $imgObj        = array(
                    'fileUrl'      => $dir_url . $relative_path . $file->getFilename(),
                    'url'          => $dir_url . $relative_path . $file->getFilename(),
                    'fileName'     => $file->getFilename(),
                    'post_title'   => $file->getFilename(),
                    'filePath'     => $file->getPathname(),
                    'size'         => (int) ( $file->getSize() / 1024 ),
                    'canOverride'  => $file->isWritable(),
                    'relativePath' => $relative_path,
                    'ID'           => 0,
                );
                $image_files[]  = $imgObj;
            }
        }

        wp_send_json_success( $image_files );
    }

    public function saveImage()
    {
        $this->ensureAuthorized();

        $id              = isset( $_REQUEST['img_id'] ) ? intval( $_REQUEST['img_id'] ) : 0;
        $should_override = isset( $_REQUEST['override'] ) ? filter_var( $_REQUEST['override'], FILTER_VALIDATE_BOOLEAN ) : false;

        if ( $id <= 0 ) {
            wp_send_json_error( 'Invalid attachment id', 400 );
        }

        $prev_path = get_attached_file( $id );
        $path      = $this->uploadFile();

        if ( '' !== $path ) {
            if ( $should_override && ! empty( $prev_path ) && file_exists( $prev_path ) ) {
                wp_delete_file( $prev_path );
            }

            update_attached_file( $id, $path );
            $metadata = wp_generate_attachment_metadata( $id, $path );
            if ( ! empty( $metadata ) ) {
                wp_update_attachment_metadata( $id, $metadata );
            }
            update_post_meta( $id, 'is_compressed', true );
            wp_send_json_success( $path );
        }

        wp_send_json_error( 'Upload failed', 500 );
    }

    public function saveFile()
    {
        $this->ensureAuthorized();

        $raw_relative_path = isset( $_REQUEST['relativePath'] ) ? wp_unslash( $_REQUEST['relativePath'] ) : '';
        $relative_path     = $this->normalizeRelativeUploadPath( sanitize_text_field( $raw_relative_path ) );
        if ( '' === $relative_path && '' !== $raw_relative_path ) {
            wp_send_json_error( 'Invalid target path', 400 );
        }

        if ( ! isset( $_FILES['image'] ) || ! isset( $_FILES['image']['name'] ) ) {
            wp_send_json_error( 'Image file is required', 400 );
        }

        $target_dir  = wp_upload_dir()['basedir'] . $relative_path;
        $file_name   = sanitize_file_name( wp_unslash( $_FILES['image']['name'] ) );
        $target_file = trailingslashit( $target_dir ) . basename( $file_name );

        $upload = wp_handle_upload( $_FILES['image'], array( 'test_form' => false ) );

        if ( ! $upload || isset( $upload['error'] ) ) {
            wp_send_json_error( isset( $upload['error'] ) ? $upload['error'] : 'Upload failed', 500 );
        }

        if ( ! file_exists( $target_dir ) ) {
            wp_mkdir_p( $target_dir );
        }

        $moved = rename( $upload['file'], $target_file );
        if ( ! $moved ) {
            wp_send_json_error( $target_file, 500 );
        }

        if ( isset( $_REQUEST['img_id'] ) ) {
            $id       = intval( $_REQUEST['img_id'] );
            $metadata = wp_generate_attachment_metadata( $id, $target_file );
            if ( ! empty( $metadata ) ) {
                wp_update_attachment_metadata( $id, $metadata );
            }
            update_post_meta( $id, 'is_compressed', true );
        }

        wp_send_json_success( $target_file );
    }

    public function processFile()
    {
    }

    public function uploadFile()
    {
        if ( isset( $_FILES['image'] ) && $_FILES['image']['error'] === UPLOAD_ERR_OK ) {
            $uploaded_file = wp_handle_upload( $_FILES['image'], array( 'test_form' => false ) );
            if ( $uploaded_file && ! isset( $uploaded_file['error'] ) ) {
                return $uploaded_file['file'];
            }
        }

        return '';
    }

    public function updateSettings()
    {
        $this->ensureAuthorized();

        $settings = isset( $_REQUEST['settings'] ) ? wp_unslash( $_REQUEST['settings'] ) : array();
        if ( ! is_array( $settings ) ) {
            wp_send_json_error( 'Invalid settings payload', 400 );
        }

        $data                          = array();
        $data['maxImageSize']          = isset( $settings['maxImageSize'] ) ? intval( $settings['maxImageSize'] ) : 2;
        $data['maxHeight']             = isset( $settings['maxHeight'] ) ? intval( $settings['maxHeight'] ) : 10000;
        $data['maxWidth']              = isset( $settings['maxWidth'] ) ? intval( $settings['maxWidth'] ) : 10000;
        $data['overrideOriginal']      = isset( $settings['overrideOriginal'] ) ? filter_var( $settings['overrideOriginal'], FILTER_VALIDATE_BOOLEAN ) : true;
        $data['regThumb']              = isset( $settings['regThumb'] ) ? filter_var( $settings['regThumb'], FILTER_VALIDATE_BOOLEAN ) : true;
        $data['keepRes']               = isset( $settings['keepRes'] ) ? filter_var( $settings['keepRes'], FILTER_VALIDATE_BOOLEAN ) : true;
        $data['preventWPScaleDown']    = isset( $settings['preventWPScaleDown'] ) ? filter_var( $settings['preventWPScaleDown'], FILTER_VALIDATE_BOOLEAN ) : true;
        $data['imageFormats']          = isset( $settings['imageFormats'] ) && is_array( $settings['imageFormats'] ) ? array_values( array_map( 'strtolower', array_map( 'sanitize_text_field', $settings['imageFormats'] ) ) ) : array( 'jpg', 'jpeg', 'png', 'gif' );
        $data['imageFormats']          = array_values( array_intersect( $data['imageFormats'], array( 'jpg', 'jpeg', 'png', 'gif', 'webp' ) ) );

        update_option( 'imagepilot_settings', $data );
        wp_send_json_success( $data );
    }

    public function getOptions()
    {
        $default                        = array();
        $default['maxImageSize']        = 2;
        $default['maxHeight']           = 10000;
        $default['maxWidth']            = 10000;
        $default['overrideOriginal']    = true;
        $default['regThumb']            = true;
        $default['keepRes']             = true;
        $default['preventWPScaleDown']  = true;
        $default['imageFormats']        = array( 'jpg', 'jpeg', 'png', 'gif' );
        $data                           = get_option( 'imagepilot_settings', $default );
        return $data;
    }

    public function getSettings()
    {
        $this->ensureAuthorized();

        $data = $this->getOptions();
        wp_send_json_success( $data );
    }
}
