<?php
declare(strict_types=1);

namespace App\Modules\Forms\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Core\EventBus;
use App\Core\Registries\PermissionRegistry;
use App\Modules\Forms\Models\FormSchema;
use App\Modules\Forms\Models\FormSubmission;
use App\Modules\Forms\Services\FormRenderer;
use App\Modules\Forms\Services\FormValidator;

class FormController extends Controller
{
    public function index(Request $request): Response
    {
        $schemas = FormSchema::allActive();
        return $this->view('Forms.Views.submissions', [
            'schemas' => $schemas,
            'rows'    => [],
            'filters' => ['form_code' => '', 'status' => '', 'search' => '', 'date_from' => '', 'date_to' => ''],
            'pagination' => ['last_page' => 1, 'current_page' => 1],
        ]);
    }

    public function submissions(Request $request): Response
    {
        $filters = [
            'form_code' => $request->get('form_code', ''),
            'status'    => $request->get('status', ''),
            'search'    => trim((string) $request->get('q', '')),
            'date_from' => $request->get('date_from', ''),
            'date_to'   => $request->get('date_to', ''),
        ];

        $page = max(1, (int) $request->get('page', 1));
        $result = FormSubmission::search($filters, 25, $page);

        $schemas = FormSchema::allActive();

        return $this->view('Forms.Views.submissions', [
            'schemas'    => $schemas,
            'rows'       => $result['data'],
            'filters'    => $filters,
            'pagination' => $result['pagination'],
        ]);
    }

    public function render(Request $request, string $code): Response
    {
        $schema = FormSchema::findByCode($code);
        if (!$schema) {
            return $this->redirect('/forms')->withError('نموذج غير موجود');
        }

        $formPermKey = 'forms.access.' . $code;
        if (PermissionRegistry::has($formPermKey)) {
            $this->authorize($formPermKey);
        }

        return $this->view('Forms.Views.render', [
            'schema'   => $schema,
            'formHtml' => FormRenderer::render($schema),
            'data'     => [],
            'errors'   => [],
        ]);
    }

    public function submit(Request $request, string $code): Response
    {
        $schema = FormSchema::findByCode($code);
        if (!$schema) {
            return $this->redirect('/forms')->withError('نموذج غير موجود');
        }

        $formPermKey = 'forms.access.' . $code;
        if (PermissionRegistry::has($formPermKey)) {
            $this->authorize($formPermKey);
        }

        $submittedData = $request->all();
        unset($submittedData['_csrf_token']);

        $validation = FormValidator::validate($schema, $submittedData);

        if (!empty($validation['errors'])) {
            return $this->view('Forms.Views.render', [
                'schema'   => $schema,
                'formHtml' => FormRenderer::render($schema, $submittedData, $validation['errors']),
                'data'     => $submittedData,
                'errors'   => $validation['errors'],
            ]);
        }

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

        $expiresAt = null;
        if ($schema->validity_days) {
            $expiresAt = date('Y-m-d H:i:s', time() + ($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($submittedData, JSON_UNESCAPED_UNICODE),
            'status'                   => 'submitted',
            'submitted_by_employee_id' => $employee ? (int) $employee->id : null,
            'expires_at'               => $expiresAt,
            'notes'                    => $submittedData['notes'] ?? null,
        ]);

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

        return $this->redirect('/forms/submissions')->withSuccess('تم تقديم النموذج بنجاح — رقم: ' . $formNumber);
    }

    public function show(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $submission = $db->selectOne(
            "SELECT sub.*, fs.form_code, fs.name_ar as schema_name_ar, fs.schema_json, e.full_name_ar as employee_name
             FROM form_submissions sub
             JOIN form_schemas fs ON fs.id = sub.form_schema_id
             LEFT JOIN employees e ON e.id = sub.submitted_by_employee_id
             WHERE sub.id = ?",
            [(int) $id]
        );

        if (!$submission) {
            return $this->redirect('/forms/submissions')->withError('النموذج غير موجود');
        }

        $schema = new FormSchema([
            'id' => $submission['form_schema_id'],
            'schema_json' => $submission['schema_json'],
        ]);

        $data = json_decode($submission['submitted_data_json'] ?? '{}', true) ?? [];

        return $this->view('Forms.Views.render', [
            'schema'     => $schema,
            'formHtml'   => FormRenderer::render($schema, $data, null, true),
            'data'       => $data,
            'errors'     => [],
            'submission' => $submission,
            'readOnly'   => true,
        ]);
    }

    public function printForm(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $submission = $db->selectOne(
            "SELECT sub.*, fs.form_code, fs.name_ar as schema_name_ar, fs.schema_json
             FROM form_submissions sub
             JOIN form_schemas fs ON fs.id = sub.form_schema_id
             WHERE sub.id = ?",
            [(int) $id]
        );

        if (!$submission) {
            return $this->redirect('/forms/submissions')->withError('النموذج غير موجود');
        }

        $schema = new FormSchema([
            'id' => $submission['form_schema_id'],
            'schema_json' => $submission['schema_json'],
        ]);

        $data = json_decode($submission['submitted_data_json'] ?? '{}', true) ?? [];

        return $this->view('Forms.Views.print', [
            'schema'     => $schema,
            'formHtml'   => FormRenderer::render($schema, $data, null, true),
            'submission' => $submission,
        ]);
    }

    public function updateStatus(Request $request, string $id): Response
    {
        $newStatus = trim((string) $request->post('status', ''));
        $validStatuses = ['draft', 'submitted', 'under_review', 'approved', 'rejected', 'expired'];

        if (!in_array($newStatus, $validStatuses)) {
            return $this->redirect('/forms/submissions/' . $id)->withError('حالة غير صالحة');
        }

        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        $db->update('form_submissions', [
            'status'     => $newStatus,
            'updated_at' => date('Y-m-d H:i:s'),
            'updated_by' => $employee ? (int) $employee->id : null,
        ], '`id` = ?', [(int) $id]);

        return $this->redirect('/forms/submissions/' . $id)->withSuccess('تم تحديث الحالة');
    }
}