<?php

namespace App\Services\AnalyticsReports;

use App\Utils\AnalyticsReportUserTypes;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class FrequentLoyalUsersReport extends BaseAnalyticsReport implements AnalyticsReportInterface
{
    private $reportMinOrderCount;

    /**
     * FrequentLoyalUsersReport constructor.
     * @param Carbon $startDate
     * @param Carbon $endDate
     * @param string $country
     * @param string $userType
     */
    public function __construct(Carbon $startDate, Carbon $endDate, string $country = null, string $userType = AnalyticsReportUserTypes::NON_MERCHANTS)
    {
        parent::__construct($startDate, $endDate, $country, $userType);
        $this->reportMinOrderCount = 1;
    }

    /**
     * @param null $limit
     * @return mixed
     */
    public function getQuery($limit = null)
    {
        $numOfDays = $this->endDate->diffInDays($this->startDate) + 1;

        $query = DB::query()->fromSub(function ($subQuery) {
            $subQuery
                ->from('user_sales as us')
                ->select(['us.user_id'])
                ->selectRaw('DATE(`us`.`transaction_time`) as date')
                ->selectRaw('COUNT(`us`.`id`) as count')
                ->where('us.status', '!=', 'declined')
                ->whereBetween('us.transaction_time', [$this->startDate->startOfDay()->toDateTimeString(), $this->endDate->endOfDay()->toDateTimeString()])
                ->groupBy(['us.user_id', DB::raw('DATE(`us`.`transaction_time`)')])
                ->havingRaw("COUNT(`us`.`id`) >= {$this->reportMinOrderCount}");
        }, 'report_summary')
            ->leftJoin('users as u', 'u.user_id', '=', 'report_summary.user_id')
            ->where('u.is_merchant', 0)
            ->groupBy('report_summary.user_id')
            ->havingRaw("COUNT(`report_summary`.`date`) = {$numOfDays}")
            ->orderBy('report_summary.user_id');

        if ($this->country)
            $query->where('u.country_code', $this->country);

        switch ($this->userType) {
            case AnalyticsReportUserTypes::NON_MERCHANTS:
                $query->where('u.is_merchant', '=', 0);
                break;
            case AnalyticsReportUserTypes::MERCHANTS:
                $query->where('u.is_merchant', '=', 1);
                break;
            default:
                break;
        }

        if ($limit) $query->limit($limit);
        return $query;
    }

    /**
     * @return array
     */
    public function getHeaders()
    {
        return [
            'User ID' => 'u.user_id',
            'First Name' => 'u.first_name',
            'Last Name' => 'u.last_name',
            'Email' => 'u.email',
            'Phone Number' => 'u.phone_number',
            '# of Orders' => DB::raw('SUM(`report_summary`.`count`) as orders_count')
        ];
    }

    /**
     * @return string
     */
    public function getCountColumn()
    {
        return 'u.user_id';
    }
}