<?php

namespace App\Models;

use App\Notifications\ResetUserPassword;
use App\Notifications\VerifyUserEmail;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Storage;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable implements MustVerifyEmail
{
    use HasApiTokens, HasFactory, Notifiable, CanResetPassword;

    protected $attributes = [
        'state' => ['pendingEmailValidation', 'pendingApproval', 'active', 'inactive'],
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    protected $fillable = [
        'name',
        'first_name',
        'last_name',
        'email',
        'password',
        'department',
        'function',
        'phone_number',
        'state',
        'member_id',
        'image_id',
        'ms_id'
    ];

    public function image() {
        return $this->belongsTo(MediaItem::class);
    }

    public function member()
    {
        return $this->belongsTo(Member::class);
    }

    public function workGroups()
    {
        return $this->belongsToMany(WorkGroup::class)->withPivot('type');
    }

    public function committees()
    {
        return $this->belongsToMany(Committee::class)->withPivot('type');
    }

    public function documentLists()
    {
        return $this->belongsToMany(DocumentList::class)->withPivot('position');
    }

    public function sendPasswordUserResetNotification($token, $email)
    {
        $this->notify(new ResetUserPassword($token, $email));
    }

    public function sendEmailVerificationNotification()
    {
        $this->notify(new VerifyUserEmail);
    }

    protected static function boot()
    {
        parent::boot();

        static::updating(function ($user) {
            // Track state changes for Microsoft Graph sync

            if ($user->isDirty('state')) {
                $oldState = $user->getOriginal('state');
                $newState = $user->state;

                try {
                    // Find all committees and workgroups this user belongs to
                    $committees = $user->committees()->withPivot('type')->get();
                    $workGroups = $user->workGroups()->withPivot('type')->get();

                    // Create state change records for each committee/workgroup membership
                    foreach ($committees as $committee) {
                        MsgraphPendingChange::create([
                            'action' => 'user_state_changed',
                            'user_id' => $user->id,
                            'model_type' => Committee::class,
                            'model_id' => $committee->id,
                            'old_membership_type' => $committee->pivot->type,
                            'new_membership_type' => $committee->pivot->type,
                            'metadata' => [
                                'user_email' => $user->email,
                                'user_name' => $user->name,
                                'old_state' => $oldState,
                                'new_state' => $newState,
                                'changed_at' => now()->toISOString()
                            ],
                            'processed' => false,
                            'priority' => 'normal'
                        ]);
                    }

                    foreach ($workGroups as $workGroup) {
                        MsgraphPendingChange::create([
                            'action' => 'user_state_changed',
                            'user_id' => $user->id,
                            'model_type' => WorkGroup::class,
                            'model_id' => $workGroup->id,
                            'old_membership_type' => $workGroup->pivot->type,
                            'new_membership_type' => $workGroup->pivot->type,
                            'metadata' => [
                                'user_email' => $user->email,
                                'user_name' => $user->name,
                                'old_state' => $oldState,
                                'new_state' => $newState,
                                'changed_at' => now()->toISOString()
                            ],
                            'processed' => false,
                            'priority' => 'normal'
                        ]);
                    }

                } catch (\Exception $e) {
                    //
                }
            }
        });

        static::deleting(function ($user) {
            // Handle profile image cleanup
            $image = $user->image;
            if ($image) {
                $filePath = 'profile_images/' . $image;

                if (Storage::disk('public')->exists($filePath)) {
                    Storage::disk('public')->delete($filePath);
                }
            }

            // Track user deletion for Microsoft Graph sync
            try {
                // Find all committees and workgroups this user belongs to
                $committees = $user->committees()->withPivot('type')->get();
                $workGroups = $user->workGroups()->withPivot('type')->get();

                // Create user_deleted changes for each committee/workgroup membership
                foreach ($committees as $committee) {
                    MsgraphPendingChange::create([
                        'action' => 'user_deleted',
                        'user_id' => $user->id,
                        'model_type' => Committee::class,
                        'model_id' => $committee->id,
                        'old_membership_type' => $committee->pivot->type,
                        'new_membership_type' => null,
                        'metadata' => [
                            'user_email' => $user->email,
                            'user_name' => $user->name,
                            'deleted_at' => now()->toISOString()
                        ],
                        'processed' => false,
                        'priority' => 'high'
                    ]);
                }

                foreach ($workGroups as $workGroup) {
                    MsgraphPendingChange::create([
                        'action' => 'user_deleted',
                        'user_id' => $user->id,
                        'model_type' => WorkGroup::class,
                        'model_id' => $workGroup->id,
                        'old_membership_type' => $workGroup->pivot->type,
                        'new_membership_type' => null,
                        'metadata' => [
                            'user_email' => $user->email,
                            'user_name' => $user->name,
                            'deleted_at' => now()->toISOString()
                        ],
                        'processed' => false,
                        'priority' => 'high'
                    ]);
                }

            } catch (\Exception $e) {
                //
            }
        });
    }
}
