<?php

namespace App\Http\Controllers\V3\Dashboard;

use App\Enums\AxisTypes;
use App\Exports\V3\SafetyAndPrivacy\CartableReport;
use App\Facades\File\FileFacade;
use App\Http\Controllers\Controller;
use App\Http\Requests\V3\SafetyAndPrivacy\FirstStepStoreRequest;
use App\Http\Requests\V3\SafetyAndPrivacy\SecondStepStoreRequest;
use App\Http\Requests\V3\SafetyAndPrivacy\ThirdStepStoreRequest;
use App\Http\Requests\V3\SafetyAndPrivacy\UpdateRequest;
use App\Http\Traits\ApiResponse;
use App\Models\InfoItem;
use App\Models\SafetyAndPrivacy;
use App\Services\Cartables\SafetyAndPrivacyTableService;
use App\Services\NominatimService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class SafetyAndPrivacyController extends Controller
{
    use ApiResponse;

    public function index(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): JsonResponse
    {
        return response()->json($safetyAndPrivacyTableService->datatable($request));
    }

    public function excelReport(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): BinaryFileResponse
    {
        $name = 'گزارش از نگهداری حریم راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx';
        $data = $safetyAndPrivacyTableService->datatable($request);
        return Excel::download(new CartableReport($data['data']), $name);
    }

    public function firstStepStore(FirstStepStoreRequest $request, NominatimService $nominatimService): JsonResponse
    {
        $user = auth()->user();

        if ($user->edarate_ostani_id || is_null($user->city_id)) {
            return $this->errorResponse('امکان ثبت این مورد برای ادارات استانی و ستادی وجود ندارد!');
        }

        if (is_null($user->edarate_shahri_id)) {
            return $this->errorResponse('اداره شهری برای شما در سامانه ثبت نشده است!');
        }

        $coordinates = explode(',', $request->point);
        $item = InfoItem::query()
            ->where('id', $request->info_id)
            ->where('item', 17)
            ->firstOrFail();

        DB::transaction(function () use ($request, $coordinates, $item, $nominatimService, $user)
        {
            $safety_and_privacy = SafetyAndPrivacy::query()->create([
                'lat' => $coordinates[0],
                'lon' => $coordinates[1],
                'operator_id' => $user->id,
                'operator_name' => $user->name,
                'province_id' => $user->province_id,
                'province_fa' => $user->province_fa,
                'info_id' => $item->id,
                'info_fa' => $item->sub_item_str,
                'city_id' => $user->city_id,
                'city_fa' => $user->city_fa,
                'activity_date_time' => $request->activity_date." ".$request->activity_time,
                'edare_shahri_id' => $user->edarate_shahri_id,
                'edare_shahri_name' => $user->edarate_shahri_name,
                'way_id' => $nominatimService->get_way_id_from_nominatim($coordinates[0], $coordinates[1]),
                'axis_type_id' => $request->axis_type_id,
                'axis_type_name' => AxisTypes::name($request->axis_type_id),
                'step' => 1,
                'step_fa' => 'گام اول (شناسایی)'
            ]);

            $safety_and_privacy->recognize_picture = $request->has('recognize_picture') ?
                FileFacade::save($request->recognize_picture, "safety_and_privacy/{$safety_and_privacy->id}") :
                null;
            $safety_and_privacy->save();

            $user->addActivityComplete(1134);
        });

        return $this->successResponse();
    }

    public function secondStepStore(SafetyAndPrivacy $safetyAndPrivacy, SecondStepStoreRequest $request): JsonResponse
    {
        $user = auth()->user();

        if ($user->edarate_ostani_id || is_null($user->city_id)) {
            return $this->errorResponse('امکان ثبت این مورد برای ادارات استانی و ستادی وجود ندارد!');
        }

        if (is_null($user->edarate_shahri_id)) {
            return $this->errorResponse('اداره شهری برای شما در سامانه ثبت نشده است!');
        }

        DB::transaction(function () use ($request, $safetyAndPrivacy, $user)
        {
            $judiciary_document = [];
            foreach ($request->judiciary_document as $index => $file) {
                $judiciary_document[] = FileFacade::save($file, "safety_and_privacy/{$safetyAndPrivacy->id}/judiciary_document");
            }
            $safetyAndPrivacy->update([
                'judiciary_document' => serialize($judiciary_document),
                'judiciary_document_upload_date' => now(),
                'step' => 2,
                'step_fa' => 'گام دوم (مستندات قضایی)'
            ]);

            $user->addActivityComplete(1135);
        });

        return $this->successResponse();
    }

    public function thirdStepStore(SafetyAndPrivacy $safetyAndPrivacy, ThirdStepStoreRequest $request): JsonResponse
    {
        $user = auth()->user();

        if ($user->edarate_ostani_id || is_null($user->city_id)) {
            return $this->errorResponse('امکان ثبت این مورد برای ادارات استانی و ستادی وجود ندارد!');
        }

        if (is_null($user->edarate_shahri_id)) {
            return $this->errorResponse('اداره شهری برای شما در سامانه ثبت نشده است!');
        }

        DB::transaction(function () use ($request, $safetyAndPrivacy, $user) {
            $safetyAndPrivacy->update([
                'step' => 3,
                'step_fa' => 'گام سوم (برخورد)',
                'action_picture' => FileFacade::save($request->action_picture, "safety_and_privacy/{$safetyAndPrivacy->id}/action_picture"),
                'action_picture_document_upload_date' => now(),
            ]);

            $user->addActivityComplete(1136);
        });

        return $this->successResponse();
    }

    public function update(SafetyAndPrivacy $safetyAndPrivacy, UpdateRequest $request): JsonResponse
    {
        DB::transaction(function () use ($request, $safetyAndPrivacy) {
            $safetyAndPrivacy->update([
                'axis_type_id' => $request->axis_type_id,
                'axis_type_name' => AxisTypes::name($request->axis_type_id),
            ]);

            auth()->user()->addActivityComplete(1168);
        });

        return $this->successResponse();
    }

    public function show(SafetyAndPrivacy $safetyAndPrivacy): JsonResponse
    {
        return $this->successResponse($safetyAndPrivacy);
    }

    public function destroy(SafetyAndPrivacy $safetyAndPrivacy): JsonResponse
    {
        Storage::deleteDirectory("public/safety_and_privacy/{$safetyAndPrivacy->id}");

        DB::transaction(function () use ($safetyAndPrivacy)
        {
            auth()->user()->addActivityComplete(1155);
            $safetyAndPrivacy->delete();
        });

        return $this->successResponse();
    }

    public function deserialize(SafetyAndPrivacy $safetyAndPrivacy): JsonResponse
    {
        $judiciaries = $safetyAndPrivacy->judiciary_document ? unserialize($safetyAndPrivacy->judiciary_document) : [];

        $result = [];

        foreach ($judiciaries as $judiciary) {
            $result[] = Storage::disk('public')->url($judiciary);
        }

        return $this->successResponse($result);
    }

    public function subItems(): JsonResponse
    {
        return $this->successResponse(InfoItem::query()
            ->where('item', '=', 17)
            ->select('id', 'item', 'item_str', 'sub_item_str as name', 'sub_item_unit as unit', 'needs_image', 'needs_end_point', 'sub_item')
            ->get());
    }
}
