<?php

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

abstract class AIEO_Order_Document_Base {

    
    abstract public function type();

    
    abstract public function label();

    
    abstract public function resolve_number($order);

    
    public function is_enabled_for($order) { return true; }

    
    public function default_attached_to_emails() { return array(); }

    
    public function generate($order, array $opts = array()) {
        if (!is_object($order) || !method_exists($order, 'get_id')) {
            return array('ok' => false, 'error' => 'invalid_order');
        }
        $force    = !empty($opts['force_regenerate']);
        $existing = AIEO_Fulfillment_Documents::get_for_order_by_type((int) $order->get_id(), $this->type());
        if ($existing && !$force && !empty($existing['pdf_path'])) {
            return array(
                'ok' => true,
                'document_id' => (int) $existing['id'],
                'pdf_path' => (string) $existing['pdf_path'],
                'duplicate' => true,
            );
        }

        $number      = $existing ? (string) $existing['number'] : $this->resolve_number($order);
        $template_id = AIEO_Fulfillment_Templates::active_template_id();
        $language    = isset($opts['language']) ? (string) $opts['language'] : null;

        if ($existing) {
            $document_id = (int) $existing['id'];
            $patch = array('template_id' => $template_id);
            if ($language !== null) { $patch['language'] = $language; }
            AIEO_Fulfillment_Documents::update($document_id, $patch);
        } else {
            $r = AIEO_Fulfillment_Documents::create(array(
                'order_id'    => (int) $order->get_id(),
                'type'        => $this->type(),
                'number'      => $number,
                'template_id' => $template_id,
                'language'    => $language,
            ));
            if (empty($r['ok'])) { return $r; }
            $document_id = (int) $r['id'];
        }

        $html = $this->get_html($document_id);
        if (is_wp_error($html)) {
            return array('ok' => false, 'document_id' => $document_id, 'error' => $html->get_error_message());
        }
        $pdf = AIEO_Fulfillment_PDF_Engine::render($html, array('paper' => 'a4', 'orientation' => 'portrait'));
        if (is_wp_error($pdf)) {
            return array('ok' => false, 'document_id' => $document_id, 'error' => $pdf->get_error_message());
        }
        $rel = AIEO_Fulfillment_Documents::cache_pdf($document_id, $this->type(), $number, $pdf);
        if ($rel === '') {
            return array('ok' => false, 'document_id' => $document_id, 'error' => 'pdf_cache_failed');
        }
        return array(
            'ok' => true,
            'document_id' => $document_id,
            'pdf_path' => $rel,
            'number' => $number,
        );
    }

    
    public function get_html($document_or_order) {
        $document = is_int($document_or_order) ? AIEO_Fulfillment_Documents::get($document_or_order) : null;
        if ($document) {
            $order = wc_get_order((int) $document['order_id']);
            $number      = (string) $document['number'];
            $template_id = (string) $document['template_id'] ?: AIEO_Fulfillment_Templates::active_template_id();
        } else {
            $order = $document_or_order;
            if (!is_object($order) || !method_exists($order, 'get_id')) {
                return new WP_Error('invalid_order', __('get_html requires a document_id or a WC_Order', 'ai-eshop-optimizer'));
            }
            $number      = $this->resolve_number($order);
            $template_id = AIEO_Fulfillment_Templates::active_template_id();
        }
        if (!$order) { return new WP_Error('order_missing', __('Order not found for document.', 'ai-eshop-optimizer')); }

        $data = array(
            'doc_type'        => $this->type(),
            'doc_label'       => $this->label(),
            'doc_number'      => $number,
            'doc_date'        => current_time('Y-m-d'),
            'order'           => $order,
            'shop'            => self::shop_info(),
            'lines'           => $this->order_lines_for_doc($order),
            'totals'          => self::order_totals($order),
            'language'        => (string) AIEO_Fulfillment_Settings::get('general.language', 'el'),
            'template_dir'    => self::template_dir($template_id),
        );
        $data = apply_filters('aieo_fulfillment_template_data', $data, $this->type(), $order);
        return AIEO_Fulfillment_Templates::render($template_id, $this->type(), $data);
    }

    
    public function get_pdf($document_id) {
        $document = AIEO_Fulfillment_Documents::get((int) $document_id);
        if (!$document) { return new WP_Error('not_found', __('Document not found', 'ai-eshop-optimizer')); }
        if (!empty($document['pdf_path'])) {
            $abs = WP_CONTENT_DIR . '/uploads/' . ltrim((string) $document['pdf_path'], '/');
            if (file_exists($abs)) { return (string) file_get_contents($abs); }
        }
        $order = wc_get_order((int) $document['order_id']);
        if (!$order) { return new WP_Error('order_missing', __('Order missing', 'ai-eshop-optimizer')); }
        $r = $this->generate($order, array('force_regenerate' => true));
        if (empty($r['ok']) || empty($r['pdf_path'])) {
            return new WP_Error('regenerate_failed', isset($r['error']) ? $r['error'] : __('unknown', 'ai-eshop-optimizer'));
        }
        $abs = WP_CONTENT_DIR . '/uploads/' . ltrim((string) $r['pdf_path'], '/');
        return (string) file_get_contents($abs);
    }

    
    public function delete($document_id) {
        return (bool) AIEO_Fulfillment_Documents::delete((int) $document_id);
    }

    
    protected function order_lines_for_doc(WC_Order $order) {
        return self::order_lines($order);
    }

    

    public static function shop_info() {
        $g = (array) AIEO_Fulfillment_Settings::get('general', array());
        return array(
            'name'      => isset($g['shop_name'])      ? (string) $g['shop_name']      : (string) get_bloginfo('name'),
            'address_1' => isset($g['shop_address_1']) ? (string) $g['shop_address_1'] : '',
            'address_2' => isset($g['shop_address_2']) ? (string) $g['shop_address_2'] : '',
            'city'      => isset($g['shop_city'])      ? (string) $g['shop_city']      : '',
            'postcode'  => isset($g['shop_postcode'])  ? (string) $g['shop_postcode']  : '',
            'country'   => isset($g['shop_country'])   ? (string) $g['shop_country']   : '',
            'phone'     => isset($g['shop_phone'])     ? (string) $g['shop_phone']     : '',
            'email'     => isset($g['shop_email'])     ? (string) $g['shop_email']     : (string) get_option('admin_email'),
            'vat'       => isset($g['vat_number'])     ? (string) $g['vat_number']     : '',
            'logo_url'  => isset($g['logo_url'])       ? (string) $g['logo_url']       : '',
        );
    }

    public static function order_lines(WC_Order $order) {
        $out = array();
        foreach ($order->get_items() as $item) {
            $product = $item->get_product();
            $sku     = $product ? (string) $product->get_sku() : '';
            $gtin    = '';
            if ($product) {
                foreach (array('_global_unique_id', 'hwp_var_gtin', 'hwp_product_gtin') as $key) {
                    $val = (string) get_post_meta($product->get_id(), $key, true);
                    if ($val !== '') { $gtin = $val; break; }
                }
            }
            $qty = (int) $item->get_quantity();
            $out[] = array(
                'name'      => (string) $item->get_name(),
                'sku'       => $sku,
                'gtin'      => $gtin,
                'qty'       => $qty,
                'subtotal'  => (float) $item->get_subtotal(),
                'total'     => (float) $item->get_total(),
                'tax'       => (float) $item->get_total_tax(),
                'price'     => $qty > 0 ? (float) $item->get_subtotal() / $qty : (float) $item->get_subtotal(),
            );
        }
        return $out;
    }

    public static function order_totals(WC_Order $order) {
        return array(
            'subtotal' => (float) $order->get_subtotal(),
            'shipping' => (float) $order->get_shipping_total(),
            'tax'      => (float) $order->get_total_tax(),
            'discount' => (float) $order->get_discount_total(),
            'total'    => (float) $order->get_total(),
            'currency' => (string) $order->get_currency(),
        );
    }

    
    public static function template_dir($template_id) {
        
        $theme_dirs = array(get_stylesheet_directory(), get_template_directory());
        foreach (array_unique($theme_dirs) as $td) {
            $cand = trailingslashit($td) . 'aieo/fulfillment/' . $template_id;
            if (is_dir($cand)) { return $cand; }
        }
        return AIEO_DIR . 'templates/fulfillment/' . $template_id;
    }
}
