<?php

declare(strict_types=1);

namespace PortalPeople\palletforce\controllers;

use PortalPeople\palletforce\services\PalletforcePdfRateParser;
use PortalPeople\shippingcosts\components\PriceImporter;
use PortalPeople\shippingcosts\services\PdfToMarkdownService;
use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\web\Response;
use yii\web\UploadedFile;

/** Preview/import endpoints for the bundled Palletforce sample rate card. */
final class RateCardController extends Controller
{
    public function behaviors(): array
    {
        return [
            'access' => [
                'class' => AccessControl::class,
                'rules' => [['allow' => true, 'roles' => ['@']]],
            ],
        ];
    }

    public function actionSamplePreview(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;
        return $this->process(false);
    }

    public function actionSampleImport(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;
        if (!Yii::$app->request->isPost || Yii::$app->request->post('confirmImport') !== '1') {
            return ['success' => false, 'message' => 'POST confirmImport=1 is required.'];
        }

        return $this->process(true);
    }

    /** Upload a PDF for preview; add confirmImport=1 to persist valid rows. */
    public function actionUpload(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;
        $file = UploadedFile::getInstanceByName('rateFile');
        if ($file === null || $file->error !== UPLOAD_ERR_OK || strtolower($file->extension) !== 'pdf') {
            return ['success' => false, 'message' => 'Upload a readable PDF in the rateFile field.'];
        }

        $temporaryPath = tempnam(sys_get_temp_dir(), 'palletforce_rate_');
        if ($temporaryPath === false || !$file->saveAs($temporaryPath)) {
            return ['success' => false, 'message' => 'The uploaded PDF could not be stored temporarily.'];
        }

        try {
            return $this->process($this->request->post('confirmImport') === '1', $temporaryPath);
        } finally {
            @unlink($temporaryPath);
        }
    }

    private function process(bool $persist, ?string $path = null): array
    {
        $path ??= dirname(__DIR__) . '/data/AHS Discounted 2026 Rate Card.pdf';
        if (!is_file($path)) {
            return ['success' => false, 'message' => 'Bundled Palletforce sample PDF was not found.'];
        }

        try {
            $markdown = (new PdfToMarkdownService())->convert($path);
            $rows = (new PalletforcePdfRateParser())->parse($markdown, 'Palletforce');
            $valid = array_values(array_filter($rows, static fn (array $row): bool => empty($row['requires_review'])));
            $result = [
                'success' => true,
                'persisted' => false,
                'sourceRows' => count($rows),
                'validRows' => count($valid),
                'reviewRows' => count($rows) - count($valid),
                'sample' => array_slice($rows, 0, 10),
            ];
            if ($persist && $valid !== []) {
                $result['import'] = (new PriceImporter($this->assignments($valid[0])))->import($valid);
                $result['persisted'] = true;
            }
            return $result;
        } catch (\Throwable $e) {
            Yii::warning($e->getMessage(), __METHOD__);
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }

    /** @param array<string, mixed> $row @return array<string, string> */
    private function assignments(array $row): array
    {
        $assignments = [];
        foreach (array_keys($row) as $header) {
            $assignments[$header] = match ($header) {
                'Provider' => 'haulierid', 'Service' => 'type', 'PostCode' => 'postcodes',
                'Qtr', 'Half', 'Full', '2', '3', '4', '5', '5+ per pallet' => 'price',
                default => 'ignore',
            };
        }
        return $assignments;
    }
}
