<?php
/* Copyright (C) 2026 ZUGFeRD Import Module
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 */

/**
 * \file    class/importnotification.class.php
 * \ingroup importzugferd
 * \brief   Email notification class for ZUGFeRD imports
 */

require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';

/**
 * Class ImportNotification
 * Handles email notifications for ZUGFeRD import events
 */
class ImportNotification
{
    /**
     * @var DoliDB Database handler
     */
    public $db;

    /**
     * @var string Error message
     */
    public $error = '';

    /**
     * @var array Error messages
     */
    public $errors = array();

    /**
     * Constructor
     *
     * @param DoliDB $db Database handler
     */
    public function __construct($db)
    {
        $this->db = $db;
    }

    /**
     * Check if notifications are enabled
     *
     * @return bool True if enabled
     */
    public function isEnabled()
    {
        return getDolGlobalString('IMPORTZUGFERD_NOTIFY_ENABLED') && getDolGlobalString('IMPORTZUGFERD_NOTIFY_EMAIL');
    }

    /**
     * Get notification email address
     *
     * @return string Email address
     */
    public function getNotifyEmail()
    {
        return getDolGlobalString('IMPORTZUGFERD_NOTIFY_EMAIL');
    }

    /**
     * Send notification for manual intervention required
     *
     * @param ZugferdImport $import Import object
     * @param array $lines Import lines
     * @return int 1 if sent, 0 if not needed, -1 on error
     */
    public function sendManualInterventionNotification($import, $lines = array())
    {
        global $conf, $langs;

        if (!$this->isEnabled() || !getDolGlobalString('IMPORTZUGFERD_NOTIFY_MANUAL')) {
            return 0;
        }

        $langs->load('importzugferd@importzugferd');

        $subject = $langs->trans('NotifySubjectManualIntervention', $import->invoice_number);

        $body = $langs->trans('NotifyBodyManualIntervention', $import->invoice_number, $import->seller_name);
        $body .= "\n\n";
        $body .= $langs->trans('InvoiceNumber').': '.$import->invoice_number."\n";
        $body .= $langs->trans('Supplier').': '.$import->seller_name."\n";
        $body .= $langs->trans('InvoiceDate').': '.dol_print_date($import->invoice_date, 'day')."\n";
        $body .= $langs->trans('TotalTTC').': '.price($import->total_ttc).' '.$import->currency."\n";
        $body .= "\n";

        // List issues
        $missingProducts = 0;
        $missingSupplier = ($import->fk_soc <= 0);

        if (!empty($lines)) {
            foreach ($lines as $line) {
                if ($line->fk_product <= 0) {
                    $missingProducts++;
                }
            }
        }

        if ($missingSupplier) {
            $body .= "- ".$langs->trans('SupplierNotAssigned')."\n";
        }
        if ($missingProducts > 0) {
            $body .= "- ".$missingProducts." ".$langs->trans('ProductsNotAssigned')."\n";
        }

        $body .= "\n";
        $body .= $langs->trans('NotifyLinkToImport').': '.dol_buildpath('/importzugferd/import.php', 2).'?action=edit&id='.$import->id;

        return $this->sendEmail($subject, $body);
    }

    /**
     * Send notification for import error
     *
     * @param ZugferdImport $import Import object (may be partial)
     * @param string $errorMessage Error message
     * @param string $filename Original filename
     * @return int 1 if sent, 0 if not needed, -1 on error
     */
    public function sendErrorNotification($import, $errorMessage, $filename = '')
    {
        global $conf, $langs;

        if (!$this->isEnabled() || !getDolGlobalString('IMPORTZUGFERD_NOTIFY_ERROR')) {
            return 0;
        }

        $langs->load('importzugferd@importzugferd');

        $invoiceNum = !empty($import->invoice_number) ? $import->invoice_number : $filename;
        $subject = $langs->trans('NotifySubjectError', $invoiceNum);

        $body = $langs->trans('NotifyBodyError', $invoiceNum);
        $body .= "\n\n";

        if (!empty($import->invoice_number)) {
            $body .= $langs->trans('InvoiceNumber').': '.$import->invoice_number."\n";
        }
        if (!empty($import->seller_name)) {
            $body .= $langs->trans('Supplier').': '.$import->seller_name."\n";
        }
        if (!empty($filename)) {
            $body .= $langs->trans('File').': '.$filename."\n";
        }

        $body .= "\n";
        $body .= $langs->trans('ErrorMessage').":\n";
        $body .= $errorMessage."\n";

        if ($import->id > 0) {
            $body .= "\n";
            $body .= $langs->trans('NotifyLinkToImport').': '.dol_buildpath('/importzugferd/import.php', 2).'?action=edit&id='.$import->id;
        }

        return $this->sendEmail($subject, $body);
    }

    /**
     * Send notification for significant price differences
     *
     * @param ZugferdImport $import Import object
     * @param array $priceDiffs Array of price differences: array of ['line' => ImportLine, 'product' => Product, 'old_price' => float, 'new_price' => float, 'diff_percent' => float]
     * @return int 1 if sent, 0 if not needed, -1 on error
     */
    public function sendPriceDifferenceNotification($import, $priceDiffs)
    {
        global $conf, $langs;

        if (!$this->isEnabled() || !getDolGlobalString('IMPORTZUGFERD_NOTIFY_PRICE_DIFF')) {
            return 0;
        }

        if (empty($priceDiffs)) {
            return 0;
        }

        $langs->load('importzugferd@importzugferd');

        $threshold = getDolGlobalInt('IMPORTZUGFERD_PRICE_DIFF_THRESHOLD', 10);
        $subject = $langs->trans('NotifySubjectPriceDiff', $import->invoice_number, count($priceDiffs));

        $body = $langs->trans('NotifyBodyPriceDiff', $import->invoice_number, $import->seller_name, $threshold);
        $body .= "\n\n";
        $body .= $langs->trans('InvoiceNumber').': '.$import->invoice_number."\n";
        $body .= $langs->trans('Supplier').': '.$import->seller_name."\n";
        $body .= $langs->trans('InvoiceDate').': '.dol_print_date($import->invoice_date, 'day')."\n";
        $body .= "\n";

        // Table header
        $body .= str_pad($langs->trans('Product'), 40)." | ";
        $body .= str_pad($langs->trans('OldPrice'), 12)." | ";
        $body .= str_pad($langs->trans('NewPrice'), 12)." | ";
        $body .= str_pad($langs->trans('Difference'), 10)."\n";
        $body .= str_repeat('-', 80)."\n";

        // List products with price differences
        foreach ($priceDiffs as $diff) {
            $productName = $diff['product']->ref.' - '.$diff['product']->label;
            if (strlen($productName) > 38) {
                $productName = substr($productName, 0, 35).'...';
            }

            $oldPrice = price($diff['old_price']).' '.$import->currency;
            $newPrice = price($diff['new_price']).' '.$import->currency;
            $diffPercent = ($diff['diff_percent'] > 0 ? '+' : '').number_format($diff['diff_percent'], 1).'%';

            $body .= str_pad($productName, 40)." | ";
            $body .= str_pad($oldPrice, 12)." | ";
            $body .= str_pad($newPrice, 12)." | ";
            $body .= str_pad($diffPercent, 10)."\n";
        }

        $body .= "\n";
        $body .= $langs->trans('NotifyLinkToImport').': '.dol_buildpath('/importzugferd/import.php', 2).'?action=edit&id='.$import->id;

        return $this->sendEmail($subject, $body);
    }

    /**
     * Check for price differences and send notification if needed
     *
     * @param ZugferdImport $import Import object
     * @param array $lines Import lines with fk_product set
     * @return int 1 if notification sent, 0 if not needed, -1 on error
     */
    public function checkAndNotifyPriceDifferences($import, $lines)
    {
        global $conf;

        if (!$this->isEnabled() || !getDolGlobalString('IMPORTZUGFERD_NOTIFY_PRICE_DIFF')) {
            return 0;
        }

        $threshold = getDolGlobalInt('IMPORTZUGFERD_PRICE_DIFF_THRESHOLD', 10);
        $priceDiffs = array();

        require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
        require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';

        foreach ($lines as $line) {
            if ($line->fk_product <= 0) {
                continue;
            }

            // Get current supplier price
            $productFourn = new ProductFournisseur($this->db);
            $result = $productFourn->find_min_price_product_fournisseur($line->fk_product, 1, $import->fk_soc);

            if ($result > 0 && $productFourn->fourn_price > 0) {
                $oldPrice = $productFourn->fourn_price;
                $newPrice = $line->unit_price;

                // Calculate percentage difference
                $diffPercent = (($newPrice - $oldPrice) / $oldPrice) * 100;

                if (abs($diffPercent) >= $threshold) {
                    $product = new Product($this->db);
                    $product->fetch($line->fk_product);

                    $priceDiffs[] = array(
                        'line' => $line,
                        'product' => $product,
                        'old_price' => $oldPrice,
                        'new_price' => $newPrice,
                        'diff_percent' => $diffPercent
                    );
                }
            }
        }

        if (!empty($priceDiffs)) {
            return $this->sendPriceDifferenceNotification($import, $priceDiffs);
        }

        return 0;
    }

    /**
     * Send test notification email
     *
     * @return int 1 if sent, -1 on error
     */
    public function sendTestNotification()
    {
        global $conf, $langs;

        if (!$this->isEnabled()) {
            $this->error = $langs->trans('NotificationsNotEnabled');
            return -1;
        }

        $langs->load('importzugferd@importzugferd');

        $subject = $langs->trans('NotifySubjectTest');

        $body = $langs->trans('NotifyBodyTest');
        $body .= "\n\n";
        $body .= $langs->trans('NotifyTestInfo')."\n\n";

        // Show current notification settings
        $body .= $langs->trans('CurrentSettings').":\n";
        $body .= "- ".$langs->trans('NotifyEmail').": ".$this->getNotifyEmail()."\n";
        $body .= "- ".$langs->trans('IMPORTZUGFERD_NOTIFY_MANUAL').": ".(getDolGlobalString('IMPORTZUGFERD_NOTIFY_MANUAL') ? $langs->trans('Yes') : $langs->trans('No'))."\n";
        $body .= "- ".$langs->trans('IMPORTZUGFERD_NOTIFY_ERROR').": ".(getDolGlobalString('IMPORTZUGFERD_NOTIFY_ERROR') ? $langs->trans('Yes') : $langs->trans('No'))."\n";
        $body .= "- ".$langs->trans('IMPORTZUGFERD_NOTIFY_PRICE_DIFF').": ".(getDolGlobalString('IMPORTZUGFERD_NOTIFY_PRICE_DIFF') ? $langs->trans('Yes') : $langs->trans('No'))."\n";

        if (getDolGlobalString('IMPORTZUGFERD_NOTIFY_PRICE_DIFF')) {
            $body .= "- ".$langs->trans('IMPORTZUGFERD_PRICE_DIFF_THRESHOLD').": ".getDolGlobalInt('IMPORTZUGFERD_PRICE_DIFF_THRESHOLD', 10)."%\n";
        }

        $body .= "\n";
        $body .= $langs->trans('NotifyTestSuccess');

        return $this->sendEmail($subject, $body);
    }

    /**
     * Send email using Dolibarr's mail system
     *
     * @param string $subject Email subject
     * @param string $body Email body (plain text)
     * @return int 1 if sent, -1 on error
     */
    protected function sendEmail($subject, $body)
    {
        global $conf, $langs, $mysoc;

        $to = $this->getNotifyEmail();
        if (empty($to)) {
            $this->error = 'No notification email configured';
            return -1;
        }

        // Get sender
        $from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
        if (empty($from)) {
            $from = $mysoc->email;
        }
        if (empty($from)) {
            $this->error = 'No sender email configured';
            return -1;
        }

        // Add module prefix to subject
        $subject = '[ZUGFeRD Import] '.$subject;

        // Create mail object
        $mailfile = new CMailFile(
            $subject,
            $to,
            $from,
            $body,
            array(),  // files
            array(),  // mimefiles
            array(),  // ccfiles
            '',       // cc
            '',       // bcc
            0,        // deliveryreceipt
            0,        // msgishtml
            '',       // errors_to
            '',       // css
            '',       // trackid
            '',       // moreinheader
            'standard', // sendcontext
            ''        // replyto
        );

        $result = $mailfile->sendfile();

        if ($result) {
            dol_syslog("ImportNotification: Email sent to ".$to." - Subject: ".$subject, LOG_INFO);
            return 1;
        } else {
            $this->error = $mailfile->error;
            $this->errors = $mailfile->errors;
            dol_syslog("ImportNotification: Failed to send email - ".$this->error, LOG_ERR);
            return -1;
        }
    }
}
