<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Member extends Model
{
  use HasFactory, SoftDeletes;

  /**
   * The table associated with the model.
   */
  protected $table = 'members';

  /**
   * The attributes that are mass assignable.
   */
  protected $fillable = [
    'api_member_id',
    'member_number',
    'member_code',
    'title',
    'first_name',
    'middle_name',
    'last_name',
    'email',
    'mobile',
    'date_of_birth',
    'gender',
    'nationality',
    'address_line1',
    'address_line2',
    'city',
    'state',
    'country',
    'postal_code',
    'tier',
    'tier_data',
    'points',
    'balances',
    'enrollment_date',
    'enrollment_touchpoint',
    'enrollment_channel',
    'enrolling_sponsor',
    'enrolling_location',
    'status',
    'email_verified',
    'mobile_verified',
    'marketing_opt_in',
    'extra_data',
    'last_synced_at',
    'last_login_at',
    'member_token',
    'token_expires_at',
    'user_id',
  ];

  /**
   * The attributes that should be cast.
   */
  protected $casts = [
    'date_of_birth' => 'date',
    'enrollment_date' => 'date',
    'email_verified' => 'boolean',
    'mobile_verified' => 'boolean',
    'marketing_opt_in' => 'boolean',
    'extra_data' => 'array',
    'tier_data' => 'array',
    'balances' => 'array',
    'last_synced_at' => 'datetime',
    'last_login_at' => 'datetime',
    'token_expires_at' => 'datetime',
    'created_at' => 'datetime',
    'updated_at' => 'datetime',
    'deleted_at' => 'datetime',
    'points' => 'integer',
    'enrollment_touchpoint' => 'integer',
    'enrolling_sponsor' => 'integer',
    'enrolling_location' => 'integer',
  ];

  /**
   * Get the user associated with the member.
   */
  public function user()
  {
    return $this->belongsTo(User::class);
  }

  /**
   * Get the full name of the member.
   */
  public function getFullNameAttribute()
  {
    return $this->first_name . ' ' . $this->last_name;
  }

  /**
   * Get the formatted mobile number.
   */
  public function getFormattedMobileAttribute()
  {
    return preg_replace('/(\d{3})(\d{3})(\d{4})/', '($1) $2-$3', $this->mobile);
  }

  /**
   * Check if member is active.
   */
  public function isActive()
  {
    return $this->status === 'active';
  }

  /**
   * Check if member email is verified.
   */
  public function hasVerifiedEmail()
  {
    return $this->email_verified === true;
  }

  /**
   * Check if member mobile is verified.
   */
  public function hasVerifiedMobile()
  {
    return $this->mobile_verified === true;
  }

  /**
   * Scope to get only active members.
   */
  public function scopeActive($query)
  {
    return $query->where('status', 'active');
  }

  /**
   * Scope to get members by tier.
   */
  public function scopeByTier($query, $tier)
  {
    return $query->where('tier', $tier);
  }

  /**
   * Scope to get verified members.
   */
  public function scopeVerified($query)
  {
    return $query->where('email_verified', true)
      ->orWhere('mobile_verified', true);
  }

  /**
   * Create member from API response.
   */
  public static function createFromApiResponse($apiData, $requestData)
  {
    return self::create([
      'api_member_id' => $apiData['id'] ?? $apiData['member_id'] ?? null,
      'member_number' => $apiData['member_number'] ?? $apiData['membership_number'] ?? $apiData['member_id'] ?? null,
      'member_code' => $apiData['member_code'] ?? null,
      'first_name' => $requestData['first_name'],
      'last_name' => $requestData['last_name'],
      'email' => $requestData['email'],
      'mobile' => $requestData['mobile'],
      'date_of_birth' => $apiData['date_of_birth'] ?? null,
      'gender' => $apiData['gender'] ?? null,
      'address_line1' => $apiData['address_line1'] ?? null,
      'address_line2' => $apiData['address_line2'] ?? null,
      'city' => $apiData['city'] ?? null,
      'state' => $apiData['state'] ?? null,
      'country' => $apiData['country'] ?? null,
      'postal_code' => $apiData['postal_code'] ?? null,
      'tier' => $apiData['tier'] ?? $apiData['membership_tier'] ?? null,
      'points' => $apiData['points'] ?? 0,
      'enrollment_date' => $apiData['enrollment_date'] ?? now(),
      'enrollment_touchpoint' => $requestData['enrollment_touchpoint'] ?? null,
      'enrollment_channel' => $requestData['enrollment_channel'] ?? null,
      'enrolling_sponsor' => $requestData['enrolling_sponsor'] ?? null,
      'enrolling_location' => $requestData['enrolling_location'] ?? null,
      'status' => $apiData['status'] ?? 'active',
      'email_verified' => $apiData['email_verified'] ?? false,
      'mobile_verified' => $apiData['mobile_verified'] ?? false,
      'marketing_opt_in' => $apiData['marketing_opt_in'] ?? false,
      'extra_data' => $apiData['extra_data'] ?? $apiData,
      'last_synced_at' => now(),
    ]);
  }

  /**
   * Update member from API response.
   */
  public function updateFromApiResponse($apiData)
  {
    $this->update([
      'api_member_id' => $apiData['id'] ?? $this->api_member_id,
      'member_number' => $apiData['member_number'] ?? $this->member_number,
      'tier' => $apiData['tier'] ?? $this->tier,
      'points' => $apiData['points'] ?? $this->points,
      'status' => $apiData['status'] ?? $this->status,
      'email_verified' => $apiData['email_verified'] ?? $this->email_verified,
      'mobile_verified' => $apiData['mobile_verified'] ?? $this->mobile_verified,
      'extra_data' => $apiData,
      'last_synced_at' => now(),
    ]);

    return $this;
  }

  /**
   * Update member from login API response.
   */
  public function updateFromLoginResponse($loginData)
  {
    $memberData = $loginData['member_data'] ?? [];
    $userData = $memberData['user'] ?? [];

    // Extract tier information
    $tierData = $memberData['tier_data'] ?? [];
    $tierCode = null;
    if (!empty($tierData) && isset($tierData[0]['tier_code_id'])) {
      $tierCode = $tierData[0]['tier_code_id'];
    }

    $this->update([
      'api_member_id' => $memberData['id'] ?? $this->api_member_id,
      'member_number' => $memberData['member_id'] ?? $this->member_number,
      'first_name' => $userData['first_name'] ?? $this->first_name,
      'last_name' => $userData['last_name'] ?? $this->last_name,
      'email' => $userData['email'] ?? $this->email,
      'mobile' => $memberData['mobile'] ?? $this->mobile,
      'date_of_birth' => $memberData['date_of_birth'] ?? $this->date_of_birth,
      'gender' => $memberData['gender'] ?? $this->gender,
      'address_line1' => $memberData['address_line1'] ?? $this->address_line1,
      'address_line2' => $memberData['address_line2'] ?? $this->address_line2,
      'city' => $memberData['city_name'] ?? $this->city,
      'state' => $memberData['region_name'] ?? $this->state,
      'country' => $memberData['country_name'] ?? $this->country,
      'postal_code' => $memberData['postal_code'] ?? $this->postal_code,
      'tier' => $tierCode ?? $this->tier,
      'tier_data' => $tierData,
      'points' => 0, // Points are in balances, not directly provided
      'balances' => $memberData['balances'] ?? [],
      'enrollment_date' => $memberData['date_of_joining'] ?? $this->enrollment_date,
      'enrollment_touchpoint' => $memberData['enrollment_touchpoint'] ?? $this->enrollment_touchpoint,
      'enrollment_channel' => $memberData['enrollment_channel'] ?? $this->enrollment_channel,
      'enrolling_sponsor' => $memberData['enrolling_sponsor'] ?? $this->enrolling_sponsor,
      'status' => strtolower($memberData['membership_stage'] ?? 'active'),
      'email_verified' => $memberData['email_validated'] === 'YES',
      'mobile_verified' => $memberData['phone_validated'] === 'YES',
      'marketing_opt_in' => $memberData['receive_offers'] ?? false,
      'extra_data' => $memberData,
      'member_token' => $loginData['token'] ?? $this->member_token,
      'token_expires_at' => isset($loginData['expires_in'])
        ? now()->addSeconds((int)$loginData['expires_in'])
        : $this->token_expires_at,
      'last_synced_at' => now(),
      'last_login_at' => now(),
    ]);

    return $this;
  }

  /**
   * Check if member token is valid.
   */
  public function hasValidToken()
  {
    return $this->member_token &&
      $this->token_expires_at &&
      $this->token_expires_at->isFuture();
  }

  /**
   * Get member by membership number.
   */
  public static function findByMemberNumber($memberNumber)
  {
    return self::where('member_number', $memberNumber)->first();
  }
}
