<?php

namespace MintyPHP\Module\Helpdesk\Service;

use MintyPHP\Module\Helpdesk\Repository\SoftwareProductRepository;

class SoftwareProductSyncService
{
    public function __construct(
        private readonly BcODataGateway $bcODataGateway,
        private readonly SoftwareProductRepository $repository,
        private readonly HelpdeskSettingsGateway $settingsGateway
    ) {
    }

    /**
     * Sync contract types from BC to the local helpdesk_software_products table.
     *
     * - Fetches all types with Create_SaaS_License=true
     * - Upserts each entry (inserts new, updates bc_description, reactivates soft-deleted)
     * - Soft-deletes entries whose code no longer appears in BC
     *
     * @return array{status: string, error_code: ?string, error_message: ?string, result: array<string, int>}
     */
    public function sync(): array
    {
        if (!$this->settingsGateway->isConfigured()) {
            return [
                'status' => 'skipped',
                'error_code' => 'bc_not_configured',
                'error_message' => 'Business Central connection is not configured',
                'result' => [],
            ];
        }

        try {
            $bcTypes = $this->bcODataGateway->listContractTypes();
        } catch (\Throwable $e) {
            return [
                'status' => 'failed',
                'error_code' => 'bc_fetch_failed',
                'error_message' => mb_substr('BC OData fetch failed: ' . $e->getMessage(), 0, 255),
                'result' => [],
            ];
        }

        if ($bcTypes === []) {
            return [
                'status' => 'skipped',
                'error_code' => 'bc_empty_response',
                'error_message' => 'BC returned no contract types — skipping sync to preserve local state',
                'result' => [],
            ];
        }

        $syncedCodes = [];
        $upserted = 0;

        foreach ($bcTypes as $type) {
            $code = $type['Code'];
            $description = $type['Description'];

            if ($this->repository->upsertByCode($code, $description)) {
                $upserted++;
            }
            $syncedCodes[] = $code;
        }

        $deactivated = $this->repository->softDeleteNotInCodes($syncedCodes);

        return [
            'status' => 'success',
            'error_code' => null,
            'error_message' => null,
            'result' => [
                'bc_count' => count($bcTypes),
                'upserted' => $upserted,
                'deactivated' => $deactivated,
            ],
        ];
    }
}
