<?php
/**
 * Schema Detectie Resultaat
 *
 * Waarde object dat het resultaat van schema detectie bevat
 * met hoofd schema, extra schema's, scores en betrouwbaarheid
 *
 * @package TamRank
 * @subpackage Schema\Detector
 * @since 1.0.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Klasse TAMRANK_Schema_Detection_Result
 *
 * Bevat alle informatie over een schema detectie resultaat
 */
class TAMRANK_Schema_Detection_Result {

    /**
     * Beschikbare schema types
     *
     * @var array
     */
    const SCHEMA_TYPES = array(
        'WebPage',
        'AboutPage',
        'ContactPage',
        'CollectionPage',
        'ItemPage',
        'BlogPosting',
        'Product',
        'FAQPage',
        'HowTo',
        'VideoObject',
        'ImageObject',
        'Event',
        'Recipe',
        'LocalBusiness',
        'NewsArticle',
        'Course',
        'Service',
        'JobPosting',
        'SoftwareApplication',
    );

    /**
     * Schema types die als extra kunnen worden toegevoegd
     *
     * @var array
     */
    const EXTRA_SCHEMA_TYPES = array(
        'FAQPage',
        'VideoObject',
        'HowTo',
        'ImageObject',
        'BreadcrumbList',
    );

    /**
     * Hoofd schema type
     *
     * @var string|null
     */
    private $hoofd_schema = null;

    /**
     * Lijst met extra schema types
     *
     * @var array
     */
    private $extra_schemas = array();

    /**
     * Scores per schema type
     *
     * @var array
     */
    private $scores = array();

    /**
     * Betrouwbaarheid van de detectie (0.0 tot 1.0)
     *
     * @var float
     */
    private $betrouwbaarheid = 0.0;

    /**
     * Detectie details voor debugging
     *
     * @var array
     */
    private $details = array();

    /**
     * Post ID waarvoor deze detectie is uitgevoerd
     *
     * @var int
     */
    private $post_id = 0;

    /**
     * Tijdstip van detectie
     *
     * @var int
     */
    private $detectie_tijd = 0;

    /**
     * Constructor
     *
     * @param int $post_id Post ID waarvoor detectie is uitgevoerd
     */
    public function __construct( $post_id = 0 ) {
        $this->post_id        = absint( $post_id );
        $this->detectie_tijd  = time();
        $this->scores         = array_fill_keys( self::SCHEMA_TYPES, 0 );
    }

    /**
     * Stel het hoofd schema type in
     *
     * @param string $schema_type Schema type (bijv. 'Article', 'Product')
     * @return self
     */
    public function stel_hoofd_schema_in( $schema_type ) {
        if ( in_array( $schema_type, self::SCHEMA_TYPES, true ) ) {
            $this->hoofd_schema = $schema_type;
        }
        return $this;
    }

    /**
     * Haal het hoofd schema type op
     *
     * @return string|null
     */
    public function krijg_hoofd_schema() {
        return $this->hoofd_schema;
    }

    /**
     * Alias voor krijg_hoofd_schema (Engelse naamgeving)
     *
     * @return string|null
     */
    public function get_main_type() {
        return $this->krijg_hoofd_schema();
    }

    /**
     * Voeg een extra schema type toe
     *
     * @param string $schema_type Extra schema type
     * @return self
     */
    public function voeg_extra_schema_toe( $schema_type ) {
        if ( in_array( $schema_type, self::EXTRA_SCHEMA_TYPES, true ) ) {
            if ( ! in_array( $schema_type, $this->extra_schemas, true ) ) {
                $this->extra_schemas[] = $schema_type;
            }
        }
        return $this;
    }

    /**
     * Stel meerdere extra schema types in
     *
     * @param array $schema_types Array van extra schema types
     * @return self
     */
    public function stel_extra_schemas_in( $schema_types ) {
        $this->extra_schemas = array();
        foreach ( $schema_types as $type ) {
            $this->voeg_extra_schema_toe( $type );
        }
        return $this;
    }

    /**
     * Haal extra schema types op
     *
     * @return array
     */
    public function krijg_extra_schemas() {
        return $this->extra_schemas;
    }

    /**
     * Alias voor krijg_extra_schemas (Engelse naamgeving)
     *
     * @return array
     */
    public function get_extra_types() {
        return $this->krijg_extra_schemas();
    }


    /**
     * Stel de score in voor een schema type
     *
     * @param string $schema_type Schema type
     * @param int    $score       Score waarde
     * @return self
     */
    public function stel_score_in( $schema_type, $score ) {
        if ( in_array( $schema_type, self::SCHEMA_TYPES, true ) || in_array( $schema_type, self::EXTRA_SCHEMA_TYPES, true ) ) {
            $this->scores[ $schema_type ] = absint( $score );
        }
        return $this;
    }


    /**
     * Haal alle scores op
     *
     * @return array
     */
    public function krijg_alle_scores() {
        return $this->scores;
    }

    /**
     * Stel de betrouwbaarheid in
     *
     * @param float $betrouwbaarheid Waarde tussen 0.0 en 1.0
     * @return self
     */
    public function stel_betrouwbaarheid_in( $betrouwbaarheid ) {
        $this->betrouwbaarheid = max( 0.0, min( 1.0, floatval( $betrouwbaarheid ) ) );
        return $this;
    }

    /**
     * Haal de betrouwbaarheid op
     *
     * @return float
     */
    public function krijg_betrouwbaarheid() {
        return $this->betrouwbaarheid;
    }


    /**
     * Voeg een detail toe voor debugging
     *
     * @param string $sleutel Sleutel voor het detail
     * @param mixed  $waarde  Waarde van het detail
     * @return self
     */
    public function voeg_detail_toe( $sleutel, $waarde ) {
        $this->details[ $sleutel ] = $waarde;
        return $this;
    }

    /**
     * Haal alle details op
     *
     * @return array
     */
    public function krijg_details() {
        return $this->details;
    }



    /**
     * Controleer of de detectie geldig is
     *
     * @return bool
     */
    public function is_geldig() {
        return ! empty( $this->hoofd_schema );
    }


    /**
     * Geef een betrouwbaarheid label
     *
     * @return string
     */
    public function krijg_betrouwbaarheid_label() {
        if ( $this->betrouwbaarheid >= 0.8 ) {
            return __( 'Very reliable', 'tam-rank' );
        } elseif ( $this->betrouwbaarheid >= 0.6 ) {
            return __( 'Reliable', 'tam-rank' );
        } elseif ( $this->betrouwbaarheid >= 0.4 ) {
            return __( 'Fairly reliable', 'tam-rank' );
        } elseif ( $this->betrouwbaarheid >= 0.2 ) {
            return __( 'Less reliable', 'tam-rank' );
        } else {
            return __( 'Uncertain', 'tam-rank' );
        }
    }

    /**
     * Converteer naar array voor opslag
     *
     * @return array
     */
    public function naar_array() {
        return array(
            'hoofd_schema'    => $this->hoofd_schema,
            'extra_schemas'   => $this->extra_schemas,
            'scores'          => $this->scores,
            'betrouwbaarheid' => $this->betrouwbaarheid,
            'details'         => $this->details,
            'post_id'         => $this->post_id,
            'detectie_tijd'   => $this->detectie_tijd,
        );
    }

    /**
     * Maak instantie van array
     *
     * @param array $data Array met detectie data
     * @return self
     */
    public static function van_array( $data ) {
        $resultaat = new self( isset( $data['post_id'] ) ? $data['post_id'] : 0 );

        if ( isset( $data['hoofd_schema'] ) ) {
            $resultaat->stel_hoofd_schema_in( $data['hoofd_schema'] );
        }

        if ( isset( $data['extra_schemas'] ) && is_array( $data['extra_schemas'] ) ) {
            $resultaat->stel_extra_schemas_in( $data['extra_schemas'] );
        }

        if ( isset( $data['scores'] ) && is_array( $data['scores'] ) ) {
            foreach ( $data['scores'] as $type => $score ) {
                $resultaat->stel_score_in( $type, $score );
            }
        }

        if ( isset( $data['betrouwbaarheid'] ) ) {
            $resultaat->stel_betrouwbaarheid_in( $data['betrouwbaarheid'] );
        }

        if ( isset( $data['details'] ) && is_array( $data['details'] ) ) {
            foreach ( $data['details'] as $sleutel => $waarde ) {
                $resultaat->voeg_detail_toe( $sleutel, $waarde );
            }
        }

        if ( isset( $data['detectie_tijd'] ) ) {
            $resultaat->detectie_tijd = absint( $data['detectie_tijd'] );
        }

        return $resultaat;
    }



    /**
     * Debug string representatie
     *
     * @return string
     */
    public function __toString() {
        return sprintf(
            'Schema Detectie: %s (betrouwbaarheid: %.0f%%) + [%s]',
            $this->hoofd_schema ?: 'Geen',
            $this->betrouwbaarheid * 100,
            implode( ', ', $this->extra_schemas )
        );
    }
}
