<?php

namespace App\Http\Controllers\V3\Dashboard;
use App\Exports\V3\RoadObservation\ComplaintsReport;
use App\Exports\V3\RoadObservation\OperatorCartableReport;
use App\Exports\V3\RoadObservation\SupervisorCartableReport;
use App\Facades\File\FileFacade;
use App\Facades\Sms\Sms;
use App\Http\Controllers\Controller;
use App\Http\Requests\V3\RoadObservation\ModifyRegisterationRequest;
use App\Http\Requests\V3\RoadObservation\ReferRequest;
use App\Http\Requests\V3\RoadObservation\RegisterRequest;
use App\Http\Requests\V3\RoadObservation\RestoreRequest;
use App\Http\Requests\V3\RoadObservation\VerifyBySupervisorRequest;
use App\Http\Traits\ApiResponse;
use App\Models\EdarateShahri;
use App\Models\Province;
use App\Models\RoadObservationHistory;
use App\Models\RoadObserved;
use App\Models\User;
use App\Services\NikarayanService;
use Carbon\Carbon;
use Hekmatinasser\Verta\Verta;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Services\Cartables\RoadObservationTableService;
use Maatwebsite\Excel\Facades\Excel;
use SoapFault;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class RoadObservationController extends Controller
{
    use ApiResponse;

    public function supervisorIndex(Request $request,RoadObservationTableService $roadObservationTableService ): JsonResponse
    {
        return response()->json($roadObservationTableService->supervisorCartableIndex($request));
    }

    public function verifyBySupervisor(VerifyBySupervisorRequest $request, RoadObserved $roadObserved): JsonResponse
    {
        $statusFa = $request->verify == 1 ? 'تایید شده' : 'عدم تایید';

        $roadObserved->update([
                'status' => $request->verify,
                'status_fa' => $statusFa,
                'supervisor_id' => auth()->user()->id,
                'supervisor_name' => auth()->user()->name,
                'supervisor_description' => $request->description,
                'supervising_time' => now(),
            ]);

        auth()->user()->addActivityComplete(1138);

        return $this->successResponse();
    }

    public  function supervisorCartableReport(Request $request, RoadObservationTableService $roadObservationTableService): BinaryFileResponse
    {
        $name = 'گزارش از کارتابل ارزیابی واکنش سریع '. verta()->now()->format('Y-m-d H:i') . '.xlsx';
        $data = $roadObservationTableService->supervisorCartableIndex($request);

        return Excel::download(new SupervisorCartableReport($data['data']), $name);
    }

    public function operatorIndex(Request $request, RoadObservationTableService $roadObservationTableService): JsonResponse
    {
        return response()->json($roadObservationTableService->operatorCartableIndex($request));
    }

    public function operatorCartableReport(Request $request, RoadObservationTableService $roadObservationTableService): BinaryFileResponse
    {
        $name = 'گزارش از کارتابل عملیات واکنش سریع ' . verta()->now()->format('Y-m-d H:i') . '.xlsx';
        $data = $roadObservationTableService->operatorCartableIndex($request);
        return Excel::download(new OperatorCartableReport($data['data']), $name);
    }

    public function complaintsIndex(Request $request, RoadObservationTableService $roadObservationTableService): JsonResponse
    {
        return response()->json($roadObservationTableService->complaintsIndex($request));
    }

    public function complaintsReport(Request $request, RoadObservationTableService $roadObservationTableService): BinaryFileResponse
    {
        $name = 'گزارش از رسیدگی به شکایات واکنش سریع ' . verta()->now()->format('Y-m-d H:i') . '.xlsx';
        $data = $roadObservationTableService->complaintsIndex($request);
        return Excel::download(new ComplaintsReport($data['data']), $name);
    }

    public function show(RoadObserved $roadObserved): JsonResponse
    {
        return $this->successResponse($roadObserved->only(['rms_status', 'rms_description', 'image_before', 'image_after', 'rms_start_latlng']));
    }

    public function register(RegisterRequest $request, RoadObserved $roadObserved, NikarayanService $nikarayanService): JsonResponse
    {
        $roadObservedData = [
            'status' => 0,
            'status_fa' => 'در حال بررسی',
            'rms_status' => $request->rms_status ?? $roadObserved->rms_status,
            'rms_description' => $request->rms_description ?? $roadObserved->rms_description,
        ];

        $roadObservedHistoryData = [
            'user_id' => auth()->user()->id,
            'previous_rms_status' => $roadObserved->rms_status,
            'previous_rms_start_latlng' => $roadObserved->rms_start_latlng,
            'previous_rms_end_latlng' => $roadObserved->rms_end_latlng,
            'previous_rms_description' => $roadObserved->rms_description,
            'new_files' => json_encode([])
        ];

        if ($request->rms_status == 1) {

            $files_path = [];

            $roadObserved->files()->where('path', 'like', '%_image_before%')->delete();
            $roadObserved->files()->where('path', 'like', '%_image_after%')->delete();

            $image_before = FileFacade::save($request->image_before, "road_observeds/{$roadObserved->id}/");
            $image_after = FileFacade::save($request->image_after, "road_observeds/{$roadObserved->id}/");

            $files_path[0]['path'] = $image_before;
            $files_path[1]['path'] = $image_after;

            $files = json_encode($files_path);
            $now_date_time = Carbon::now();

            $roadObservedData['image_after'] = $image_after;
            $roadObservedData['image_before'] = $image_before;
            $roadObservedData['rms_start_latlng'] = explode(',', $request->start_point);
            $roadObservedData['updated_at_fa'] = Verta::instance($now_date_time);
            $roadObservedData['rms_last_activity_fa'] = Verta::instance($now_date_time);
            $roadObservedData['rms_last_activity'] = $now_date_time;
            $roadObservedHistoryData['new_files'] = $files;
        }

        $roadObserved->problemHistories()->create($roadObservedHistoryData);
        $roadObserved->update($roadObservedData);

        auth()->user()->addActivityComplete(1142);

        try {
            $nikarayanService->updateRoadObservedInfoByNikarayan($request, $roadObserved, json_encode($roadObservedHistoryData['new_files']));
        }
        catch (SoapFault $e) {

            $msg = "error in send to nikarayan at" . date("Y-m-d H:i:s") . "\n";
            $msg .= $e->getMessage();
            Sms::sendSms(env('RMS_CTO_PHONE_NUMBER'), $msg);
        }

        return $this->successResponse();
    }

    public function modifyRegistration(ModifyRegisterationRequest $request, RoadObserved $roadObserved, NikarayanService $nikarayanService): JsonResponse
    {
        $roadObservedData = [
            'status' => 0,
            'status_fa' => 'در حال بررسی',
            'rms_status' => $request->rms_status ?? $roadObserved->rms_status,
            'rms_description' => $request->rms_description ?? $roadObserved->rms_description,
        ];

        $roadObservedHistoryData = [
            'user_id' => auth()->user()->id,
            'previous_rms_status' => $roadObserved->rms_status,
            'previous_rms_start_latlng' => $roadObserved->rms_start_latlng,
            'previous_rms_end_latlng' => $roadObserved->rms_end_latlng,
            'previous_rms_description' => $roadObserved->rms_description,
            'new_files' => json_encode([])
        ];

        if ($request->rms_status == 1) {

            $files_path = [];

            $roadObserved->files()->where('path', 'like', '%_image_before%')->delete();
            $roadObserved->files()->where('path', 'like', '%_image_after%')->delete();

            if ($request->has('image_before')) {
                if ($roadObserved->image_before) {
                    FileFacade::delete($roadObserved->image_before, true);
                }
                $image_before = FileFacade::save($request->image_before, "road_observeds/{$roadObserved->id}/");
                $roadObservedData['image_before'] = $image_before;
                $files_path[0]['path'] = $image_before;
            }

            if ($request->has('image_after')) {
                if ($roadObserved->image_after) {
                    FileFacade::delete($roadObserved->image_after, true);
                }
                $image_after = FileFacade::save($request->image_after, "road_observeds/{$roadObserved->id}/");
                $roadObservedData['image_after'] = $image_after;
                $files_path[1]['path'] = $image_after;
            }

            $files = json_encode($files_path);
            $now_date_time = Carbon::now();

            $roadObservedData['rms_start_latlng'] = explode(',', $request->start_point);
            $roadObservedData['updated_at_fa'] = Verta::instance($now_date_time);
            $roadObservedData['rms_last_activity_fa'] = Verta::instance($now_date_time);
            $roadObservedData['rms_last_activity'] = $now_date_time;
            $roadObservedHistoryData['new_files'] = $files;
        }

        $roadObserved->problemHistories()->create($roadObservedHistoryData);
        $roadObserved->update($roadObservedData);

        auth()->user()->addActivityComplete(1142);

        try {
            $nikarayanService->updateRoadObservedInfoByNikarayan($request, $roadObserved, json_encode($roadObservedHistoryData['new_files']));
        }
        catch (SoapFault $e) {

            $msg = "error in send to nikarayan at" . date("Y-m-d H:i:s") . "\n";
            $msg .= $e->getMessage();
            Sms::sendSms(env('RMS_CTO_PHONE_NUMBER'), $msg);
        }

        return $this->successResponse();
    }

    public function refer(ReferRequest $request, RoadObserved $roadObserved): JsonResponse
    {
        $province = Province::query()->find($request->province_id);

        RoadObservationHistory::query()->create([
            'id' => $roadObserved->id,
            'user_id' => auth()->user()->id,
            'action' => 'refer',
            'description' => $request->refer_description,
            'from_edareh' => $roadObserved->edarate_shahri_id,
            'to_edareh' => $request->edarate_shahri_id,
            'from_province' => $roadObserved->province_id,
            'to_province' => $province->id
        ]);

        $roadObserved->update([
            'edarate_shahri_id' => $request->edarate_shahri_id,
            'province_id' => $province->id,
            'province_fa' => $province->name_fa,
        ]);

        auth()->user()->addActivityComplete(1037);

        return $this->successResponse();
    }

    public function referList(RoadObserved $roadObserved): JsonResponse
    {
        $data = RoadObservationHistory::query()
            ->where('id', '=', $roadObserved->id)
            ->where('action', '=', 'refer')
            ->orderBy('created_at', 'desc')
            ->get([
                'created_at', 'description', 'from_edareh', 'to_edareh',
                'from_province', 'to_province', 'user_id'
            ]);

        foreach ($data as $key => $value) {
            $data[$key]->from_edareh = EdarateShahri::query()->find($value->from_edareh)->name_fa ?? null;
            $data[$key]->to_edareh = EdarateShahri::query()->find($value->to_edareh)->name_fa ?? null;
            $data[$key]->from_province = Province::query()->find($value->from_province)->name_fa ?? null;
            $data[$key]->to_province = Province::query()->find($value->to_province)->name_fa ?? null;
            $user = User::query()->find($value->user_id);
            $data[$key]->user = $user->first_name . ' ' . $user->last_name;
        }
        return $this->successResponse($data);
    }

    public function restore(RestoreRequest $request, RoadObserved $roadObserved): JsonResponse
    {
        if ($roadObserved->image_before) {
            FileFacade::delete($roadObserved->image_before);
        }

        if ($roadObserved->image_after) {
            FileFacade::delete($roadObserved->image_after);
        }

        $roadObserved->update([
            'image_before' => null,
            'image_after' => null,
            'rms_last_activity' => null,
            'rms_last_activity_fa' => null,
            'updated_at_fa' => null,
            'updated_at' => null,
            'rms_status' => 0,
            'status' => null,
            'status_fa' => null,
        ]);

        RoadObservationHistory::query()->create([
            'id' => $roadObserved->id,
            'user_id' => auth()->user()->id,
            'action' => 'restore',
            'description' => $request->restore_description,
        ]);

        auth()->user()->addActivityComplete(1141);

        return $this->successResponse();
    }
}
