<?php

use MintyPHP\Buffer;
use MintyPHP\Http\SessionStoreInterface;
use MintyPHP\Service\Import\ImportService;
use MintyPHP\Session;
use MintyPHP\Support\Guard;

$session = app(SessionStoreInterface::class)->all();
Guard::requireLogin();
Guard::requireAbility(\MintyPHP\Service\Access\OperationsAuthorizationPolicy::ABILITY_ADMIN_IMPORTS_VIEW);

$request = requestInput();
$currentUserId = (int) ($session['user']['id'] ?? 0);
$importService = app(ImportService::class);

$profileOptions = [];
foreach ($importService->listProfileOptions() as $option) {
    $key = (string) $option['key'];
    $permission = $importService->requiredPermissionForType($key);
    $allowed = $permission !== '' && app(\MintyPHP\Service\Access\PermissionService::class)->userHas($currentUserId, $permission);
    $profileOptions[] = [
        'key' => $key,
        'label' => (string) $option['label'],
        'allowed' => $allowed,
        'permission' => $permission,
    ];
}

$allowedProfileOptions = array_values(array_filter($profileOptions, static fn (array $option): bool => !empty($option['allowed'])));
$firstAllowedType = '';
if ($allowedProfileOptions) {
    $firstAllowedType = (string) ($allowedProfileOptions[0]['key'] ?? '');
}

$selectedType = trim((string) ($request->body('type', $request->query('type', $firstAllowedType))));
if ($selectedType === '' || !$importService->profile($selectedType)) {
    $selectedType = $firstAllowedType;
}

$step = 'upload';
$errorBag = formErrors();
$errors = [];
$token = '';
$state = null;
$mapping = [];
$preview = null;
$result = null;

$csrfKey = Session::$csrfSessionKey;
$csrfToken = $session[$csrfKey] ?? '';

$hasImportPermission = static function (string $type) use ($currentUserId, $importService): bool {
    $permission = $importService->requiredPermissionForType($type);
    return $permission !== '' && app(\MintyPHP\Service\Access\PermissionService::class)->userHas($currentUserId, $permission);
};

if ($request->isMethod('POST')) {
    $stage = trim((string) $request->body('stage', ''));
    if (!Session::checkCsrfToken()) {
        $errorBag->addGlobal(t('Form expired, please try again'));
    } elseif ($stage === 'analyze') {
        if ($selectedType === '' || !$hasImportPermission($selectedType)) {
            $errorBag->addGlobal(t('Permission denied'));
        } else {
            $analysis = $importService->analyzeUpload($request->file('csv_file', []), $selectedType, $currentUserId);
            if (!($analysis['ok'] ?? false)) {
                $errorBag->addGlobal($importService->messageForCode((string) ($analysis['code'] ?? 'unexpected_error')));
            } else {
                $token = (string) ($analysis['token'] ?? '');
                $state = $importService->state($token);
                $mapping = is_array($analysis['auto_mapping'] ?? null) ? $analysis['auto_mapping'] : [];
                $step = 'mapping';
            }
        }
    } elseif ($stage === 'preview') {
        $token = trim((string) $request->body('token', ''));
        $state = $importService->state($token);
        $mapping = $request->bodyArray('mapping');
        if (!$state) {
            $errorBag->addGlobal($importService->messageForCode('invalid_file_type'));
        } else {
            $selectedType = (string) ($state['type'] ?? $selectedType);
            if ($selectedType === '' || !$hasImportPermission($selectedType)) {
                $errorBag->addGlobal(t('Permission denied'));
            } else {
                $preview = $importService->preview($token, ['mapping' => $mapping], $currentUserId);
                if (!($preview['ok'] ?? false)) {
                    $errorBag->addGlobal($importService->messageForCode((string) ($preview['code'] ?? 'unexpected_error')));
                    $step = 'mapping';
                } else {
                    $step = 'preview';
                }
            }
        }
    } elseif ($stage === 'commit') {
        $token = trim((string) $request->body('token', ''));
        $mapping = $request->bodyArray('mapping');
        $state = $importService->state($token);
        if (!$state) {
            $errorBag->addGlobal($importService->messageForCode('invalid_file_type'));
        } else {
            $selectedType = (string) ($state['type'] ?? $selectedType);
            if ($selectedType === '' || !$hasImportPermission($selectedType)) {
                $errorBag->addGlobal(t('Permission denied'));
            } else {
                $result = $importService->commit($token, ['mapping' => $mapping], $currentUserId);
                if (!($result['ok'] ?? false)) {
                    $errorBag->addGlobal($importService->messageForCode((string) ($result['code'] ?? 'unexpected_error')));
                    $step = 'mapping';
                } else {
                    $step = 'result';
                }
            }
        }
    }
}

$errors = $errorBag->toFlatList();
if ($step === 'mapping' && !$state && $token !== '') {
    $state = $importService->state($token);
}

$activeProfile = $selectedType !== '' ? $importService->profile($selectedType) : null;
$allowedTargets = $activeProfile ? $activeProfile->allowedTargets() : [];
$requiredTargets = $activeProfile ? $activeProfile->requiredTargets() : [];
$requiredTargetsHint = implode(', ', $requiredTargets);
$showAssignmentPermissionHint = $activeProfile ? $activeProfile->requiresAssignmentPermission() : false;
$headers = is_array($state['headers'] ?? null) ? $state['headers'] : [];
$selectedProfileLabel = $selectedType;
foreach ($profileOptions as $option) {
    if ((string) $option['key'] === $selectedType) {
        $selectedProfileLabel = (string) $option['label'];
        break;
    }
}

Buffer::set('title', t('Imports'));
