<?php
declare(strict_types=1);

namespace Autogedal\StockLog\Cron;

use Autogedal\StockLog\Model\Alert\Notifier;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ResourceConnection;
use Psr\Log\LoggerInterface;

class DailyReport
{
    const XML_PATH_ENABLE     = 'autogedal_stocklog/reports/enable_daily_report';
    const XML_PATH_RECIPIENTS = 'autogedal_stocklog/reports/report_recipients';

    private ResourceConnection $resource;
    private ScopeConfigInterface $scopeConfig;
    private Notifier $notifier;
    private LoggerInterface $logger;

    public function __construct(
        ResourceConnection $resource,
        ScopeConfigInterface $scopeConfig,
        Notifier $notifier,
        LoggerInterface $logger
    ) {
        $this->resource    = $resource;
        $this->scopeConfig = $scopeConfig;
        $this->notifier    = $notifier;
        $this->logger      = $logger;
    }

    public function execute(): void
    {
        if (!$this->scopeConfig->isSetFlag(self::XML_PATH_ENABLE)) {
            return;
        }
        $recipients = $this->notifier->parseRecipients(self::XML_PATH_RECIPIENTS);
        if (empty($recipients)) {
            return;
        }
        try {
            $since = (new \DateTimeImmutable('-24 hours', new \DateTimeZone('UTC')))->format('Y-m-d H:i:s');
            $data  = $this->collectReportData($since);

            $this->notifier->sendReport(
                [
                    'report_title' => 'Daily Stock Report — ' . date('d.m.Y'),
                    'period'       => 'Last 24 hours',
                    'since'        => $since,
                    'total'        => $data['total'],
                    'oos_count'    => count($data['oos']),
                    'oos_list'     => $data['oos'],
                    'top_drops'    => $data['top_drops'],
                    'by_source'    => $data['by_source'],
                ],
                $recipients
            );
        } catch (\Throwable $e) {
            $this->logger->error('StockLog DailyReport failed: ' . $e->getMessage());
        }
    }

    private function collectReportData(string $since): array
    {
        $connection = $this->resource->getConnection();
        $table      = $this->resource->getTableName('autogedal_stock_log');

        $total = (int)$connection->fetchOne(
            $connection->select()->from($table, ['COUNT(*)'])->where('created_at >= ?', $since)
        );

        // Per-SKU last event in the 24h window; keep only those that ended OOS.
        // This avoids counting oscillating products multiple times.
        $lastPerSku = $connection->select()
            ->from($table, ['sku', 'max_id' => new \Zend_Db_Expr('MAX(log_id)')])
            ->where('created_at >= ?', $since)
            ->group('sku');

        $oos = $connection->fetchAll(
            $connection->select()
                ->from(['sl' => $table], ['sku', 'qty_before', 'qty_after', 'source', 'created_at'])
                ->joinInner(['last' => $lastPerSku], 'sl.log_id = last.max_id', [])
                ->where('sl.is_in_stock_after = ?', 0)
                ->order('sl.created_at DESC')
        );

        $bySource = $connection->fetchAll(
            $connection->select()
                ->from($table, ['source', 'cnt' => new \Zend_Db_Expr('COUNT(*)')])
                ->where('created_at >= ?', $since)
                ->group('source')
                ->order('cnt DESC')
        );

        $topDrops = $connection->fetchAll(
            $connection->select()
                ->from($table, ['sku', 'qty_before', 'qty_after', 'source', 'created_at',
                    'drop_amount' => new \Zend_Db_Expr('(qty_before - qty_after)')])
                ->where('created_at >= ?', $since)
                ->where('qty_before > qty_after')
                ->order('drop_amount DESC')
                ->limit(10)
        );

        return ['total' => $total, 'oos' => $oos, 'by_source' => $bySource, 'top_drops' => $topDrops];
    }
}
