<?php

namespace App\Http\Controllers\Admin;

use App\CPU\Helpers;
use App\Http\Controllers\Controller;
use App\Models\Counter;
use App\Models\Order;
use Brian2694\Toastr\Facades\Toastr;
use Illuminate\Http\Request;
use Rap2hpoutre\FastExcel\FastExcel;
use function App\CPU\translate;

class CounterController extends Controller
{
    public function __construct(
        private Counter $counter,
        private Order   $order
    )
    {
    }

    public function index(Request $request)
    {
        $queryParam = [];
        if ($request->has('search')) {
            $key = explode(' ', $request['search']);
            $counters = $this->counter->where(function ($q) use ($key) {
                foreach ($key as $value) {
                    $q->where('name', 'like', "%{$value}%")
                        ->orWhere('number', 'like', "%{$value}%");
                }
            });
            $queryParam = ['search' => $request['search']];
        } else {
            $counters = $this->counter;
        }
        $counters = $counters->latest()->paginate(Helpers::pagination_limit())->appends($queryParam);
        return view('admin-views.counter.index', compact('counters', 'queryParam'));
    }

    public function details(Request $request, $id)
    {
        $counter = $this->counter
            ->withCount('orders')
            ->withSum('orders', 'order_amount')
            ->withSum('orders', 'total_tax')
            ->findOrFail($id);
        $startDateTime = \Carbon\Carbon::parse($request->start_date)->startOfDay();
        $endDateTime = \Carbon\Carbon::parse($request->end_date)->endOfDay();

        $orders = $this->order
            ->with(['customer', 'account'])
            ->where('counter_id', $request->id)
            ->when($request->filled('search'), function ($query) use ($request) {
                $search = $request->input('search');
                $query->where(function ($q) use ($search) {
                    $q->where('id', 'like', "%{$search}%")
                        ->orWhereHas('customer', function ($q) use ($search) {
                            $q->where('name', 'like', "%{$search}%")
                                ->orWhere('mobile', 'like', "%{$search}%");
                        });
                });
            })
            ->when($request->filled('start_date') && $request->filled('end_date'), function ($query) use ($request) {
                $startDate = date('Y-m-d 00:00:00', strtotime($request->input('start_date')));
                $endDate = date('Y-m-d 23:59:59', strtotime($request->input('end_date')));
                $query->whereBetween('created_at', [$startDate, $endDate]);
            })
            ->orderBy('id', 'desc')
            ->paginate(Helpers::pagination_limit())->appends($request->all());

        return view('admin-views.counter.details', compact('counter', 'orders', 'startDateTime', 'endDateTime'));
    }

    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required|max:255|unique:counters,name,NULL,id,number,' . $request->number,
            'number' => 'required|unique:counters,number,NULL,id,name,' . $request->name,
            'description' => 'required|max:255',
        ]);

        $counter = $this->counter;
        $counter->name = $request->input('name');
        $counter->number = $request->input('number');
        $counter->description = $request->input('description');
        $counter->save();

        Toastr::success(translate('Counter added successfully'));
        return back();
    }

    public function edit($id)
    {
        $counter = $this->counter->findOrFail($id);
        return view('admin-views.counter.edit', compact('counter'));
    }

    public function update(Request $request, $id)
    {
        $request->validate([
            'name' => 'required|max:255|unique:counters,name,' . $id . ',id,number,' . $request->number,
            'number' => 'required|unique:counters,number,' . $id . ',id,name,' . $request->name,
            'description' => 'required|max:255',
        ]);

        $counter = $this->counter->findOrFail($id);
        $counter->name = $request->input('name');
        $counter->number = $request->input('number');
        $counter->description = $request->input('description');
        $counter->save();

        Toastr::success(translate('Counter updated successfully'));
        return redirect()->route('admin.counter.index');
    }

    public function delete($id)
    {
        $counter = $this->counter->findOrFail($id);
        $counter->delete();

        Toastr::success(translate('Counter deleted successfully'));
        return back();
    }

    public function changeStatus($id, $status)
    {
        $counter = $this->counter->findOrFail($id);
        $counter->status = $status;
        $counter->save();

        Toastr::success(translate('Counter status updated successfully'));
        return back();
    }

    public function export(Request $request)
    {
        $counter = $this->counter->findOrFail($request->id);
        $orders = $this->order
            ->with(['customer', 'account'])
            ->where('counter_id', $request->id)
            ->when($request->filled('search'), function ($query) use ($request) {
                $key = explode(' ', $request->input('search'));

                // Apply search filter on related customers
                $query->whereHas('customer', function ($q) use ($key) {
                    foreach ($key as $value) {
                        $q->where('name', 'like', "%{$value}%")
                            ->orWhere('mobile', 'like', "%{$value}%");
                    }
                });
            })
            ->when($request->filled('start_date') && $request->filled('end_date'), function ($query) use ($request) {
                $startDate = date('Y-m-d 00:00:00', strtotime($request->input('start_date')));
                $endDate = date('Y-m-d 23:59:59', strtotime($request->input('end_date')));
                $query->whereBetween('created_at', [$startDate, $endDate]);
            })
            ->orderBy('id', 'desc')
            ->get();
        $fileName = $counter->name . '-' . $counter->number . '-' . date('Y-m-d') . '.xlsx';
        $data = $orders->map(function ($order) {
            return [
                'Order ID' => $order->id,
                'Order Date' => date('d M Y', strtotime($order->created_at)),
                'Customer Info' => $order?->customer?->name . ' - ' . $order?->customer?->mobile,
                'Total Amount' => \App\CPU\Helpers::currency_symbol() . ' ' . number_format($order->order_amount + $order->total_tax - $order->coupon_discount_amount - ($order->extra_discount ?? 0), 2),
                'Paid By' => $order->payment_id = 0 ? \App\CPU\translate('Customer balance') : ($order->account ? $order->account->account : \App\CPU\translate('account_deleted')),
            ];
        });
        return (new FastExcel($data))->download($fileName);
    }
}
