<?php

namespace onespace\tools\activeApi\models\people;

use onespace\tools\activeApi\components\clients\PeopleClient;
use yii\helpers\ArrayHelper;
use yii\web\NotFoundHttpException;

/**
 * @property integer $id
 * @property string $guid
 * @property string $osid
 * @property integer $site_id
 * @property string $first_name
 * @property string $surname
 * @property string $phone_number
 * @property integer $phone_number_confirmed_at
 * @property string $email
 * @property integer $email_confirmed_at
 * @property array $data
 * @property integer $person_relationship
 * @property string $face_image_url
 * @property integer $status
 * @property integer $gdpr_deleted_at
 * @property string $full_name
 * @property string $search_text
 * @property array $merged_guids
 * @property array $face_map_id
 * @property string $id_number
 * @property string $id_number_bidx
 * @property integer $created_by
 * @property string $created_at
 * @property string $updated_at
 */
class Person extends \onespace\tools\activeApi\models\BaseActiveApiModel {
    public $id;
    public $guid;
    public $osid;
    public $site_id;
    public $first_name;
    public $surname;
    public $phone_number;
    public $phone_number_confirmed_at;
    public $email;
    public $email_confirmed_at;
    public $data;
    public $person_relationship;
    public $face_image_url;
    public $status;
    public $gdpr_deleted_at;
    public $created_by;
    public $created_at;
    public $updated_at;
    public $full_name;
    public $search_text;
    public $merged_guids;
    public $face_map_id;
    public $id_number;
    public $id_number_bidx;

    /** Not yet linked to a site record. */
    public const STATUS_PENDING = 0;

    /** @deprecated in favour of `STATUS_ENABLED` */
    public const STATUS_ACTIVE = 1;
    /** Default state functionality based on at least one active Record Link */
    public const STATUS_ENABLED = 1;

    /** A person has a temporary restriction */
    public const STATUS_SUSPENDED = 6;

    /** A person is permanently restricted. Auto-denies future join requests. Alerting configurable */
    public const STATUS_BLACKLISTED = 7;
    /** A person is permanently restricted. Softer in that it is a non-alerting block. Auto-denies future join requests. */
    public const STATUS_BLOCKED = 3; // blocked as in hidden from site, should never be able to apply to join again
    /** A person is permanently restricted. They are essentially `deleted`. */
    public const STATUS_ARCHIVED = 2;

    /** A person is temporarily restricted while it is part of an active merge process */
    public const STATUS_PENDING_MERGE = 4;
    /** A person is permanently restricted. The have been merged into a different person and that person's status now applies. */
    public const STATUS_MERGED = 5; // person that has been merged into another

    /**
     * {@inheritdoc}
     */
    public function client(): PeopleClient {
        return new PeopleClient();
    }

    /**
     * {@inheritdoc}
     */
    public function primaryKey(): string {
        return 'id';
    }

    /**
     * {@inheritdoc}
     */
    public function baseEndpoints(): array {
        return [
            'v1' => 'api/v1/person',
        ];
    }

    /**
     * {@inheritdoc}
     */
    #[\Override]
    public function rules() {
        $parentRules = parent::rules();
        return ArrayHelper::merge($parentRules, [
            [['osid', 'phone_number', 'phone_number_confirmed_at', 'email', 'email_confirmed_at', 'data', 'person_relationship', 'face_image_url', 'full_name', 'search_text', 'merged_guids', 'face_map_id', 'id_number', 'id_number_bidx'], 'default', 'value' => null],
            [['gdpr_deleted_at'], 'default', 'value' => 0],
            [['site_id', 'first_name', 'surname'], 'required'],
            [['site_id', 'phone_number_confirmed_at', 'email_confirmed_at', 'person_relationship', 'status', 'gdpr_deleted_at', 'face_map_id'], 'integer'],
            [['data', 'merged_guids'], 'safe'],
            [['guid', 'osid'], 'string', 'max' => 36],
            [['first_name', 'surname'], 'string', 'max' => 512],
            [['phone_number'], 'string', 'max' => 25],
            [['email', 'face_image_url', 'full_name', 'id_number', 'id_number_bidx'], 'string', 'max' => 255],
        ]);
    }

    /**
     * @inheritdoc
     */
    #[\Override]
    public function attributeLabels() {
        return ArrayHelper::merge(parent::attributeLabels(), [
            'id' => 'ID',
            'guid' => 'Guid',
            'osid' => 'Osid',
            'site_id' => 'Site ID',
            'first_name' => 'First Name',
            'surname' => 'Surname',
            'phone_number' => 'Phone Number',
            'phone_number_confirmed_at' => 'Phone Number Confirmed At',
            'email' => 'Email',
            'email_confirmed_at' => 'Email Confirmed At',
            'data' => 'Data',
            'created_by' => 'Created By',
            'person_relationship' => 'Person Relationship',
            'face_image_url' => 'Face Image Url',
            'created_at' => 'Created At',
            'updated_at' => 'Updated At',
            'status' => 'Status',
            'gdpr_deleted_at' => 'Gdpr Deleted At',
            'full_name' => 'Full Name',
            'search_text' => 'Search Text',
            'merged_guids' => 'Merged Guids',
            'face_map_id' => 'Face Map ID',
            'id_number' => 'Id Number',
            'id_number_bidx' => 'Id Number Bidx',
        ]);
    }

    /**
     * @inheritdoc
     */
    #[\Override]
    public function attributeHints() {
        return ArrayHelper::merge(parent::attributeHints(), [
            'guid' => 'The Person GUID for this instance of a person on a site',
            'osid' => 'If the person has an OSID backing them, this links them to their account',
            'site_id' => 'Link to the site that this person belongs to',
            'first_name' => 'The person\'s recorded first name',
            'surname' => 'The person\'s recorded surname',
            'phone_number' => 'The person\'s recorded phone number',
            'phone_number_confirmed_at' => 'Indicated if and when the person\'s phone number was confirmed',
            'email' => 'The person\'s recorded email address',
            'email_confirmed_at' => 'Indicated if and when the person\'s email was confirmed',
            'data' => 'Any other miscellaneous data recorded on the person',
            'created_by' => 'The person who created this person. Typically for the relationship between an OSID person (the parent) and a non OSID person (the child)',
            'person_relationship' => 'Recorded relationship between the person who created this person and this person',
            'face_image_url' => 'If existing, the url to the face image of this person',
            'created_at' => 'Timestamp of when the record was created',
            'updated_at' => 'Timestamp of when the record was last updated',
            'status' => 'Enum of the status of the person',
            'gdpr_deleted_at' => 'Unix timestamp of when the user account behind this person GDPR deleted their account',
            'merged_guids' => 'Simple list of merge guids for future searching',
        ]);
    }

    /**
     * @throws  NotFoundHttpException
     */
    public static function findById(int $id): Person {
        $model = self::findOne(['id' => $id]);

        if ($model === null) {
            throw new NotFoundHttpException("Person not found");
        }

        return $model;
    }

    /**
     * @throws  NotFoundHttpException
     */
    public static function findByGuid(string $guid): Person {
        $model = self::findOne(['guid' => $guid]);

        if ($model === null) {
            throw new NotFoundHttpException("Person not found");
        }

        return $model;
    }
}
