<?php

namespace HelpGent\App\Repositories;

defined( 'ABSPATH' ) || exit;

use Exception;
use HelpGent\App\Models\ElementAnswers;
use HelpGent\App\Models\Response;
use HelpGent\App\Support\Element\Fields\Address;
use HelpGent\App\Support\Element\Fields\ContactInfo;
use HelpGent\App\Support\Element\Fields\OpenEnded;
use HelpGent\App\Utils\Repository;

class SummaryRepository {
    public ElementAnswerRepository $element_answer_repository;

    public AttachmentRepository $attachment_repository;

    public function __construct( 
        ElementAnswerRepository $element_answer_repository, 
        AttachmentRepository $attachment_repository
    ) {
        $this->element_answer_repository = $element_answer_repository;
        $this->attachment_repository     = $attachment_repository;
    }

    public function get( int $form_id, string $element_id, string $element_type, int $page = 0, int $per_page = 0 ) {
        /**
         * @var FormRepository $form_repository
         */
        $form_repository = helpgent_singleton( FormRepository::class );
        $form            = $form_repository->get_by_id( $form_id );

        if ( ! $form ) {
            throw new Exception( esc_html__( 'Form not found.', 'helpgent' ), 404 );
        }

        $form = helpgent_migrate_old_form( $form, false );

        $content  = $form->content;
        $elements = $content['elements'];

        $element_key = array_search( $element_id, array_column( $elements, 'id' ) );

        if ( ! is_int( $element_key ) ) {
            throw new Exception( esc_html__( 'Element not found', 'helpgent' ), 404 );
        }

        $element = $elements[$element_key];

        $element_field_handlers = helpgent_config( 'element-fields-handlers' );
        
        if ( empty( $element_field_handlers[$element_type] ) ) {
            throw new Exception( esc_html__( 'Field handler not found.', 'helpgent' ), 404 );
        }

        $field_handler = helpgent_singleton( $element_field_handlers[$element_type] );

        /**
         * @var \HelpGent\App\Support\Element\Element $field_handler
         */
        return $field_handler->get_summary( $form, $element, $page, $per_page );
    }

    public function get_form_summary( int $form_id ): array {
        /**
         * @var QuizRepository $quiz_repository
         */
        $quiz_repository = helpgent_singleton( QuizRepository::class );
        $result = Response::query( 'response' )
            ->select( 
                [
                    'COUNT( id ) AS total_submitted',
                    'SUM( CASE WHEN response.is_completed = 1 THEN 1 ELSE 0 END ) AS total_completed',
                ]
            )
            ->where( 'response.form_id', $form_id )
            ->first();

        $summary = [
            'total_submitted'   => 0,
            'total_completed'   => 0,
            'total_incompleted' => 0,
            'completion_rate'   => null,
        ];

        if ( empty( $result ) ) {
            return $summary;
        }

        if ( absint( $result->total_submitted ) < 1 ) {
            return $summary;
        }

        $total_incompleted = absint( $result->total_submitted ) - absint( $result->total_completed );
        $completion_rate   = ( absint( $result->total_completed ) / absint( $result->total_submitted ) ) * 100;

        $summary = [
            'total_submitted'   => absint( $result->total_submitted ),
            'total_completed'   => absint( $result->total_completed ),
            'total_incompleted' => $total_incompleted,
            'completion_rate'   => round( $completion_rate, 2 ),
        ];

        $quiz_summary = $quiz_repository->get_form_quiz_summary( $form_id );

        if ( ! empty( $quiz_summary ) ) {
            $summary['quiz'] = $quiz_summary;
        }

        return $summary;
    }

    public function get_elements( int $form_id ) {
        /**
         * @var FormRepository $form_repository
         */
        $form_repository = helpgent_singleton( FormRepository::class );
        $form            = $form_repository->get_by_id( $form_id );

        if ( ! $form ) {
            throw new Exception( esc_html__( 'Form not found.', 'helpgent' ), 404 );
        }

        $form = helpgent_migrate_old_form( $form, false );
        /**
         * @var QuizRepository $quiz_repository
         */
        $quiz_repository = helpgent_singleton( QuizRepository::class );

        $content  = $form->content;
        $elements = $content['elements'];

        $allowed_elements_submission = array_filter(
            helpgent_allowed_elements_on_submission(), function( $element ) {
                return 'gdpr' !== $element;
            }
        );
    
        $final_elements = [];
        
        $totals = ElementAnswers::query()->where( 'form_id', $form_id )->select( 'element_id, COUNT(element_id) as total' )->group_by( 'element_id' )->get();

        foreach ( $elements as $element ) {
            $element_type = $element['element_type'];

            if ( ! in_array( $element_type, $allowed_elements_submission, true ) ) {
                continue;
            }

            $element_id = $element['id'];

            $total_key = array_search( $element_id, array_column( $totals, 'element_id' ) );

            if ( is_int( $total_key ) ) {
                $total = intval( $totals[$total_key]->total );
            } else {
                $total = 0;
            }

            $final_element = [
                'id'             => $element_id,
                'title'          => $element['attributes']['title'],
                'element_type'   => $element_type,
                'total_response' => $total
            ];

            $quiz = $quiz_repository->get_element_overview( $content, $element );

            if ( ! empty( $quiz ) ) {
                $final_element['quiz'] = $quiz;
                $final_element['quiz_summary'] = $quiz_repository->get_element_quiz_summary( $form_id, $element );
            }

            if ( in_array( $element_type, [ContactInfo::get_key(), Address::get_key()] ) ) {
                $fields = $element['fields'] ?? $element['attributes']['fields'] ?? [];

                if ( ! empty( $fields ) ) {
                    $final_element['labels'] = Repository::get_fields_labels( $fields );
                }

            } elseif ( OpenEnded::get_key() === $element_type ) {
                $final_element['labels'] = Repository::get_fields_labels( helpgent_get_nested_value( 'attributes.text_fields', $element ) );
            }

            $final_elements[] = $final_element;
        }

        return $final_elements;
    }
}
