<?php
namespace PrimeLink\Modules\Imports\DataSources;

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

final class OneDriveSource implements DataSourceInterface {

    private $settings = array();

    public function __construct( array $settings = array() ) {
        $this->settings = $settings;
    }

    public function handle( array $payload ) {
        $token = $this->settings['onedrive_access_token'] ?? '';
        if ( ! $token ) {
            return array( 'error' => 'OneDrive access token is missing. Add it in Settings → Integrations.' );
        }

        $input = $payload['file'] ?? ( $payload['path'] ?? ( $this->settings['onedrive_default_file'] ?? '' ) );
        $input = trim( (string) $input );
        if ( ! $input ) {
            return array( 'error' => 'No OneDrive item ID or share link provided.' );
        }

        $is_url = filter_var( $input, FILTER_VALIDATE_URL );
        $url    = '';
        $name   = '';

        if ( $is_url ) {
            // For share links we can often append ?download=1 without auth; if token exists we also pass Authorization.
            $url = $input;
            if ( false === stripos( $url, 'download=1' ) ) {
                $url .= ( strpos( $url, '?' ) === false ? '?' : '&' ) . 'download=1';
            }
        } else {
            // Treat as item ID; requires token
            $url = 'https://graph.microsoft.com/v1.0/me/drive/items/' . rawurlencode( $input ) . '/content';
        }

        $response = \PrimeLink\Helpers\HttpHelper::get( $url, array(
            'headers' => array(
                'Authorization' => 'Bearer ' . $token,
            ),
            'timeout'     => 60,
            'retry'       => 1,
            'retry_delay' => 1,
        ) );

        if ( ! $response['success'] ) {
            return array( 'error' => $response['error'] ?? 'Failed to fetch from OneDrive.' );
        }

        $code = $response['code'];
        if ( $code < 200 || $code > 299 ) {
            $body = $response['body'];
            return array( 'error' => 'OneDrive download failed (' . $code . '): ' . wp_strip_all_tags( $body ) );
        }

        $body = $response['body'];
        if ( ! $body ) {
            return array( 'error' => 'OneDrive returned an empty file.' );
        }

        // Try to grab filename from headers
        $disp = isset( $response['headers']['content-disposition'] ) ? $response['headers']['content-disposition'] : null;
        if ( $disp && preg_match( '/filename=\"?([^\";]+)\"?/i', $disp, $m ) ) {
            $name = $m[1];
        } else {
            $name = basename( parse_url( $input, PHP_URL_PATH ) ) ?: 'onedrive-file';
        }

        $upload_dir = wp_upload_dir();
        $dest_dir   = trailingslashit( $upload_dir['basedir'] ) . 'primelink/';
        $dest_url   = trailingslashit( $upload_dir['baseurl'] ) . 'primelink/';
        if ( ! \PrimeLink\Helpers\FilesystemHelper::directory_exists( $dest_dir ) ) {
            \PrimeLink\Helpers\FilesystemHelper::create_directory( $dest_dir );
        }

        $sanitized_name = sanitize_file_name( $name );
        if ( ! $sanitized_name ) {
            $sanitized_name = 'onedrive-file.csv';
        }
        $dest_name = time() . '-' . $sanitized_name;
        $dest_path = $dest_dir . $dest_name;

        \PrimeLink\Helpers\FilesystemHelper::write_file( $dest_path, $body );

        $ext  = strtolower( pathinfo( $sanitized_name, PATHINFO_EXTENSION ) );
        $type = in_array( $ext, array( 'xml', 'xlsx', 'xls', 'json', 'csv' ), true ) ? $ext : 'csv';

        return array(
            'path'          => $dest_path,
            'url'           => $dest_url . $dest_name,
            'type'          => $type,
            'original_name' => $sanitized_name,
            'source'        => 'onedrive',
            'downloaded_at' => current_time( 'mysql' ),
        );
    }
}
