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

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

final class GoogleDriveSource implements DataSourceInterface {

    private $settings = array();

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

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

        $file_input = $payload['file'] ?? ( $payload['path'] ?? ( $this->settings['gdrive_default_file'] ?? '' ) );
        $file_input = trim( (string) $file_input );
        if ( ! $file_input ) {
            return array( 'error' => 'No Google Drive file ID or link provided.' );
        }

        $file_id = $this->extract_file_id( $file_input );
        if ( ! $file_id ) {
            return array( 'error' => 'Invalid Google Drive file link or ID.' );
        }

        // Fetch metadata to get name and mime type
        $meta = $this->fetch_metadata( $file_id, $token );
        if ( isset( $meta['error'] ) ) {
            return $meta;
        }

        $name = $meta['name'] ?? ( $file_id . '.csv' );
        $mime = $meta['mimeType'] ?? '';

        // Download content
        $content = $this->download_file( $file_id, $token );
        if ( isset( $content['error'] ) ) {
            return $content;
        }

        $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 ?: ( $file_id . '.csv' ) );
        $dest_name      = time() . '-' . $sanitized_name;
        $dest_path      = $dest_dir . $dest_name;

        \PrimeLink\Helpers\FilesystemHelper::write_file( $dest_path, $content['body'] );

        $ext  = strtolower( pathinfo( $sanitized_name, PATHINFO_EXTENSION ) );
        $type = $this->map_type( $ext, $mime );

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

    private function extract_file_id( $input ) {
        // If looks like ID (no spaces and short), return it
        if ( preg_match( '#^[a-zA-Z0-9_-]{10,}$#', $input ) ) {
            return $input;
        }
        // Try to extract from URL patterns
        if ( preg_match( '#/d/([^/]+)/#', $input, $m ) ) {
            return $m[1];
        }
        if ( preg_match( '#id=([^&]+)#', $input, $m ) ) {
            return $m[1];
        }
        return '';
    }

    private function fetch_metadata( $file_id, $token ) {
        $url = 'https://www.googleapis.com/drive/v3/files/' . rawurlencode( $file_id ) . '?fields=name,mimeType';
        $res = \PrimeLink\Helpers\HttpHelper::get( $url, array(
            'headers' => array(
                'Authorization' => 'Bearer ' . $token,
            ),
            'timeout'     => 30,
            'retry'       => 1,
            'retry_delay' => 1,
        ) );
        if ( ! $res['success'] ) {
            return array( 'error' => $res['error'] ?? 'Failed to fetch metadata from Google Drive.' );
        }
        $code = $res['code'];
        $body = json_decode( $res['body'], true );
        if ( $code < 200 || $code > 299 ) {
            $msg = $body['error']['message'] ?? 'Google Drive metadata error.';
            return array( 'error' => $msg );
        }
        return $body;
    }

    private function download_file( $file_id, $token ) {
        $url = 'https://www.googleapis.com/drive/v3/files/' . rawurlencode( $file_id ) . '?alt=media';
        $res = \PrimeLink\Helpers\HttpHelper::get( $url, array(
            'headers' => array(
                'Authorization' => 'Bearer ' . $token,
            ),
            'timeout'     => 60,
            'retry'       => 1,
            'retry_delay' => 1,
        ) );
        if ( ! $res['success'] ) {
            return array( 'error' => $res['error'] ?? 'Failed to download from Google Drive.' );
        }
        $code = $res['code'];
        if ( $code < 200 || $code > 299 ) {
            $body = json_decode( $res['body'], true );
            $msg  = $body['error']['message'] ?? 'Google Drive download failed.';
            return array( 'error' => $msg );
        }
        return array( 'body' => $res['body'] );
    }

    private function map_type( $ext, $mime ) {
        $map = array(
            'xml'  => 'xml',
            'csv'  => 'csv',
            'xlsx' => 'xlsx',
            'xls'  => 'xlsx',
            'json' => 'json',
        );
        if ( isset( $map[ $ext ] ) ) {
            return $map[ $ext ];
        }
        if ( $mime ) {
            if ( false !== strpos( $mime, 'xml' ) ) return 'xml';
            if ( false !== strpos( $mime, 'sheet' ) ) return 'xlsx';
            if ( false !== strpos( $mime, 'csv' ) ) return 'csv';
            if ( false !== strpos( $mime, 'json' ) ) return 'json';
        }
        return 'csv';
    }
}
