<?php

namespace Shopping\Feed;

use Shopping\Schema\SchemaRegistry;
use Shopping\Mapping\SphinxToCanonicalMapper;
use Shopping\Validation\ProductValidator;
use Shopping\Sphinx\SphinxConnection;
use Shopping\Sphinx\SphinxSource;

class FeedGenerator {

    public function __construct(private string $baseDir) {}

    public function generateForPublisher(array $publisher, SphinxConnection $conn, array $allFeedDetails, S3FeedPublisher $s3, array $whitelist = []): string {
        $publisherId = $publisher['id'];

        $schema = SchemaRegistry::get(SchemaRegistry::V1);
        $validator = new ProductValidator($schema);
        $mapper = new SphinxToCanonicalMapper();

        $source = new SphinxSource($conn);

        $indexes = ['connexity_feed'];  // TODO Should come from DB

        $namer = new FeedNamer($this->baseDir);
        $writer = new FeedWriter($namer->tempPath($publisherId));

        $writer->open();

        foreach ($indexes as $indexName) {
            foreach ($source->fetch($indexName) as $row) {

                $product = $mapper->map($row);
                $result = $validator->validate($product);

                if (!$result->valid) {
                    continue;
                }

                $feed = $row->get('feed_name');

                if (is_null($feed) || empty($allFeedDetails[$feed])) {
                    echo "Feed Details not available " . $feed . "\n";
                }

                $feedDetails = $allFeedDetails[$feed];

                $advId = $feedDetails['adv_id'];
                if (empty($whitelist) || !isset($whitelist[$advId])) {
                    continue;
                }

                $feedDetails['campaign_id'] = $whitelist[$advId];

                $product->set(
                    'redirect_url',
                    generateClickUrl(
                        affiliate_id:   $publisher['id'],
                        affiliate_name: $publisher['affiliate'],
                        feedDetails:    $feedDetails,
                        data:           $product->toArray()
                    )
                );

                $writer->write($product->toArray());
            }
        }

        $writer->close();
        $finalPath = $namer->publish($publisherId);

        $compressor = new FeedCompressor();
        $gzPath = $compressor->compress($finalPath);

        $gzSize = filesize($gzPath);
        $s3Uri  = $s3->publish(
            $publisherId,
            $gzPath,
            gmdate('Ymd')
        );

        unlink($finalPath);
        unlink($gzPath);

        FeedRunLogger::success(
            $publisherId,
            $writer->getCount(),
            $gzSize
        );

        return $s3Uri;
    }
}