<?php

namespace App\Models;

use App\Modules\Bookings\Device;
use App\Modules\Bookings\Task;
use App\Models\ValidationModel;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;

class Keychain extends ValidationModel
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'keychain';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['client_id', 'client_type', 'type','username', 'password', 'device_id', 'created_by', 'updated_by'];

    /**
     * Array of validation rules.
     *
     * @var  array
     */
    protected static $rules = [
        'client_id'   => 'required',
        'client_type' => 'required',
        'username'    => 'required',
    ];

    /**
     * Insert the validation checks on the model.
     * The model only gets created if the validation checks pass.
     *
     * @var void
     */
    public static function boot()
    {
        parent::boot();

        // When a transaction is created we want to
        // update the created_by field
        static::creating(function ($model) {
            $model->created_by = Auth::user()->id;
            $model->updated_by = Auth::user()->id;
        });

        // When a transaction gets updated we want to know who
        // updated it
        static::updating(function ($model) {
            $model->updated_by = Auth::user()->id;
        });
    }

    /**
     * Retrieves a list of possible password types.
     *
     * @return array
     */
    public static function getTypes()
    {
        return [
            'windows'   => 'Windows',
            'osx'       => 'Apple OSX',
            'appleid'   => 'Apple ID',
            'icloud'    => 'iCloud',
            'email'     => 'Email',
            'skype'     => 'Skype',
            'bitlocker' => 'BitLocker',
        ];
    }

    /**
     * Decrypt the password.
     *
     * @param  (string) $value : encrypted value
     *
     * @return (string) plain text password
     */
    public function getPasswordAttribute($value)
    {
        // If value is null or empty, return as is
        if (empty($value)) {
            return $value;
        }

        // Check if the value looks like it's encrypted (Laravel encrypted values start with base64 encoded data)
        // Laravel encrypted values are typically longer and contain special characters
        if (strlen($value) > 50 && preg_match('/^[A-Za-z0-9+\/=]+$/', $value)) {
            try {
                $password = Crypt::decrypt($value);
                return $password;
            } catch (\Illuminate\Contracts\Encryption\DecryptException $e) {
                // If decryption fails due to invalid MAC or corrupted data, return null
                return null;
            } catch (\Exception $e) {
                // If any other decryption error occurs, return null
                return null;
            }
        }

        // If it doesn't look encrypted, return as plain text
        return $value;
    }

    /**
     * Encrypts the password.
     *
     * @param  (string) $value : plain text password
     *
     * @return void
     */
    public function setPasswordAttribute($value)
    {
        // Only encrypt if the value is not empty and not already encrypted
        if (!empty($value)) {
            // Check if it's already encrypted (same logic as getter)
            if (strlen($value) <= 50 || !preg_match('/^[A-Za-z0-9+\/=]+$/', $value)) {
                $this->attributes['password'] = Crypt::encrypt($value);
            } else {
                // Already encrypted, store as is
                $this->attributes['password'] = $value;
            }
        } else {
            $this->attributes['password'] = $value;
        }
    }

    /**
     * The device item of the keychain.
     *
     * @return Illuminate\Database\Eloquent\Relations\BenlongsTo
     */
    public function device(): BelongsTo
    {
        return $this->belongsTo(Device::class);
    }

    /**
     * The task with this keychain.
     *
     * @return Illuminate\Database\Eloquent\Relations\BenlongsTo
     */
    public function tasks()
    {
        return $this->belongsToMany(Task::class, 'task_keychains');
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}
