<?php

namespace App\Repositories\Member\Voucher;

use App\Models\Voucher;
use App\Models\Customer;
use App\Models\User;
use App\Models\Cart;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
use Carbon\Carbon;

class VoucherRepository
{
    public function getList($request)
    {
        $user_id = auth()->user()->id;
        $customer = Customer::where("user_id", $user_id)->first();
        $model = Voucher::where('customer_id', (int) @$customer->id)
        ->where('used_at', null)
        ->where('expired_at','>=',Carbon::now())
        ->orderBy('created_at','desc')->paginate($request->limit ?? 100);

        return $model;
    }


    public function getValidByItems($carts, $customer_id)
    {
        $item_reference_ids = $carts->pluck("item_reference_id")->toArray();
        // collect voucher ids valids
        if (count($item_reference_ids) == 0){
            $item_reference_ids[] = 0;
        }

        $item_ids = implode(',', $item_reference_ids);
        $ids = DB::select("SELECT distinct vouchers.id from vouchers
            left join voucher_events on vouchers.voucher_event_id = voucher_events.id
            left join voucher_items on voucher_items.voucher_event_id = voucher_events.id
            where used_at is null and
                (expired_at > now() or expired_at is null) and
                customer_id = ? and (
                redeem_point > 0 or
                ( vouchers.voucher_event_id is null and vouchers.item_reference_id is null) or
                ( vouchers.voucher_event_id is not null and voucher_items.item_reference_id is null) or
                ( vouchers.item_reference_id is not null and vouchers.item_reference_id in ($item_ids)) or
                ( vouchers.voucher_event_id is not null and voucher_items.item_reference_id in ($item_ids))
                )",[$customer_id]);
        $ids = collect($ids)->pluck("id")->toArray();
        return $ids;
    }

    public function getSum($params)
    {
        $user_id = auth()->user()->id;
        $customer = Customer::where("user_id", $user_id)->firstOrFail();
        $voucher_ids = $params["voucher_ids"];
        // collect item_reference_ids
        $cart_ids = @$params["cart_ids"] ?? [];
        $carts = Cart::where("user_id", $user_id)
            ->where(function($query) use ($cart_ids){
                if (count($cart_ids)){
                    $query->whereIn("id", $cart_ids);
                }
            })
            ->get();
        $ids = $this->getValidByItems($carts, $customer->id);

        return Voucher::where('customer_id', (int) @$customer->id)
            ->where('used_at', null)
            ->whereIn('id', $ids)
            ->whereIn('id', $ids)
            ->orderBy('created_at','desc')
            ->get();
    }

    public function getValid($params)
    {
        $user_id = auth()->user()->id;
        $customer = Customer::where("user_id", $user_id)->first();
        $limit = $params["limit"] ?? 10;

        // collect item_reference_ids
        $cart_ids = @$params["cart_ids"] ?? [];
        $carts = Cart::where("user_id", $user_id)
            ->where(function($query) use ($cart_ids){
                if (count($cart_ids)){
                    $query->whereIn("id", $cart_ids);
                }
            })
            ->get();

        $ids = $this->getValidByItems($carts, $customer->id);

        return Voucher::where('customer_id', (int) @$customer->id)
        ->where('used_at', null)
        ->orderBy('created_at','desc')->paginate($limit)
        ->transform(function ($voucher, $key) use ($ids) {
            $voucher->is_valid = in_array($voucher->id, $ids);
            return $voucher;
        });
    }

    public function detail($id)
    {
        $model = Voucher::findOrFail($id);
        return $model;
    }

    public function send($id, $data)
    {
        $model = DB::transaction(function () use ($id, $data) {

            $customer = Customer::where("user_id", $data['customer_id'])->firstOrFail();
            $model = Voucher::findOrFail($id);

            \Log::info("VOUCHER SEND FROM ".$model->customer_id." TO ".$customer->id);

            $model->customer_id = $customer->id;
            $model->save();

            return $model;
        });

        return $model;
    }

    public function phoneCheck($data)
    {
        $model = DB::transaction(function () use ($data) {

            $model = Customer::where('phone', $data['phone'])->first();

            if ($model->user_id == null) {

                throw ValidationException::withMessages([
                    "phone" => "User dari phone number belum terdaftar"
                ]);
            }

            $model = User::findOrfail($model->user_id);

            return $model;
        });

        return $model;
    }

}
