<?php

namespace App\Http\Controllers;

use A7kz\Platform\Models\UniModel;
use A7kz\Platform\Modules\Platform\Segment\Facades\Segment;
use App\Modules\applications\Enum\ApplicationStatus;
use App\Modules\auto\Enums\AutoStatusEnums;
use Carbon\CarbonPeriod;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Storage;
use Mpdf\Tag\Mark;
use function PHPUnit\Framework\isEmpty;

class MobileApiController extends Controller
{
    public function getMarks(): JsonResponse {
        $data = [];
        $marks = UniModel::model('pipi_brand_models')->get();
        if (!isset($marks)) {
            return response()->json();
        }
        foreach ($marks as $mark) {
            $brand = UniModel::model('pipi_auto_brands')->find($mark->brand_id);
            $tariffs = UniModel::model('pipi_auto_tariffs')->where('model_id', $mark->id)->get();
            $equipment = UniModel::model('pipi_auto_equipment')->where('id', $mark->equipment_id)->first();
            if ($mark->name != 'Ввод остатков') {
                foreach ($tariffs as $tariff) {
                    $tariffs_new[$tariff?->day_range_start . '-' . $tariff->day_range_end] = [
                        'name' => $tariff?->name,
                        'price' => $tariff?->base_rate,
                        'min' => $tariff?->day_range_start,
                        'max' => $tariff?->day_range_end,
                    ];
                }
                $data[$mark->name . '-' . $mark->year] = [
                    'id'            => $mark->id,
                    'brand'         => $brand->name,
                    'mark'          => $mark->name,
                    'year'          => $mark->year,
                    'configuration' => $equipment?->name,
                    'tariffs'       => $tariffs_new
                ];
            }
        }
        return response()->json($data);
    }

    public function sendApplication(Request $request): JsonResponse {
        $data = $request->all();
        $data['started_at'] = Carbon::parse($data['started_at'])?->format('Y-m-d H:i:s');
        $data['ended_at'] = Carbon::parse($data['ended_at'])?->format('Y-m-d H:i:s');
        $authToken = null;
        $data['car_id'] = null;
        if ($request->header('Authorization')) {
            $user = auth()->guard('api')->user();
            $data['user_id'] = $user ? $user->id : null;
        } else {
            $user = UniModel::model('core_users')
                ->where('email', $data['email'])
                ->first();

            if ($user) {
                $data['user_id'] = $user->id;
                $tokenResult = $user->createToken('auth_token');
                $authToken = $tokenResult->accessToken;
            } else {
                $data['user_id'] = null;
            }

        }

        $response = [
            'status' => 'OK',
            'message' => 'Заявка создана',
        ];

        if ($authToken) {
            $car = $this->getAvailableCar($data['started_at'], $data['ended_at'], $data['mark_id']);
            if (isEmpty($car)) {
                return response()->json('Нет свободных машин');
            }
            $period = CarbonPeriod::create($data['started_at'], $data['ended_at']);

            $dates = array_map(fn($date) => $date->toDateString(), iterator_to_array($period));

            foreach ($dates as $date) {
                UniModel::model('pipi_auto_calendar')->create([
                    'auto_id' => $car->id,
                    'date' => $date,
                    'status' => AutoStatusEnums::Rent->name
                ]);
            }
            $response['auth_token'] = $authToken;
            $response['message'] = 'Заявка создана, и вы были автоматически авторизованы';
        } elseif (!isset($data['user_id'])) {
            $response['message'] = 'Заявка создана, с вами свяжется наш оператор';
        }

        UniModel::model('pipi_applications')->create([
            'rent_day'      => $data['rent_day'],
            'started_at'    => $data['started_at'],
            'ended_at'      => $data['ended_at'],
            'user_id'       => $data['user_id'],
            'phone'         => $data['phone'],
            'car_id'        => $data['car_id'],
            'user_name'     => $data['name'] ?? null,
            'user_surname'  => $data['surname'] ?? null,
            'user_email'    => $data['email'] ?? null,
            'status'        => ApplicationStatus::pending->value
        ]);

        return response()->json($response);
    }

    public function getApplications(): JsonResponse
    {
        return response()->json(UniModel::model('pipi_applications')->get());
    }

    public function login(Request $request)
    {
        $credentials = $request->only('email', 'password');

        if (auth()->attempt($credentials)) {
            $user = auth()->user();
            $tokenResult = $user->createToken('auth_token');

            $response = [
                'access_token' => $tokenResult->plainTextToken,
                'token_type' => 'Bearer',
                'user' => [
                    'id' => $user->id,
                    'name' => $user->name,
                    'email' => $user->email,
                ],
            ];

            return response()->json($response, 200);
        } else {
            return response()->json(['error' => 'Unauthorized'], 401);
        }
    }

    public function checkAvailableCar($started_at = null, $ended_at = null, $modelId = null): bool {
        if (!$started_at || !$ended_at || !$modelId) {
            $request = request();
            $started_at = $started_at ?? $request->input('started_at');
            $ended_at = $ended_at ?? $request->input('ended_at');
            $modelId = $modelId ?? $request->input('model_id');
        }

        if (!$started_at || !$ended_at || !$modelId) {
            return false;
        }

        $started_at = Carbon::parse($started_at)->format('Y-m-d');
        $ended_at = Carbon::parse($ended_at)->format('Y-m-d');
        $cars = UniModel::model('pipi_auto')->where('model_id', $modelId)->get();
        $busyCars = UniModel::model('pipi_auto_calendar')
            ->whereBetween('date', [$started_at, $ended_at])
            ->pluck('auto_id')
            ->toArray();

        $availableCars = $cars->reject(fn($car) => in_array($car->id, $busyCars));

        return $availableCars->isNotEmpty();
    }



    public function getAvailableMarksList(Request $request): JsonResponse
    {
        $started_at = $request->query('started_at');
        $ended_at = $request->query('ended_at');

        $marks = UniModel::model('pipi_brand_models')->get();
        $availableMarks = [];

        foreach ($marks as $mark) {
            if ($mark->name === 'Ввод остатков') {
                continue;
            }

            if (!$this->checkAvailableCar($started_at, $ended_at, $mark->id)) {
                continue;
            }

            $brand = UniModel::model('pipi_auto_brands')->find($mark->brand_id);
            $tariffs = UniModel::model('pipi_auto_tariffs')->where('model_id', $mark->id)->get();
            $equipment = UniModel::model('pipi_auto_equipment')->where('id', $mark->equipment_id)->first();

            $tariffs_new = [];
            foreach ($tariffs as $tariff) {
                $tariffs_new[$tariff?->day_range_start . '-' . $tariff->day_range_end] = [
                    'name'  => $tariff?->name,
                    'price' => $tariff?->base_rate,
                    'min'   => $tariff?->day_range_start,
                    'max'   => $tariff?->day_range_end,
                ];
            }

            $availableMarks[$mark->name . '-' . $mark->year] = [
                'id'            => $mark->id,
                'brand'         => $brand->name ?? null,
                'mark'          => $mark->name,
                'year'          => $mark->year,
                'configuration' => $equipment?->name,
                'tariffs'       => $tariffs_new,
            ];
        }

        return response()->json($availableMarks);
    }

    public function getAvailableCar($started_at, $ended_at, $modelId)
    {
        $started_at = Carbon::parse($started_at)->format('Y-m-d');
        $ended_at = Carbon::parse($ended_at)->format('Y-m-d');
        $cars = UniModel::model('pipi_auto')->where('model_id', $modelId)->get();
        $busyCars = UniModel::model('pipi_auto_calendar')
            ->whereBetween('date', [$started_at, $ended_at])
            ->pluck('auto_id')
            ->toArray();

        $availableCars = $cars->reject(fn($car) => in_array($car->id, $busyCars));

        if ($availableCars->isNotEmpty()) {
            return $availableCars->first();
        } else {
            return (object) [];
        }
    }
}
