<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use App\Models\Promocode;
use Auth;
use Illuminate\Validation\Rule;

class OrganiserPromocodeController extends Controller
{
    protected $promocode;
    protected $organizer_id;

    public function __construct()
    {
        $this->middleware('common');
        $this->middleware(['organiser'])->except(['promocodes']);
        $this->promocode = new Promocode();
        $this->organizer_id = null;
    }

    /**
     * Display the Create/Edit Promocode form.
     *
     * @return \Illuminate\View\View
     */
    public function index()
    {
        $organizer_id = Auth::id();
        return view('promocode.form', compact('organizer_id'));
    }

    /**
     * Retrieve all promocodes for the logged-in organizer.
     *
     * @param  Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function promocodes(Request $request)
    {
        $this->is_admin($request);

        $params = ['organizer_id' => $this->organizer_id];
        $promocodes = $this->promocode->get_promocodes($params);

        return empty($promocodes)
            ? response()->json(['status' => false])
            : response()->json(['status' => true, 'promocodes' => $promocodes]);
    }

    /**
     * Create or update a promocode.
     *
     * @param  Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function store(Request $request)
    {
        $organizer_id = Auth::id();
        $this->is_admin($request);

        // Assuming that 'store_id' is the id of the promocode being updated.
        $promocodeId = $request->promocode_id;
        
        // Validate input, ensuring the 'code' field is unique, but ignoring the current record's id
        $request->validate([
            'code' => [
                'required',
                'max:512',
                Rule::unique('promocodes', 'code')
                    ->ignore($promocodeId) // Ignore the current promocode's id
                    ->where(function ($query) use ($organizer_id) {
                        return $query->where('organizer_id', $organizer_id);
                    }),
            ],
            'reward' => 'required|numeric|min:0',
            'quantity' => 'required|integer|min:1',
            'p_type' => 'required|in:fixed,percent',
            // 'is_disposable' => 'nullable|boolean',
            'expires_at' => 'required|date|after:today',
            'status' => 'required|boolean',
        ]);

        $params = [
            'code' => $request->code,
            'reward' => $request->reward,
            'quantity' => $request->quantity,
            'p_type' => $request->p_type,
            'organizer_id' => $this->organizer_id,
            // 'is_disposable' => $request->is_disposable,
            'expires_at' => Carbon::parse($request->expires_at),
            'status' => $request->status,
        ];

        // Use updateOrCreate to update the record if it exists, or create a new one
        $store = Promocode::updateOrCreate(
            [
                'organizer_id' => $params['organizer_id'],
                'id' => $promocodeId, // Ensure you're checking with the correct id
            ],
            $params
        );

        return response()->json(['status' => true, 'store' => $store]);
    }


    /**
     * Delete a specific promocode.
     *
     * @param  Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function delete_promocode(Request $request)
    {
        $this->is_admin($request);

        $request->validate([
            'promocode_id' => 'required|numeric|exists:promocodes,id',
        ]);

        $promocode = $this->promocode->where('id', $request->promocode_id)
            ->where('organizer_id', $this->organizer_id)
            ->first();

        if (!$promocode) {
            return response()->json(['status' => false, 'message' => 'Promocode not found.'], 404);
        }

        $promocode->delete();

        return response()->json(['status' => true, 'message' => 'Promocode deleted successfully.']);
    }

    /**
     * Search for promocodes by code or other attributes.
     *
     * @param  Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function search_promocodes(Request $request)
    {
        $this->is_admin($request);

        if (!empty($request->search)) {
            $request->validate([
                'search' => 'max:255',
            ]);
        }

        $params = [
            'organizer_id' => $this->organizer_id,
            'search' => $request->search,
        ];

        $promocodes = $this->promocode->search_promocodes($params);

        return $promocodes->isEmpty()
            ? response()->json(['status' => false, 'promocodes' => []])
            : response()->json(['status' => true, 'promocodes' => $promocodes]);
    }

    /**
     * Check if the authenticated user is an admin, and adjust the organizer_id accordingly.
     *
     * @param  Request  $request
     * @return void
     */
    protected function is_admin(Request $request)
    {
        $this->organizer_id = Auth::id();

        if (Auth::user()->hasRole('admin')) {
            $request->validate([
                'organizer_id' => 'required|numeric|min:1',
            ]);
            $this->organizer_id = $request->organizer_id;
        }
    }

    /**
     * Fetch promocodes by organizer_id.
     *
     * @param  Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getPromocodesByOrganizer(Request $request)
    {
        $request->validate([
            'organizer_id' => 'required|numeric',
        ]);

        $promocodes = $this->promocode->where('organizer_id', $request->organizer_id)->get();
        
        return $promocodes->isEmpty()
            ? response()->json(['status' => false, 'message' => 'No promocodes found'])
            : response()->json(['status' => true, 'promocodes' => $promocodes]);
    }

     /**
     * Fetch promocodes by organizer_id.
     *
     * @param  Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getPromocodesOrganizer(Request $request)
    {
        $organizer_id = Auth::id();

        $promocodes = $this->promocode
        ->where('organizer_id', $organizer_id)
        ->orWhereNull('organizer_id')
        ->get();

        foreach($promocodes as $key => $value)
        {
            $promocodes[$key]['currency'] = setting('regional.currency_default');
        }


        return $promocodes->isEmpty()
            ? response()->json(['status' => false, 'message' => 'No promocodes found'])
            : response()->json(['status' => true, 'promocodes' => $promocodes]);
    }

}
