<?php

use MintyPHP\Buffer;
use MintyPHP\DB;
use MintyPHP\Http\SessionStoreInterface;
use MintyPHP\Module\Helpdesk\HelpdeskAuthorizationPolicy;
use MintyPHP\Module\Helpdesk\Service\HandoverService;
use MintyPHP\Module\Helpdesk\Service\SoftwareProductService;
use MintyPHP\Router;
use MintyPHP\Service\Access\AuthorizationService;
use MintyPHP\Session;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;

Guard::requireLogin();
Guard::requireAbilityOrForbidden(HelpdeskAuthorizationPolicy::ABILITY_HANDOVERS_CREATE);

$request = requestInput();
$returnTarget = requestResolveReturnTarget('helpdesk/handovers');
$closeTarget = requestResolveReturnTarget('helpdesk/handovers');
$createTarget = requestPathWithReturnTarget('helpdesk/handovers/create', $returnTarget);

$errorBag = formErrors();
$productService = app(SoftwareProductService::class);
$handoverService = app(HandoverService::class);
$sessionStore = app(SessionStoreInterface::class);
$appSession = $sessionStore->all();
$sessionKey = 'module.helpdesk.handover_create';

$authService = app(AuthorizationService::class);
$currentUserId = (int) ($appSession['user']['id'] ?? 0);
$currentTenantId = (int) ($appSession['current_tenant']['id'] ?? 0);
$canManage = $authService->authorize(HelpdeskAuthorizationPolicy::ABILITY_HANDOVERS_MANAGE, ['actor_user_id' => $currentUserId])->isAllowed();

// For managers: step 1 = mode selection (self/assign), step 2 = form, step 3 = protocol (self mode only)
// For non-managers: step 1 = form, step 2 = protocol
$step = (int) $request->query('step', '1');
$mode = $request->query('mode', ''); // 'self' or 'assign'

// ── Manager step 1: choose mode ──────────────────────────────────────

if ($canManage && $step === 1) {
    if ($request->isMethod('POST')) {
        if (!Session::checkCsrfToken()) {
            Flash::error(t('Form expired, please try again'), $createTarget, 'csrf_expired');
            Router::redirect($createTarget);
            return;
        }

        $chosenMode = (string) $request->body('mode', '');
        if (!in_array($chosenMode, ['self', 'assign'], true)) {
            $errorBag->add('mode', t('Please select an option'));
        }

        if (!$errorBag->hasAny()) {
            $sessionStore->remove($sessionKey);
            Router::redirect(lurl('helpdesk/handovers/create') . '?step=2&mode=' . $chosenMode . ($returnTarget ? '&return=' . rawurlencode($returnTarget) : ''));
            return;
        }
    }

    $errors = $errorBag->toFlatList();
    $validationSummaryErrors = $errorBag->toArray();
    Buffer::set('title', t('New handover'));
    Buffer::set('style_groups', json_encode(['helpdesk']));
    $breadcrumbs = [
        ['label' => t('Home'), 'path' => 'admin'],
        ['label' => t('Helpdesk'), 'path' => 'helpdesk'],
        ['label' => t('Handovers'), 'path' => 'helpdesk/handovers'],
        ['label' => t('New handover')],
    ];
    return;
}

// ── Step for form (step 2 for managers, step 1 for non-managers) ──────

$formStep = $canManage ? 2 : 1;
$protocolStep = $canManage ? 3 : 2;

// Redirect non-managers who somehow get step > 2
if (!$canManage && $step > 2) {
    $step = 1;
}

// For managers: validate mode param
if ($canManage && $step >= 2) {
    $sessionData = $sessionStore->get($sessionKey);
    $mode = $mode ?: (string) ($sessionData['mode'] ?? '');
    if (!in_array($mode, ['self', 'assign'], true)) {
        Router::redirect($createTarget);
        return;
    }
}

// ── Form step: select debitor + product (+ assignee for assign mode) ──

if ($step === $formStep) {
    $productsWithSchema = $productService->listWithSchema();

    $tenantUsers = [];
    if ($canManage && $mode === 'assign') {
        $rows = DB::select(
            'SELECT u.id, u.display_name, u.email'
            . ' FROM users u'
            . ' JOIN user_tenants ut ON ut.user_id = u.id'
            . ' WHERE ut.tenant_id = ? AND u.active = 1'
            . ' ORDER BY u.display_name ASC',
            (string) $currentTenantId
        );
        $tenantUsers = is_array($rows) ? $rows : [];
    }

    $form = [
        'debitor_no' => (string) $request->body('debitor_no', ''),
        'debitor_name' => (string) $request->body('debitor_name', ''),
        'product_code' => (string) $request->body('product_code', ''),
        'domain_no' => (string) $request->body('domain_no', ''),
        'domain_url' => (string) $request->body('domain_url', ''),
        'assigned_to' => (int) $request->body('assigned_to', 0),
        'due_date' => (string) $request->body('due_date', ''),
    ];

    if ($request->isMethod('POST')) {
        if (!Session::checkCsrfToken()) {
            Flash::error(t('Form expired, please try again'), $createTarget, 'csrf_expired');
            Router::redirect($createTarget);
            return;
        }

        if (trim($form['debitor_no']) === '') {
            $errorBag->add('debitor_no', t('Please select a customer'));
        }

        if (trim($form['domain_no']) === '') {
            $errorBag->add('domain_no', t('Please select a domain'));
        }

        if (trim($form['product_code']) === '') {
            $errorBag->add('product_code', t('Please select a software product'));
        } else {
            $product = $productService->findByCode($form['product_code']);
            if ($product === null) {
                $errorBag->add('product_code', t('Software product not found'));
            } elseif (empty($product['handover_protocol_schema'])) {
                $errorBag->add('product_code', t('Software product has no handover protocol schema'));
            }
        }

        if ($canManage && $mode === 'assign' && $form['assigned_to'] <= 0) {
            $errorBag->add('assigned_to', t('Please select an employee to assign'));
        }

        if (!$errorBag->hasAny()) {
            $sessionStore->set($sessionKey, [
                'mode' => $mode,
                'debitor_no' => trim($form['debitor_no']),
                'debitor_name' => trim($form['debitor_name']),
                'product_code' => trim($form['product_code']),
                'domain_no' => trim($form['domain_no']),
                'domain_url' => trim($form['domain_url']),
                'assigned_to' => $form['assigned_to'],
                'due_date' => trim($form['due_date']),
            ]);

            // Assign mode: create record immediately and send invitation, skip protocol step
            if ($canManage && $mode === 'assign') {
                $result = $handoverService->create(
                    $currentTenantId,
                    trim($form['debitor_no']),
                    trim($form['debitor_name']),
                    trim($form['product_code']),
                    trim($form['domain_no']),
                    trim($form['domain_url']),
                    $currentUserId,
                    []
                );

                if (!($result['ok'] ?? false)) {
                    foreach ($result['errors'] ?? [] as $key => $msg) {
                        $errorBag->add($key, $msg);
                    }
                } else {
                    $handoverId = $result['id'];
                    $dueDate = trim($form['due_date']) ?: null;
                    $handoverService->assign($currentTenantId, $handoverId, $form['assigned_to'], $currentUserId, $dueDate, HandoverService::PERMISSION_MANAGE);
                    $sessionStore->remove($sessionKey);

                    $listUrl = lurl('helpdesk/handovers');
                    Flash::success(t('Handover created and assigned'), null, 'handover_created');
                    Router::redirect($listUrl);
                    return;
                }
            } else {
                // Self mode: continue to protocol step
                $nextStep = $protocolStep;
                $modeParam = $canManage ? '&mode=' . $mode : '';
                Router::redirect(lurl('helpdesk/handovers/create') . '?step=' . $nextStep . $modeParam . ($returnTarget ? '&return=' . rawurlencode($returnTarget) : ''));
                return;
            }
        }
    }

    $errors = $errorBag->toFlatList();
    $validationSummaryErrors = $errorBag->toArray();
}

// ── Protocol step: fill protocol form ────────────────────────────────

if ($step === $protocolStep) {
    $wizardData = $sessionStore->get($sessionKey);
    if (!is_array($wizardData) || empty($wizardData['debitor_no']) || empty($wizardData['product_code'])) {
        Flash::error(t('Please complete step 1 first'), $createTarget, 'wizard_step_missing');
        Router::redirect($createTarget);
        return;
    }

    $product = $productService->findByCode($wizardData['product_code']);
    if ($product === null) {
        Flash::error(t('Software product not found'), $createTarget, 'product_not_found');
        Router::redirect($createTarget);
        return;
    }

    $schemaRaw = $product['handover_protocol_schema'] ?? null;
    $schema = is_array(json_decode((string) $schemaRaw, true)) ? json_decode($schemaRaw, true) : null;
    $schemaFields = is_array($schema) ? ($schema['fields'] ?? []) : [];
    $fieldValues = [];

    $productDisplayName = trim((string) ($product['name'] ?? '')) !== ''
        ? $product['name']
        : (string) ($product['bc_description'] ?? $wizardData['product_code']);

    if ($request->isMethod('POST')) {
        if (!Session::checkCsrfToken()) {
            $modeParam = $canManage ? '&mode=' . ($wizardData['mode'] ?? 'self') : '';
            Flash::error(t('Form expired, please try again'), $createTarget . '?step=' . $protocolStep . $modeParam, 'csrf_expired');
            Router::redirect($createTarget . '?step=' . $protocolStep . $modeParam);
            return;
        }

        foreach ($schemaFields as $field) {
            $key = $field['key'] ?? null;
            if ($key === null) {
                continue;
            }
            $type = $field['type'] ?? 'text';
            if ($type === 'checkbox') {
                $fieldValues[$key] = $request->body('field_' . $key, '') !== '' ? '1' : '0';
            } else {
                $fieldValues[$key] = (string) $request->body('field_' . $key, '');
            }
        }

        $result = $handoverService->create(
            $currentTenantId,
            $wizardData['debitor_no'],
            $wizardData['debitor_name'],
            $wizardData['product_code'],
            $wizardData['domain_no'] ?? '',
            $wizardData['domain_url'] ?? '',
            $currentUserId,
            $fieldValues
        );

        if (!($result['ok'] ?? false)) {
            $errors = array_values($result['errors'] ?? []);
            $validationSummaryErrors = $result['errors'] ?? [];
        } else {
            $handoverId = $result['id'];
            $sessionStore->remove($sessionKey);

            $editUrl = lurl('helpdesk/handovers/edit/' . $handoverId);
            Flash::success(t('Handover created'), $editUrl, 'handover_created');
            Router::redirect($editUrl);
            return;
        }
    }

    $errors = $errors ?? $errorBag->toFlatList();
    $validationSummaryErrors = $validationSummaryErrors ?? $errorBag->toArray();
}

Buffer::set('title', t('New handover'));
Buffer::set('style_groups', json_encode(['helpdesk']));
$breadcrumbs = [
    ['label' => t('Home'), 'path' => 'admin'],
    ['label' => t('Helpdesk'), 'path' => 'helpdesk'],
    ['label' => t('Handovers'), 'path' => 'helpdesk/handovers'],
    ['label' => t('New handover')],
];
