<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Casts\Attribute;

class User extends Authenticatable
{
    protected $connection = 'mysql';
  
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'email',
        'organization_id',
        'user_name',
        'region',
        'address',
        'city', 'country', 'role', 'password',
        'profile_visibility', 'display_name_format', 'include_in_stats',
        'show_salary_to_connections', 'allow_comparison_requests',
        'show_activity_to_connections', 'show_online_status',
        'product_updates', 'weekly_reports', 'marketing_emails',
        'notify_messages', 'notify_connections', 'notify_activity',
        'push_messages', 'push_alerts', 'language', 'theme'
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list<string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
            'include_in_stats' => 'boolean',
            'show_salary_to_connections' => 'boolean',
            'allow_comparison_requests' => 'boolean',
            'show_activity_to_connections' => 'boolean',
            'show_online_status' => 'boolean',
            'product_updates' => 'boolean',
            'weekly_reports' => 'boolean',
            'marketing_emails' => 'boolean',
            'notify_messages' => 'boolean',
            'notify_connections' => 'boolean',
            'notify_activity' => 'boolean',
            'push_messages' => 'boolean',
            'push_alerts' => 'boolean',
        ];
    }

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

    public function isRegular(): bool
    {
        return $this->role === 'regular';
    }

    public function isMember(): bool
    {
        return $this->role === 'member';
    }

    public function isAdmin(): bool
    {
        return $this->role === 'admin';
    }

    public function isOrganizationAdmin(): bool
    {
        return $this->isAdmin() && $this->organization_id !== null;
    }

    // Job Experience Relationships
    public function jobExperiences(): HasMany
    {
        return $this->hasMany(JobExperience::class);
    }

    public function publishedJobs(): HasMany
    {
        return $this->hasMany(JobExperience::class)->published();
    }

    public function activeJob(): BelongsTo
    {
        return $this->belongsTo(JobExperience::class, 'id', 'user_id')
            ->where('is_published', true);
    }

    public function hasPublishedJob(): bool
    {
        return $this->publishedJobs()->exists();
    }

    public function getTotalExperienceAttribute(): float
    {
        return $this->jobExperiences->max('years_of_experience') ?? 0;
    }

    // Rate My Pay Relationships
    public function rateMyPays(): HasMany
    {
        return $this->hasMany(RateMyPay::class);
    }

    public function ratings(): HasMany
    {
        return $this->hasMany(Rating::class);
    }

    public function postComments(): HasMany
    {
        return $this->hasMany(PostComment::class);
    }

    public function postLikes(): HasMany
    {
        return $this->hasMany(PostLike::class);
    }

    public function getPublicRateMyPays()
    {
        return $this->rateMyPays()
            ->withCount(['likes', 'comments', 'ratings'])
            ->latest();
    }

    public function hasRated(RateMyPay $rateMyPay): bool
    {
        return $this->ratings()->where('rate_my_pay_id', $rateMyPay->id)->exists();
    }

    public function getRatingFor(RateMyPay $rateMyPay): ?Rating
    {
        return $this->ratings()->where('rate_my_pay_id', $rateMyPay->id)->first();
    }

    // Community Relationships
    public function createdCommunities()
    {
        return $this->hasMany(Community::class, 'user_id');
    }
    
    public function communities(): BelongsToMany
    {
        return $this->belongsToMany(Community::class, 'community_user')
            ->withPivot('role', 'joined_at')
            ->withTimestamps();
    }

    public function moderatedCommunities(): BelongsToMany
    {
        return $this->belongsToMany(Community::class, 'community_user')
            ->wherePivotIn('role', ['moderator', 'admin'])
            ->withPivot('role', 'joined_at');
    }

    // Methods
    public function isMemberOf(Community $community): bool
    {
        return $this->communities()->where('community_id', $community->id)->exists();
    }

    public function getCommunityRole(Community $community): ?string
    {
        $membership = $this->communities()
            ->where('community_id', $community->id)
            ->first();

        return $membership ? $membership->pivot->role : null;
    }

    public function canPostInCommunity(Community $community): bool
    {
        return $this->isMemberOf($community);
    }

    public function getCommunityPosts(Community $community)
    {
        return $this->rateMyPays()
            ->whereHas('communities', function($query) use ($community) {
                $query->where('communities.id', $community->id);
            })
            ->latest();
    }

    // ==========================================
    // NEW: Connection Relationships
    // ==========================================
    
    public function sentConnections()
    {
        return $this->belongsToMany(User::class, 'connections', 'requester_id', 'recipient_id')
            ->withPivot('status', 'created_at')
            ->withTimestamps();
    }

    public function receivedConnections()
    {
        return $this->belongsToMany(User::class, 'connections', 'recipient_id', 'requester_id')
            ->withPivot('status', 'created_at')
            ->withTimestamps();
    }

    // NEW: Accessors for Blade Card Component

    // Map 'user_name' to 'nickname' for the Blade card
    protected function nickname(): Attribute
    {
        return Attribute::make(
            get: fn () => $this->user_name ?? explode(' ', $this->name)[0]
        );
    }

    // Map latest Job Title to 'role'
    protected function role(): Attribute
    {
        return Attribute::make(
            get: fn () => $this->activeJob->job_title ?? 'Member'
        );
    }

    // Map Industry to 'companyType'
    protected function companyType(): Attribute
    {
        return Attribute::make(
            get: fn () => $this->activeJob->industry ?? 'Tech'
        );
    }

    // Map Salary
    protected function salary(): Attribute
    {
        return Attribute::make(
            get: fn () => $this->activeJob 
                ? ($this->activeJob->currency . ' ' . number_format($this->activeJob->annual_base_salary)) 
                : 'Not disclosed'
        );
    }

    // Map Location
    protected function location(): Attribute
    {
        return Attribute::make(
            get: fn () => $this->city ? "{$this->city}, {$this->country}" : 'Remote'
        );
    }

    // Map Experience Years
    protected function yoe(): Attribute
    {
        return Attribute::make(
            get: fn () => $this->activeJob->years_of_experience ?? 0
        );
    }

    // Generate Tags dynamically from job data
    protected function tags(): Attribute
    {
        return Attribute::make(
            get: function () {
                $tags = [];
                if ($this->activeJob) {
                    if ($this->activeJob->industry) $tags[] = $this->activeJob->industry;
                    if ($this->activeJob->level) $tags[] = $this->activeJob->level;
                    if ($this->activeJob->work_arrangement) $tags[] = $this->activeJob->work_arrangement;
                }
                return empty($tags) ? ['Member'] : array_slice($tags, 0, 3);
            }
        );
    }
}
