<?php

namespace Devikit\Infakt\Api;

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

class Client {

    /**
     * API URL
     */
    const API_URL = 'https://api.infakt.pl/v3';

    /**
     * API Key
     * 
     * @var string
     */
    private $api_key;

    /**
     * Constructor
     * 
     * @param string $api_key
     */
    public function __construct( $api_key ) {
        $this->api_key = $api_key;
    }

    /**
     * Get headers
     * 
     * @return array
     */
    private function get_headers() {
        return [
            'X-inFakt-ApiKey' => $this->api_key,
            'Content-Type'    => 'application/json',
            'User-Agent'      => 'WooCommerce Infakt Plugin/' . DEVIKIT_INFAKT_VERSION
        ];
    }

    /**
     * Test connection
     * 
     * @return bool
     */
    public function test_connection() {
        $response = $this->request( 'GET', '/vat_rates.json' );
        return ! is_wp_error( $response ) && ( isset( $response['entities'] ) || isset( $response['id'] ) );
    }

    /**
     * Create Client
     * 
     * @param array $data
     * @return array|WP_Error
     */
    public function create_client( $data ) {
        return $this->request( 'POST', '/clients.json', [ 'client' => $data ] );
    }

    /**
     * Update Client
     * 
     * @param int $client_id
     * @param array $data
     * @return array|WP_Error
     */
    public function update_client( $client_id, $data ) {
        $this->log( 'Updating client ID: ' . $client_id . ' with data: ' . wp_json_encode( $data, JSON_UNESCAPED_UNICODE ), 'debug' );
        $result = $this->request( 'PUT', '/clients/' . $client_id . '.json', [ 'client' => $data ] );
        
        if ( is_wp_error( $result ) ) {
            $this->log( 'Client update ERROR: ' . $result->get_error_message(), 'error' );
        } else {
            $this->log( 'Client update SUCCESS: ' . wp_json_encode( $result, JSON_UNESCAPED_UNICODE ), 'debug' );
        }
        
        return $result;
    }

    /**
     * Get Client by NIP
     * 
     * @param string $nip
     * @return array|null
     */
    public function get_client_by_nip( $nip ) {
        $response = $this->request( 'GET', '/clients.json', [ 'q[nip_eq]' => $nip ] );
        
        if ( is_wp_error( $response ) ) {
            return null;
        }

        if ( ! empty( $response['entities'] ) ) {
            return $response['entities'][0];
        }

        return null;
    }

    /**
     * Create Invoice
     * 
     * @param array $data
     * @return array|WP_Error
     */
    public function create_invoice( $data ) {
        return $this->request( 'POST', '/invoices.json', [ 'invoice' => $data ] );
    }

    /**
     * Get Invoice Details
     * 
     * @param string $invoice_uuid Invoice UUID
     * @return array|WP_Error Invoice data or error
     */
    public function get_invoice( $invoice_uuid ) {
        if ( empty( $invoice_uuid ) ) {
            return new \WP_Error( 'no_uuid', 'Invoice UUID is required' );
        }
        
        return $this->request( 'GET', '/invoices/' . $invoice_uuid . '.json' );
    }

    /**
     * Download Invoice PDF
     * 
     * @param int $invoice_id
     * @return string|WP_Error PDF content or error
     */
    public function download_invoice_pdf( $invoice_id ) {
        if ( empty( $this->api_key ) ) {
            return new \WP_Error( 'no_api_key', 'API key is required' );
        }

        // Build URL with query parameters
        $url = 'https://api.infakt.pl/v3/invoices/' . $invoice_id . '/pdf.json';
        $url = add_query_arg( [
            'document_type' => 'original',
            'locale' => 'pl'
        ], $url );
        
        $response = wp_safe_remote_get( $url, [
            'headers' => [
                'X-inFakt-ApiKey' => $this->api_key,
                'Content-Type' => 'application/json',
            ],
            'timeout' => 30,
        ] );

        if ( is_wp_error( $response ) ) {
            return $response;
        }

        $code = wp_remote_retrieve_response_code( $response );
        
        if ( $code !== 200 ) {
            $body = wp_remote_retrieve_body( $response );
            $error = json_decode( $body, true );
            $error_message = isset( $error['error'] ) ? $error['error'] : 'Failed to download PDF';
            
            // Add more details if available
            if ( isset( $error['errors'] ) && is_array( $error['errors'] ) ) {
                $error_message .= ': ' . implode( ', ', array_map( function( $err ) {
                    return is_array( $err ) ? implode( ' ', $err ) : $err;
                }, $error['errors'] ) );
            }
            
            return new \WP_Error( 'pdf_download_failed', $error_message );
        }

        return wp_remote_retrieve_body( $response );
    }

    /**
     * Get Bank Accounts
     * 
     * @param bool $refresh Force refresh from API
     * @return array
     */
    public function get_bank_accounts( $refresh = false ) {
        if ( ! $refresh ) {
            $cached = get_transient( 'devikit_infakt_bank_accounts' );
            if ( false !== $cached ) {
                return $cached;
            }
        }

        $response = $this->request( 'GET', '/bank_accounts.json', [ 
            'offset' => '0',
            'limit'  => '120' 
        ] );
        
        if ( is_wp_error( $response ) ) {
            $this->log( 'Bank Accounts API Error: ' . $response->get_error_message() );
            $cached = get_transient( 'devikit_infakt_bank_accounts' );
            return $cached !== false ? $cached : [];
        }

        if ( empty( $response['entities'] ) ) {
            return [];
        }

        $accounts = [];
        foreach ( $response['entities'] as $row ) {
            if ( isset( $row['bank_name'] ) && isset( $row['account_number'] ) ) {
                $accounts[] = [
                    'bank_name'      => $row['bank_name'],
                    'account_number' => $row['account_number'],
                ];
            }
        }

        set_transient( 'devikit_infakt_bank_accounts', $accounts, WEEK_IN_SECONDS );
        return $accounts;
    }

    /**
     * Get VAT Exemptions
     * 
     * @param bool $refresh Force refresh from API
     * @return array Key-value pairs: id => description
     */
    public function get_vat_exemptions( $refresh = false ) {
        if ( ! $refresh ) {
            $cached = get_transient( 'devikit_infakt_vat_exemptions' );
            if ( false !== $cached ) {
                return $cached;
            }
        }

        $response = $this->request( 'GET', '/vat_exemptions.json', [ 
            'offset' => '0',
            'limit'  => '120' 
        ] );
        
        if ( is_wp_error( $response ) ) {
            $this->log( 'VAT Exemptions API Error: ' . $response->get_error_message() );
            // Return cached data if available, otherwise return minimal default
            $cached = get_transient( 'devikit_infakt_vat_exemptions' );
            return $cached !== false ? $cached : [ '' => __( 'Brak', 'invoicing-integration-for-infakt-and-woocommerce' ) ];
        }

        if ( empty( $response['entities'] ) ) {
            $this->log( 'VAT Exemptions: Empty response from API' );
            return [ '' => __( 'Brak', 'invoicing-integration-for-infakt-and-woocommerce' ) ];
        }

        $exemptions = [ '' => __( 'Brak', 'invoicing-integration-for-infakt-and-woocommerce' ) ];
        foreach ( $response['entities'] as $row ) {
            if ( isset( $row['id'] ) && isset( $row['description'] ) ) {
                $exemptions[ $row['id'] ] = $row['description'];
            }
        }

        $this->log( 'VAT Exemptions loaded: ' . count( $exemptions ) . ' items', 'info' );
        set_transient( 'devikit_infakt_vat_exemptions', $exemptions, WEEK_IN_SECONDS );
        return $exemptions;
    }

    /**
     * Get Flat Rates (Ryczałt)
     * 
     * @param bool $refresh Force refresh from API
     * @return array
     */
    public function get_flat_rates( $refresh = false ) {
        if ( ! $refresh ) {
            $cached = get_transient( 'devikit_infakt_flat_rates' );
            if ( false !== $cached ) {
                return $cached;
            }
        }

        $response = $this->request( 'GET', '/flat_rates.json', [ 
            'offset' => '0',
            'limit'  => '20' 
        ] );
        
        if ( is_wp_error( $response ) ) {
            $this->log( 'Flat Rates API Error: ' . $response->get_error_message() );
            $cached = get_transient( 'devikit_infakt_flat_rates' );
            return $cached !== false ? $cached : [ '' => __( 'Brak', 'invoicing-integration-for-infakt-and-woocommerce' ) ];
        }

        if ( empty( $response['entities'] ) ) {
            return [ '' => __( 'Brak', 'invoicing-integration-for-infakt-and-woocommerce' ) ];
        }

        $rates = [ '' => __( 'Brak', 'invoicing-integration-for-infakt-and-woocommerce' ) ];
        foreach ( $response['entities'] as $row ) {
            // Skip rate 2% (not commonly used)
            if ( isset( $row['rate'] ) && (int) $row['rate'] === 2 ) {
                continue;
            }
            if ( isset( $row['rate'] ) && isset( $row['name'] ) ) {
                $rates[ $row['rate'] ] = $row['name'];
            }
        }

        set_transient( 'devikit_infakt_flat_rates', $rates, WEEK_IN_SECONDS );
        return $rates;
    }

    /**
     * Get Income Transaction Markings
     * 
     * @param bool $refresh Force refresh from API
     * @return array
     */
    public function get_income_markings( $refresh = false ) {
        if ( ! $refresh ) {
            $cached = get_transient( 'devikit_infakt_income_markings' );
            if ( false !== $cached ) {
                return $cached;
            }
        }

        $response = $this->request( 'GET', '/documents_markings/incomes.json', [ 
            'offset' => '0',
            'limit'  => '25' 
        ] );
        
        if ( is_wp_error( $response ) ) {
            $this->log( 'Income Markings API Error: ' . $response->get_error_message() );
            $cached = get_transient( 'devikit_infakt_income_markings' );
            return $cached !== false ? $cached : [ '' => __( 'Brak oznaczenia', 'invoicing-integration-for-infakt-and-woocommerce' ) ];
        }

        if ( empty( $response['entities'] ) ) {
            return [ '' => __( 'Brak oznaczenia', 'invoicing-integration-for-infakt-and-woocommerce' ) ];
        }

        $markings = [ '' => __( 'Brak oznaczenia', 'invoicing-integration-for-infakt-and-woocommerce' ) ];
        foreach ( $response['entities'] as $row ) {
            if ( isset( $row['id'] ) && isset( $row['code'] ) && isset( $row['short_description'] ) ) {
                // Format: "kod - krótki opis"
                $markings[ $row['id'] ] = $row['code'] . ' - ' . $row['short_description'];
            }
        }

        set_transient( 'devikit_infakt_income_markings', $markings, WEEK_IN_SECONDS );
        return $markings;
    }

    /**
     * Clear API cache
     */
    public static function clear_cache() {
        delete_transient( 'devikit_infakt_vat_exemptions' );
        delete_transient( 'devikit_infakt_flat_rates' );
        delete_transient( 'devikit_infakt_bank_accounts' );
        delete_transient( 'devikit_infakt_income_markings' );
    }

    /**
     * Send request
     * 
     * @param string $method
     * @param string $endpoint
     * @param array $body
     * @return mixed
     */
    private function request( $method, $endpoint, $body = [] ) {
        $url = self::API_URL . $endpoint;
        
        $args = [
            'method'  => $method,
            'headers' => $this->get_headers(),
            'timeout' => 30,
        ];

        if ( ! empty( $body ) ) {
            if ( $method === 'GET' ) {
                $url = add_query_arg( $body, $url );
            } else {
                $args['body'] = json_encode( $body );
            }
        }

        $response = wp_remote_request( $url, $args );

        if ( is_wp_error( $response ) ) {
            $this->log( 'Error: ' . $response->get_error_message() );
            return $response;
        }

        $code = wp_remote_retrieve_response_code( $response );
        $body = wp_remote_retrieve_body( $response );
        $data = json_decode( $body, true );

        if ( $code >= 400 ) {
            $error_msg = isset( $data['error'] ) ? $data['error'] : 'Unknown error';
            if ( isset( $data['errors'] ) ) {
                $error_msg .= ' ' . wp_json_encode( $data['errors'], JSON_UNESCAPED_UNICODE );
            }
            $this->log( "API Error ($code): $error_msg" );
            return new \WP_Error( 'infakt_api_error', $error_msg, [ 'code' => $code, 'data' => $data ] );
        }

        return $data;
    }

    /**
     * Log message
     * 
     * @param string $message
     * @param string $level Log level: 'error', 'warning', 'info', 'debug'
     */
    public function log( $message, $level = 'error' ) {
        if ( ! class_exists( 'WC_Logger' ) ) {
            return;
        }

        $logger = wc_get_logger();
        
        // Check if debug logging is enabled (from FREE version settings)
        $settings = get_option( 'devikit_infakt_settings', [] );
        $debug_enabled = isset( $settings['enable_debug_logging'] ) && $settings['enable_debug_logging'] === 'yes';
        
        if ( $debug_enabled ) {
            // Log to debug file when enabled
            $logger->log( $level, $message, [ 'source' => 'devikit_infakt_debug' ] );
        } elseif ( $level === 'error' ) {
            // Always log errors to main file
            $logger->error( $message, [ 'source' => 'invoicing-integration-for-infakt-and-woocommerce' ] );
        }
    }
}
