<?php

namespace App\Models;

use Illuminate\Support\Facades\Storage;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Carbon\Carbon;
use App\Models\User;
use App\Models\Loan;
use App\Models\MonthlySaving;
use App\Models\LoanInstallment;
use App\Models\CommitteeMember;

class Member extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'member_id',
        'name',
        'father_name',
        'mother_name',
        'date_of_birth',
        'gender',
        'nid',
        'phone',
        'email',
        'present_address',
        'permanent_address',
        'occupation',
        'photo',
        'nominee_name',
        'nominee_relation',
        'nominee_nid',
        'nominee_photo',
        'monthly_saving',
        'form_fee',
        'form_fee_paid',
        'registration_date',
        'approval_status',
        'status',
        'created_by'
    ];

    protected $casts = [
        'date_of_birth' => 'date',
        'registration_date' => 'date',
        'form_fee_paid' => 'boolean',
        'monthly_saving' => 'decimal:2',
        'form_fee' => 'decimal:2',
        'deleted_at' => 'datetime',
    ];

    // Accessors
    protected $appends = [
        'formatted_phone',
        'phone_link',
        'email_link',
        'age',
        'full_address',
        'photo_url',
        'nominee_photo_url',
        'status_in_bangla',
        'approval_status_in_bangla',
        'gender_in_bangla',
        'membership_duration',
        'status_class',
        'approval_status_class',
        'form_fee_status_class',
        'form_fee_status_in_bangla',
        'total_savings',
        'total_loan_amount',
        'active_loan_amount',
        'total_loan_paid',
        'total_loan_due',
        'total_due'
    ];

    // স্কোপ: সক্রিয় সদস্য
    public function scopeActive($query)
    {
        return $query->where('status', 'active');
    }

    // স্কোপ: অনুমোদিত সদস্য
    public function scopeApproved($query)
    {
        return $query->where('approval_status', 'approved');
    }

    // স্কোপ: পেন্ডিং সদস্য
    public function scopePending($query)
    {
        return $query->where('status', 'pending');
    }

    // স্কোপ: নিষ্ক্রিয় সদস্য
    public function scopeInactive($query)
    {
        return $query->where('status', 'inactive');
    }

    // স্কোপ: বাতিল সদস্য
    public function scopeTerminated($query)
    {
        return $query->where('status', 'terminated');
    }

    // স্কোপ: ফর্ম ফি পেইড সদস্য
    public function scopeFormFeePaid($query)
    {
        return $query->where('form_fee_paid', true);
    }

    // স্কোপ: ফর্ম ফি বকেয়া সদস্য
    public function scopeFormFeePending($query)
    {
        return $query->where('form_fee_paid', false);
    }

    // স্কোপ: ঋণ আছে এমন সদস্য
    public function scopeHasLoan($query)
    {
        return $query->whereHas('loans', function($q) {
            $q->whereIn('status', ['active', 'disbursed', 'approved']);
        });
    }

    // স্কোপ: নির্দিষ্ট মাসের সঞ্চয় আছে এমন সদস্য
    public function scopeHasSavingInMonth($query, $monthYear)
    {
        return $query->whereHas('monthlySavings', function($q) use ($monthYear) {
            $q->where('month_year', $monthYear);
        });
    }

    // স্বয়ংক্রিয় সদস্য আইডি জেনারেটর
    public static function generateMemberId()
    {
        $year = date('Y');
        $prefix = 'AMB';
        
        // সর্বশেষ সদস্য খুঁজুন
        $lastMember = self::where('member_id', 'like', $prefix . $year . '%')
            ->orderBy('member_id', 'desc')
            ->first();
        
        if ($lastMember && preg_match('/' . $prefix . $year . '(\d{3})/', $lastMember->member_id, $matches)) {
            $lastNumber = intval($matches[1]);
            $nextNumber = str_pad($lastNumber + 1, 3, '0', STR_PAD_LEFT);
        } else {
            $nextNumber = '001';
        }
        
        return $prefix . $year . $nextNumber;
    }

    // রিলেশনশিপ: ব্যবহারকারী
    public function user()
    {
        return $this->hasOne(User::class, 'member_id', 'member_id');
    }

    // রিলেশনশিপ: মাসিক সঞ্চয়
    public function monthlySavings()
    {
        return $this->hasMany(MonthlySaving::class, 'member_id', 'member_id');
    }

    // রিলেশনশিপ: বর্তমান মাসের সঞ্চয়
    public function currentMonthSaving()
    {
        $currentMonth = now()->format('Y-m');
        return $this->hasOne(MonthlySaving::class, 'member_id', 'member_id')
            ->where('month_year', $currentMonth);
    }

    // রিলেশনশিপ: পেইড সঞ্চয়
    public function paidSavings()
    {
        return $this->hasMany(MonthlySaving::class, 'member_id', 'member_id')
            ->where('status', 'paid');
    }

    // রিলেশনশিপ: পেন্ডিং সঞ্চয়
    public function pendingSavings()
    {
        return $this->hasMany(MonthlySaving::class, 'member_id', 'member_id')
            ->where('status', 'pending');
    }

    // রিলেশনশিপ: ঋণ
    public function loans()
    {
        return $this->hasMany(Loan::class, 'member_id', 'member_id');
    }

    // রিলেশনশিপ: সক্রিয় ঋণ
    public function activeLoans()
    {
        return $this->hasMany(Loan::class, 'member_id', 'member_id')
            ->whereIn('status', ['approved', 'disbursed', 'active']);
    }

    // রিলেশনশিপ: পেন্ডিং ঋণ
    public function pendingLoans()
    {
        return $this->hasMany(Loan::class, 'member_id', 'member_id')
            ->where('status', 'pending');
    }

    // রিলেশনশিপ: ডিসবার্সড ঋণ
    public function disbursedLoans()
    {
        return $this->hasMany(Loan::class, 'member_id', 'member_id')
            ->where('status', 'disbursed');
    }

    // রিলেশনশিপ: কমপ্লিটেড ঋণ
    public function completedLoans()
    {
        return $this->hasMany(Loan::class, 'member_id', 'member_id')
            ->where('status', 'completed');
    }

    // রিলেশনশিপ: ডিফল্টেড ঋণ
    public function defaultedLoans()
    {
        return $this->hasMany(Loan::class, 'member_id', 'member_id')
            ->where('status', 'defaulted');
    }

    // রিলেশনশিপ: লোন ইনস্টলমেন্ট (LoanInstallment এর মাধ্যমে)
    public function loanInstallments()
    {
        return $this->hasManyThrough(
            LoanInstallment::class,
            Loan::class,
            'member_id', // Foreign key on loans table
            'loan_id',   // Foreign key on loan_installments table
            'member_id', // Local key on members table
            'id'         // Local key on loans table
        );
    }

    // রিলেশনশিপ: কমিটি সদস্য
    public function committeeMembers()
    {
        return $this->hasMany(CommitteeMember::class, 'member_id', 'member_id');
    }

    // রিলেশনশিপ: সক্রিয় কমিটি
    public function activeCommittee()
    {
        return $this->hasOne(CommitteeMember::class, 'member_id', 'member_id')
            ->whereHas('committee', function($query) {
                $query->where('status', 'active');
            });
    }

    // Accessor: মাসিক সঞ্চয় পরিমাণ
    public function getMonthlySavingAmountAttribute()
    {
        return $this->monthly_saving ?? config('app.monthly_saving_amount', 620);
    }

    // Accessor: মোট সঞ্চয়
    public function getTotalSavingsAttribute()
    {
        return $this->monthlySavings()->where('status', 'paid')->sum('amount');
    }

    // Accessor: মোট ঋণ পরিমাণ
    public function getTotalLoanAmountAttribute()
    {
        return $this->loans()->sum('loan_amount');
    }

    // Accessor: সক্রিয় ঋণ পরিমাণ
    public function getActiveLoanAmountAttribute()
    {
        return $this->activeLoans()->sum('loan_amount');
    }

    // Accessor: মোট ঋণ পরিশোধ
    public function getTotalLoanPaidAttribute()
    {
        return $this->loans()->sum('paid_amount');
    }

    // Accessor: বকেয়া ঋণ
    public function getTotalLoanDueAttribute()
    {
        return $this->loans()->whereIn('status', ['approved', 'disbursed', 'active'])->sum('remaining_balance');
    }

    // Accessor: মোট বকেয়া (ঋণ + সঞ্চয়)
    public function getTotalDueAttribute()
    {
        $loanDue = $this->getTotalLoanDueAttribute();
        $savingDue = $this->pendingSavings()->sum('amount');
        return $loanDue + $savingDue;
    }

    // Method: সদস্য ফর্ম ফি পেমেন্ট চেক
    public function isFormFeePaid()
    {
        return $this->form_fee_paid;
    }

    // Accessor: ফরমেটেড ফোন নম্বর
    public function getFormattedPhoneAttribute()
    {
        $phone = $this->phone;
        if (strlen($phone) == 11 && substr($phone, 0, 2) == '01') {
            return substr($phone, 0, 3) . ' ' . substr($phone, 3, 4) . ' ' . substr($phone, 7, 4);
        }
        return $phone;
    }

    // Accessor: লিংক সহ ফোন নম্বর
    public function getPhoneLinkAttribute()
    {
        return $this->phone ? 'tel:' . $this->phone : null;
    }

    // Accessor: ইমেইল লিংক
    public function getEmailLinkAttribute()
    {
        return $this->email ? 'mailto:' . $this->email : null;
    }

    // Accessor: বয়স
    public function getAgeAttribute()
    {
        if (!$this->date_of_birth) {
            return null;
        }
        
        try {
            return Carbon::parse($this->date_of_birth)->age;
        } catch (\Exception $e) {
            return null;
        }
    }

    // Accessor: পূর্ণ ঠিকানা
    public function getFullAddressAttribute()
    {
        if ($this->present_address && $this->permanent_address) {
            if ($this->present_address === $this->permanent_address) {
                return $this->present_address;
            }
            return $this->present_address . ' (বর্তমান), ' . $this->permanent_address . ' (স্থায়ী)';
        }
        return $this->present_address ?? $this->permanent_address;
    }

    // Accessor: ছবি URL
    public function getPhotoUrlAttribute()
    {
        if ($this->photo && Storage::disk('public')->exists($this->photo)) {
            return asset('storage/' . $this->photo);
        }
        return asset('images/default-avatar.png');
    }

    // Accessor: নমিনি ছবি URL
    public function getNomineePhotoUrlAttribute()
    {
        if ($this->nominee_photo && Storage::disk('public')->exists($this->nominee_photo)) {
            return asset('storage/' . $this->nominee_photo);
        }
        return asset('images/default-avatar.png');
    }

    // Accessor: সদস্য স্ট্যাটাস বাংলায়
    public function getStatusInBanglaAttribute()
    {
        $statuses = [
            'active' => 'সক্রিয়',
            'inactive' => 'নিষ্ক্রিয়',
            'terminated' => 'বাতিল',
            'pending' => 'অপেক্ষমান'
        ];
        
        return $statuses[$this->status] ?? $this->status;
    }

    // Accessor: অনুমোদন স্ট্যাটাস বাংলায়
    public function getApprovalStatusInBanglaAttribute()
    {
        $statuses = [
            'approved' => 'অনুমোদিত',
            'pending' => 'অপেক্ষমান',
            'rejected' => 'প্রত্যাখ্যান'
        ];
        
        return $statuses[$this->approval_status] ?? $this->approval_status;
    }

    // Accessor: লিঙ্গ বাংলায়
    public function getGenderInBanglaAttribute()
    {
        $genders = [
            'male' => 'পুরুষ',
            'female' => 'মহিলা',
            'other' => 'অন্যান্য'
        ];
        
        return $genders[$this->gender] ?? $this->gender;
    }

    // Accessor: নিবন্ধনের সময় থেকে কতদিন
    public function getMembershipDurationAttribute()
    {
        if (!$this->registration_date) {
            return null;
        }
        
        try {
            $now = now();
            $registrationDate = Carbon::parse($this->registration_date);
            
            $years = $registrationDate->diffInYears($now);
            $months = $registrationDate->diffInMonths($now) % 12;
            
            if ($years > 0) {
                return $years . ' বছর ' . $months . ' মাস';
            }
            
            return $months . ' মাস';
        } catch (\Exception $e) {
            return null;
        }
    }

    // Accessor: সদস্য স্ট্যাটাস ক্লাস (UI এর জন্য)
    public function getStatusClassAttribute()
    {
        $classes = [
            'active' => 'badge bg-success',
            'inactive' => 'badge bg-secondary',
            'terminated' => 'badge bg-danger',
            'pending' => 'badge bg-warning'
        ];
        
        return $classes[$this->status] ?? 'badge bg-info';
    }

    // Accessor: অনুমোদন স্ট্যাটাস ক্লাস (UI এর জন্য)
    public function getApprovalStatusClassAttribute()
    {
        $classes = [
            'approved' => 'badge bg-success',
            'pending' => 'badge bg-warning',
            'rejected' => 'badge bg-danger'
        ];
        
        return $classes[$this->approval_status] ?? 'badge bg-info';
    }

    // Accessor: ফর্ম ফি স্ট্যাটাস ক্লাস (UI এর জন্য)
    public function getFormFeeStatusClassAttribute()
    {
        return $this->form_fee_paid ? 'badge bg-success' : 'badge bg-danger';
    }

    // Accessor: ফর্ম ফি স্ট্যাটাস বাংলায়
    public function getFormFeeStatusInBanglaAttribute()
    {
        return $this->form_fee_paid ? 'পরিশোধিত' : 'বকেয়া';
    }

    // ঋণ সম্পর্কিত অতিরিক্ত মেথড
    public function getLoanStatisticsAttribute()
    {
        return [
            'total_approved_loans' => $this->loans()->where('status', 'approved')->count(),
            'total_disbursed_loans' => $this->loans()->where('status', 'disbursed')->count(),
            'total_active_loans' => $this->loans()->whereIn('status', ['disbursed', 'active'])->count(),
            'total_completed_loans' => $this->loans()->where('status', 'completed')->count(),
            'total_defaulted_loans' => $this->loans()->where('status', 'defaulted')->count(),
            
            'total_approved_amount' => $this->loans()->where('status', 'approved')->sum('loan_amount'),
            'total_disbursed_amount' => $this->loans()->where('status', 'disbursed')->sum('loan_amount'),
            'total_active_amount' => $this->loans()->whereIn('status', ['disbursed', 'active'])->sum('loan_amount'),
            'total_paid_amount' => $this->loans()->sum('paid_amount'),
            'total_due_amount' => $this->loans()->whereIn('status', ['approved', 'disbursed', 'active'])->sum('remaining_balance'),
        ];
    }

    // ঋণ গ্রহণের যোগ্যতা চেক
    public function isEligibleForLoan()
    {
        // সক্রিয় সদস্য হতে হবে
        if ($this->status != 'active') {
            return false;
        }
        
        // অনুমোদিত হতে হবে
        if ($this->approval_status != 'approved') {
            return false;
        }
        
        // ফর্ম ফি পরিশোধিত হতে হবে
        if (!$this->form_fee_paid) {
            return false;
        }
        
        // কোনো ডিফল্টেড লোন থাকা যাবে না
        $hasDefaultedLoan = $this->defaultedLoans()->exists();
        if ($hasDefaultedLoan) {
            return false;
        }
        
        // সক্রিয় লোনের সংখ্যা সীমিত
        $activeLoanCount = $this->activeLoans()->count();
        if ($activeLoanCount >= config('app.max_active_loans_per_member', 1)) {
            return false;
        }
        
        return true;
    }

    // সর্বোচ্চ ঋণ গ্রহণের যোগ্যতা
    public function getMaxLoanEligibility()
    {
        if (!$this->isEligibleForLoan()) {
            return 0;
        }
        
        $totalSavings = $this->getTotalSavingsAttribute();
        $maxLoanMultiplier = config('app.loan_to_saving_ratio', 10);
        
        return min(
            $totalSavings * $maxLoanMultiplier,
            config('app.max_loan_amount_per_member', 100000)
        );
    }

    // Method: কার্ডের জন্য সদস্য তথ্য
    public function getCardInfoAttribute()
    {
        return [
            'name' => $this->name,
            'member_id' => $this->member_id,
            'photo_url' => $this->photo_url,
            'phone' => $this->formatted_phone,
            'address' => $this->present_address,
            'registration_date' => $this->registration_date ? $this->registration_date->format('d/m/Y') : '',
            'validity' => $this->registration_date ? $this->registration_date->addYears(1)->format('d/m/Y') : '',
            'qr_code_data' => json_encode([
                'member_id' => $this->member_id,
                'name' => $this->name,
                'phone' => $this->phone,
                'registration_date' => $this->registration_date ? $this->registration_date->format('Y-m-d') : null
            ])
        ];
    }

    // Method: সদস্যের জন্য পরবর্তী মাসের সঞ্চয় তৈরি
    public function createNextMonthSaving()
    {
        $latestSaving = $this->monthlySavings()
            ->orderBy('month_year', 'desc')
            ->first();
        
        if ($latestSaving) {
            try {
                $nextMonth = Carbon::createFromFormat('Y-m', $latestSaving->month_year)
                    ->addMonth()
                    ->format('Y-m');
            } catch (\Exception $e) {
                $nextMonth = now()->format('Y-m');
            }
        } else {
            $nextMonth = now()->format('Y-m');
        }
        
        // চেক করুন যদি ইতিমধ্যেই রেকর্ড থাকে
        $existing = $this->monthlySavings()
            ->where('month_year', $nextMonth)
            ->exists();
            
        if (!$existing) {
            return MonthlySaving::create([
                'member_id' => $this->member_id,
                'month_year' => $nextMonth,
                'amount' => $this->monthly_saving,
                'status' => 'pending',
                'due_date' => Carbon::createFromFormat('Y-m', $nextMonth)->endOfMonth(),
                'created_by' => auth()->id() ?? 1
            ]);
        }
        
        return null;
    }

    // Method: নির্দিষ্ট মাসের সঞ্চয় পান
    public function getSavingForMonth($monthYear)
    {
        return $this->monthlySavings()
            ->where('month_year', $monthYear)
            ->first();
    }

    // Method: নির্দিষ্ট মাসের জন্য লোন ইনস্টলমেন্ট পান
    public function getLoanInstallmentsForMonth($monthYear)
    {
        return $this->loanInstallments()
            ->where('month_year', $monthYear)
            ->get();
    }

    // Method: মোট বকেয়া মাসিক সঞ্চয়
    public function getTotalSavingDue()
    {
        return $this->pendingSavings()->sum('amount');
    }

    // Method: সম্পূর্ণ তথ্য অ্যারে পান
    public function getCompleteInfo()
    {
        return [
            'member' => $this,
            'savings' => [
                'total' => $this->total_savings,
                'monthly_due' => $this->getTotalSavingDue(),
                'current_month' => $this->currentMonthSaving
            ],
            'loans' => [
                'total_amount' => $this->total_loan_amount,
                'active_amount' => $this->active_loan_amount,
                'total_paid' => $this->total_loan_paid,
                'total_due' => $this->total_loan_due,
                'active_loans' => $this->activeLoans
            ],
            'statistics' => $this->getLoanStatisticsAttribute(),
            'committee_info' => $this->activeCommittee
        ];
    }

    // Boot method for model events
    protected static function boot()
    {
        parent::boot();

        // Generate member_id before creating
        static::creating(function ($member) {
            if (empty($member->member_id)) {
                $member->member_id = self::generateMemberId();
            }
            
            // Set registration date if not provided
            if (empty($member->registration_date)) {
                $member->registration_date = now();
            }
        });

        // After member is created
        static::created(function ($member) {
            // Create initial monthly saving
            if ($member->monthly_saving > 0) {
                $member->createNextMonthSaving();
            }
        });

        // After member is updated
        static::updated(function ($member) {
            // If monthly saving amount changed
            if ($member->wasChanged('monthly_saving')) {
                // Update future pending savings
                $member->monthlySavings()
                    ->where('status', 'pending')
                    ->whereDate('due_date', '>', now())
                    ->update(['amount' => $member->monthly_saving]);
            }
            
            // If status changed to inactive or terminated
            if ($member->wasChanged('status') && in_array($member->status, ['inactive', 'terminated'])) {
                // Deactivate user account
                $user = User::where('member_id', $member->member_id)->first();
                if ($user) {
                    $user->status = 'inactive';
                    $user->save();
                }
                
                // Deactivate all active loans
                $member->loans()->whereIn('status', ['approved', 'disbursed', 'active'])->update([
                    'status' => 'inactive'
                ]);
            }
            
            // If status changed to active
            if ($member->wasChanged('status') && $member->status == 'active') {
                // Activate user account
                $user = User::where('member_id', $member->member_id)->first();
                if ($user) {
                    $user->status = 'active';
                    $user->save();
                }
            }
        });

        // Before member is deleted (soft delete)
        static::deleting(function ($member) {
            if ($member->isForceDeleting()) {
                // Hard delete related records
                $member->monthlySavings()->delete();
                $member->loans()->delete();
                $member->committeeMembers()->delete();
                
                // Delete associated user
                User::where('member_id', $member->member_id)->delete();
            }
        });
    }
}