<?php

namespace classes;

/** Require the form_t trait */
require_once WD . '/traits/form_t.php';

/** Require the form_helper_c class */
require_once WD . '/modules/forms/form_helper_c.php';

use Exception;
use forms\form_helper_c;
use forms\objects\book_interior_wash_f;
use forms\objects\book_wash_f;
use forms\objects\complete_booking_f;
use forms\objects\generate_booking_wash_certificate_f;
use objects\form_submissions_o;
use traits\form_t;

/** Require the forms using glob */

foreach ( glob(WD . '/modules/forms/objects/*.php') as $filename ) {
    require_once $filename;
}

class form
{
    /**
     * The BOOK_WASH form
     * @var book_wash_f $book_wash The BOOK_WASH form
     */
    public book_wash_f $book_wash;
    /**
     * The GENERATE_BOOKING_CERTIFICATE form
     * @var generate_booking_wash_certificate_f $generate_booking_wash_certificate The GENERATE_BOOKING_CERTIFICATE form
     */
    public generate_booking_wash_certificate_f $generate_booking_wash_certificate;

    /**
     * The COMPLETE_BOOKING_WITHOUT_WASH_CERTIFICATE form
     * @var complete_booking_f $complete_booking_without_wash_certificate The COMPLETE_BOOKING_WITHOUT_WASH_CERTIFICATE form
     */
    public complete_booking_f $complete_booking_without_wash_certificate;
    public $last_submitted_form;
    public form_submissions_o $form_submission;

    public function __construct()
    {
        $this->book_wash = new book_wash_f();
        $this->generate_booking_wash_certificate = new generate_booking_wash_certificate_f();
        $this->complete_booking_without_wash_certificate = new complete_booking_f();
    }

    /**
     * Submit a form
     * @throws Exception If the form is not valid
     * @throws Exception If the form is not submitted
     * @throws Exception If the form is not found
     * @throws Exception If the form is not found in the form helper
     */
    public function submitForm(object $form): void
    {
        /** @var form_t|object $form */
        $form->submit();
        $this->last_submitted_form = $form;
        $this->form_submission = $form->form_submissions_o;
    }

    /**
     * Check if a form exists (by its identifier)
     * @param string $form_identifier The form identifier
     * @return bool True if the form exists, false if not
     */
    public function doesFormExist(string $form_identifier): bool
    {
        // Check if there's any form with the given identifier
        $form_classes = get_declared_classes();
        foreach ( $form_classes as $form_class ) {
            if (is_subclass_of($form_class, form_helper_c::class)) {
                $form = new $form_class();
                // Check if the class is a subclass of form_helper_c, and has the form_t trait
                if (method_exists($form, 'getFormIdentifier') && $form->getFormIdentifier() === $form_identifier) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Get a form by its identifier
     * @param string $form_identifier The form identifier
     * @return form_t The form object
     * @throws Exception If the form is not found
     */
    public function getForm(string $form_identifier): object
    {
        // Check if there's any form with the given identifier
        $form_classes = get_declared_classes();
        foreach ( $form_classes as $form_class ) {
            // Check if the class is a subclass of form_helper_c, and has the form_t trait
            if (is_subclass_of($form_class, form_helper_c::class) && trait_exists(form_t::class)) {
                // Create an instance of the form class (If it is a subclass of form_helper_c, and use the form_t trait)
                $form = new $form_class();
                if (method_exists($form, 'getFormIdentifier') && $form->getFormIdentifier() === $form_identifier) {
                    return $form;
                }
            }
        }
        throw new Exception('The form was not found');
    }
}