#!/usr/bin/env php
<?php

declare(strict_types=1);

use FeedManager\Application\SyncWorkflowService;
use FeedManager\Application\VariantToGoogleFeedItemMapper;
use FeedManager\Integrations\Shopify\ShopifyAccessTokenProvider;
use FeedManager\Integrations\Shopify\ShopifyGraphqlClient;
use FeedManager\Integrations\Shopify\ShopifyVariantFeedSource;
use FeedManager\Repositories\AuditLogRepository;
use FeedManager\Repositories\FieldChangeRepository;
use FeedManager\Repositories\FieldPolicyRepository;
use FeedManager\Repositories\SyncRunRepository;
use FeedManager\Repositories\VariantStateRepository;
use FeedManager\Support\DotenvLoader;
use FeedManager\Support\Env;
use FeedManager\Support\PdoFactory;

require_once __DIR__ . '/../bootstrap.php';

$client = $argv[1] ?? null;
$triggerType = 'manual';
$triggerUserId = null;

foreach (array_slice($argv, 2) as $arg) {
    if (str_starts_with((string) $arg, '--trigger=')) {
        $triggerType = (string) substr((string) $arg, strlen('--trigger='));
    }
    if (str_starts_with((string) $arg, '--user-id=')) {
        $triggerUserId = (int) substr((string) $arg, strlen('--user-id='));
    }
}

if (!is_string($client) || trim($client) === '') {
    fwrite(STDERR, "Usage: php bin/sync-feed <client> [--trigger=manual|cron|web] [--user-id=123]\n");
    exit(1);
}

try {
    DotenvLoader::load(__DIR__ . '/../.env');
    $pdo = PdoFactory::fromEnv();

    $configPath = __DIR__ . '/../clients/' . $client . '/config.php';
    if (!is_file($configPath)) {
        throw new RuntimeException(sprintf('Client config not found: %s', $configPath));
    }

    /** @var array<string, mixed> $config */
    $config = require $configPath;
    $shopifyConfig = $config['shopify'] ?? null;
    $feedConfig = $config['feed'] ?? null;
    if (!is_array($shopifyConfig) || !is_array($feedConfig)) {
        throw new RuntimeException('Client config missing shopify/feed sections');
    }

    $shopDomain = Env::require((string) ($shopifyConfig['shop_domain_env'] ?? ''));
    $directAccessToken = Env::get((string) ($shopifyConfig['access_token_env'] ?? ''));
    $clientId = Env::get((string) ($shopifyConfig['client_id_env'] ?? ''));
    $clientSecret = Env::get((string) ($shopifyConfig['client_secret_env'] ?? ''));
    $apiVersion = Env::get((string) ($shopifyConfig['api_version_env'] ?? 'SHOPIFY_API_VERSION'), (string) ($shopifyConfig['api_version_default'] ?? '2025-10'));
    $requestTimeoutSeconds = (int) Env::get((string) ($shopifyConfig['request_timeout_env'] ?? 'SHOPIFY_REQUEST_TIMEOUT_SECONDS'), '120');

    if ($apiVersion === null || $apiVersion === '') {
        throw new RuntimeException('Shopify API version missing');
    }
    if ($requestTimeoutSeconds < 10) {
        $requestTimeoutSeconds = 10;
    }

    $fallbackStorefrontBaseUrl = Env::get((string) ($config['storefront_base_url_env'] ?? ''), 'https://' . preg_replace('#^https?://#i', '', $shopDomain));
    if ($fallbackStorefrontBaseUrl === null || $fallbackStorefrontBaseUrl === '') {
        throw new RuntimeException('Storefront base URL missing');
    }

    $tokenProvider = new ShopifyAccessTokenProvider(
        shopDomain: $shopDomain,
        directAccessToken: $directAccessToken,
        clientId: $clientId,
        clientSecret: $clientSecret,
    );
    $accessToken = $tokenProvider->resolve();

    $shopifyClient = new ShopifyGraphqlClient(
        shopDomain: $shopDomain,
        accessToken: $accessToken,
        apiVersion: $apiVersion,
        timeoutSeconds: $requestTimeoutSeconds,
    );

    $mappingConfig = is_array($feedConfig['mapping'] ?? null) ? $feedConfig['mapping'] : [];

    $source = new ShopifyVariantFeedSource($shopifyClient, $mappingConfig);
    $mapper = new VariantToGoogleFeedItemMapper(
        currencyCode: (string) ($feedConfig['currency'] ?? 'GBP'),
        defaultCondition: (string) ($feedConfig['condition'] ?? 'new'),
        fallbackStorefrontBaseUrl: $fallbackStorefrontBaseUrl,
        fallbackBrand: 'Unknown',
        googleProductCategoryConfig: is_array($feedConfig['google_product_category'] ?? null)
            ? $feedConfig['google_product_category']
            : ['default' => ''],
        mappingConfig: $mappingConfig,
    );

    $service = new SyncWorkflowService(
        source: $source,
        syncRuns: new SyncRunRepository($pdo),
        variantStates: new VariantStateRepository($pdo),
        policies: new FieldPolicyRepository($pdo),
        fieldChanges: new FieldChangeRepository($pdo),
        auditLog: new AuditLogRepository($pdo),
    );

    $summary = $service->run($client, $triggerType, $triggerUserId, $mapper);

    fwrite(STDOUT, sprintf(
        "Sync complete (run_id=%d): source=%d mapped=%d auto=%d pending=%d skipped=%d seeded=%d\n",
        (int) $summary['run_id'],
        (int) $summary['source_variants_count'],
        (int) $summary['mapped_variants_count'],
        (int) $summary['auto_applied_changes_count'],
        (int) $summary['pending_changes_count'],
        (int) $summary['skipped_variants_count'],
        (int) $summary['seeded_variants_count'],
    ));
    exit(0);
} catch (Throwable $e) {
    fwrite(STDERR, sprintf("Sync failed: %s\n", $e->getMessage()));
    exit(1);
}
