<?php

namespace App\Repositories\Warehouse;

use App\Repositories\BaseRepository;
use App\Models\Warehouse\Supplier;
use Illuminate\Database\Eloquent\Builder;
use Carbon\Carbon;

class SupplierRepository extends BaseRepository
{
    /**
     * Create a new repository instance.
     */
    public function __construct(Supplier $model)
    {
        $this->model = $model;
    }

    /**
     * Get suppliers for DataTables.
     */
    public function getForDataTable(array $filters = [])
    {
        $query = $this->model->with(['createdBy'])
                            ->where('is_active', true)
                            ->select([
                                'id',
                                'supplier_code',
                                'name',
                                'contact_person',
                                'email',
                                'phone',
                                'city',
                                'country',
                                'status',
                                'is_active',
                                'rating',
                                'payment_terms',
                                'created_at',
                                'created_by'
                            ]);

        // Apply filters
        $query = $this->applyFilters($query, $filters);

        return $query;
    }

    /**
     * Get active suppliers for dropdown.
     */
    public function getActiveForDropdown()
    {
        return $this->model->active()
                          ->select('id', 'supplier_code', 'name')
                          ->orderBy('name')
                          ->get()
                          ->map(function ($supplier) {
                              return [
                                  'id' => $supplier->id,
                                  'text' => $supplier->supplier_code . ' - ' . $supplier->name
                              ];
                          });
    }

    /**
     * Get top performers.
     */
    public function getTopPerformers($limit = 10)
    {
        return $this->model->active()
                          ->where('rating', '>', 0)
                          ->orderBy('rating', 'desc')
                          ->limit($limit)
                          ->get();
    }

    /**
     * Get suppliers by performance score.
     */
    public function getByPerformanceScore($minScore = 70)
    {
        return $this->model->active()
                          ->get()
                          ->filter(function ($supplier) use ($minScore) {
                              return $supplier->performance_score >= $minScore;
                          });
    }

    /**
     * Get suppliers by rating.
     */
    public function getByRating($minRating = 3.0)
    {
        return $this->model->where('rating', '>=', $minRating)
                          ->where('status', 'active')
                          ->orderBy('rating', 'desc')
                          ->get();
    }

    /**
     * Get suppliers by location.
     */
    public function getByLocation(string $country = null, string $city = null)
    {
        $query = $this->model->active();

        if ($country) {
            $query->where('country', $country);
        }

        if ($city) {
            $query->where('city', $city);
        }

        return $query->orderBy('name')->get();
    }

    /**
     * Get suppliers with recent activity.
     */
    public function getWithRecentActivity($days = 30)
    {
        $date = Carbon::now()->subDays($days);

        return $this->model->active()
                          ->whereHas('incomingTransactions', function ($query) use ($date) {
                              $query->where('created_at', '>=', $date);
                          })
                          ->with(['incomingTransactions' => function ($query) use ($date) {
                              $query->where('created_at', '>=', $date);
                          }])
                          ->get();
    }

    /**
     * Get suppliers due for review.
     */
    public function getDueForReview($monthsThreshold = 6)
    {
        $date = Carbon::now()->subMonths($monthsThreshold);

        return $this->model->active()
                          ->where(function ($query) use ($date) {
                              $query->where('updated_at', '<=', $date)
                                    ->orWhereNull('rating')
                                    ->orWhere('rating', 0);
                          })
                          ->get();
    }

    /**
     * Get supplier statistics.
     */
    public function getStatistics()
    {
        return [
            'total_suppliers' => $this->model->count(),
            'active_suppliers' => $this->model->active()->count(),
            'inactive_suppliers' => $this->model->inactive()->count(),
            'top_rated_suppliers' => $this->model->where('rating', '>=', 4.0)->count(),
            'average_rating' => $this->model->where('rating', '>', 0)->avg('rating') ?? 0,
            'suppliers_with_outstanding_payments' => $this->getWithOutstandingPayments()->count(),
            'new_suppliers_this_month' => $this->getNewSuppliersThisMonth()->count(),
        ];
    }

    /**
     * Get suppliers with outstanding payments.
     */
    public function getWithOutstandingPayments()
    {
        // This would query based on unpaid invoices
        // For now, return empty collection
        return collect();
    }

    /**
     * Get new suppliers this month.
     */
    public function getNewSuppliersThisMonth()
    {
        return $this->model->where('created_at', '>=', Carbon::now()->startOfMonth())
                          ->get();
    }

    /**
     * Apply supplier-specific search filters.
     */
    protected function applySearchFilter(Builder $query, $search)
    {
        return $query->where(function ($q) use ($search) {
            $q->where('name', 'LIKE', "%{$search}%")
              ->orWhere('supplier_code', 'LIKE', "%{$search}%")
              ->orWhere('contact_person', 'LIKE', "%{$search}%")
              ->orWhere('email', 'LIKE', "%{$search}%")
              ->orWhere('phone', 'LIKE', "%{$search}%")
              ->orWhere('city', 'LIKE', "%{$search}%")
              ->orWhere('country', 'LIKE', "%{$search}%");
        });
    }

    /**
     * Apply supplier-specific filters.
     */
    protected function applyFilters(Builder $query, array $filters)
    {
        foreach ($filters as $key => $value) {
            if ($value === null || $value === '') {
                continue;
            }

            switch ($key) {
                case 'status':
                    $query->where('status', $value);
                    break;
                case 'country':
                    $query->where('country', $value);
                    break;
                case 'city':
                    $query->where('city', $value);
                    break;
                case 'payment_terms':
                    $query->where('payment_terms', $value);
                    break;
                case 'rating_min':
                    $query->where('rating', '>=', $value);
                    break;
                case 'rating_max':
                    $query->where('rating', '<=', $value);
                    break;
                case 'created_from':
                    $query->where('created_at', '>=', $value);
                    break;
                case 'created_to':
                    $query->where('created_at', '<=', $value);
                    break;
                case 'has_transactions':
                    if ($value) {
                        $query->whereHas('incomingTransactions');
                    }
                    break;
                case 'search':
                    $this->applySearchFilter($query, $value);
                    break;
            }
        }

        return $query;
    }

    /**
     * Get countries for filter dropdown.
     */
    public function getCountries()
    {
        return $this->model->select('country')
                          ->distinct()
                          ->whereNotNull('country')
                          ->where('country', '!=', '')
                          ->orderBy('country')
                          ->pluck('country');
    }

    /**
     * Get cities for filter dropdown.
     */
    public function getCities($country = null)
    {
        $query = $this->model->select('city')
                            ->distinct()
                            ->whereNotNull('city')
                            ->where('city', '!=', '');

        if ($country) {
            $query->where('country', $country);
        }

        return $query->orderBy('city')->pluck('city');
    }

    /**
     * Get payment terms for filter dropdown.
     */
    public function getPaymentTerms()
    {
        return $this->model->select('payment_terms')
                          ->distinct()
                          ->whereNotNull('payment_terms')
                          ->where('payment_terms', '!=', '')
                          ->orderBy('payment_terms')
                          ->pluck('payment_terms');
    }
}