<?php
declare(strict_types=1);

namespace App\Modules\Forms\Services;

use App\Core\App;
use App\Core\EventBus;
use App\Core\Logger;
use App\Modules\Forms\Models\FormSchema;
use App\Modules\Forms\Models\FormSubmission;

/**
 * Bridge layer for modules to render and validate schema-driven forms.
 *
 * Usage in a controller:
 *   $html = FormBridge::render('NEW_MEMBERSHIP', $prefillData);
 *   $result = FormBridge::validate('NEW_MEMBERSHIP', $request->all());
 *   $submission = FormBridge::submit('NEW_MEMBERSHIP', $data, $memberId);
 */
final class FormBridge
{
    public static function render(string $formCode, ?array $prefillData = null, ?array $errors = null, bool $readOnly = false): string
    {
        $schema = FormSchema::findByCode($formCode);
        if (!$schema) {
            Logger::warning("FormBridge: schema not found", ['form_code' => $formCode]);
            return '';
        }
        return FormRenderer::render($schema, $prefillData, $errors, $readOnly);
    }

    public static function validate(string $formCode, array $data): array
    {
        $schema = FormSchema::findByCode($formCode);
        if (!$schema) {
            return ['errors' => ['_form' => ['النموذج غير موجود']], 'validated' => [], 'passes' => false];
        }

        unset($data['_csrf_token']);

        $result = FormValidator::validate($schema, $data);

        return [
            'errors'    => $result['errors'] ?? [],
            'validated' => $result['validated'] ?? $data,
            'passes'    => empty($result['errors']),
        ];
    }

    public static function submit(string $formCode, array $data, ?int $memberId = null, ?string $notes = null): array
    {
        $schema = FormSchema::findByCode($formCode);
        if (!$schema) {
            return ['success' => false, 'error' => 'النموذج غير موجود'];
        }

        unset($data['_csrf_token']);

        $validation = FormValidator::validate($schema, $data);
        if (!empty($validation['errors'])) {
            return ['success' => false, 'errors' => $validation['errors']];
        }

        $employee = App::getInstance()->currentEmployee();
        $formNumber = FormSubmission::generateFormNumber($formCode);

        $expiresAt = null;
        if ($schema->validity_days) {
            $expiresAt = date('Y-m-d H:i:s', time() + ((int) $schema->validity_days * 86400));
        }

        $submission = FormSubmission::create([
            'form_schema_id'           => (int) $schema->id,
            'schema_version'           => (int) $schema->version,
            'form_number'              => $formNumber,
            'submitted_data_json'      => json_encode($data, JSON_UNESCAPED_UNICODE),
            'status'                   => 'submitted',
            'submitted_by_employee_id' => $employee ? (int) $employee->id : null,
            'member_id'                => $memberId,
            'expires_at'               => $expiresAt,
            'notes'                    => $notes,
        ]);

        EventBus::dispatch('form.submitted', [
            'submission_id' => (int) $submission->id,
            'form_code'     => $formCode,
            'form_number'   => $formNumber,
            'member_id'     => $memberId,
            'data'          => $data,
        ]);

        return [
            'success'       => true,
            'submission_id' => (int) $submission->id,
            'form_number'   => $formNumber,
        ];
    }

    public static function exists(string $formCode): bool
    {
        return FormSchema::findByCode($formCode) !== null;
    }

    public static function getFee(string $formCode): string
    {
        $schema = FormSchema::findByCode($formCode);
        if (!$schema || !$schema->form_fee) {
            return '0.00';
        }
        return (string) $schema->form_fee;
    }
}
