<?php

namespace App\Http\Controllers;

use App\Services\PaymentService;
use Illuminate\Http\Request;
use App\Models\Province;
use App\Models\City;
use App\Models\Damage;
use App\Models\Accident;
use App\Models\DailyAccidentSettings;
use Illuminate\Support\Facades\Storage;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Arr;
use App\Facades\Sms\Sms;
use App\Services\NominatimService;


class ReceiptController extends Controller
{
    public function view(Request $request)
    {
        if (! auth()->user()->hasAnyPermission(['show-receipt', 'show-receipt-province'])) {
            abort(403);
        }

        return view('version2.dashboard_pages.receipt.list');
    }

    public function getDamages()
    {
        return response()->json(Damage::where('status', 1)->get(), 200);
    }

    public function show(Request $request)
    {
        if (! auth()->user()->hasAnyPermission(['show-receipt', 'show-receipt-province'])) {
            abort(403);
        }

        $fields = ['id', 'province_fa','city_fa', 'axis_name', 'accident_type_fa', 'accident_date', 'id', 'damage_picture1', 'damage_picture2', 'plaque', 'created_at', 'sum', 'deposit_date', 'status','police_file_date','deposit_insurance_image','deposit_daghi_image','deposit_insurance_amount','deposit_daghi_amount','status_fa','final_amount','province_id','accident_time','accident_type','city_id','driver_name','driver_national_code','driver_phone_number','police_file','lat','lng','police_serial','report_base'];

        $aliases = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '','','','','','','','','','','','','','','','','',''];

        $selectRaw = makeSelectQuery($fields, $aliases);

        if (auth()->user()->hasPermissionTo('show-receipt')) {
            $query = Accident::with('damages')->selectRaw($selectRaw);
        } else {
            if (is_null(auth()->user()->province_id)) {
                return response()->json([
                    'message' => 'استانی برای شما در سامانه ثبت نشده است!'
                ], 400);
            }

            $query = Accident::with('damages')->where('province_id', auth()->user()->province_id)
                                 ->selectRaw($selectRaw);
        }

        $accidents_list = processDataTable($request, '', $fields, $query);

        if (Auth::check()) {
            auth()->user()->addActivityComplete(1122);
        }

        return response()->json(
            $accidents_list,
            200
        );
    }

    public function store(Request $request, NominatimService $nominatimService)
    {
        DB::transaction(function () use ($request, $nominatimService) {
            $new_accident = new Accident();


            $new_accident->province_fa = Province::where('id', $request->province_id)->first()->name_fa;
            $new_accident->province_id = $request->province_id;

            $new_accident->city_fa = City::where('id', $request->city_id)->first()->name_fa;
            $new_accident->city_id = $request->city_id;

            $new_accident->axis_name = $request->axis_name;
            $new_accident->driver_name = $request->driver_name;
            $new_accident->plaque = $request->plaque;
            $new_accident->driver_national_code = $request->national_code;
            $new_accident->driver_phone_number = $request->phone_number;

            $new_accident->user_id = auth()->user()->id;

            $new_accident->lat = $request->lat;
            $new_accident->lng = $request->lng;

            $new_accident->accident_type = $request->accident_type;
            $new_accident->accident_type_fa = DailyAccidentSettings::where('type', 'accident_type')->where('name', $request->accident_type)->first()->value;
            $new_accident->accident_date = $request->accident_date;
            $new_accident->accident_time = $request->accident_time;

            // $new_accident->way_id = get_way_id_from_nominatim($request->lat, $request->lng);
            $new_accident->way_id = $nominatimService->get_way_id_from_nominatim($request->lat, $request->lng);

            $new_accident->save();

            if ($request->report_base) {
                $new_accident->report_base = 1;
            } else {
                $new_accident->police_file = $request->file('police_file')->storeAs('receipts_files/'.$new_accident->id, 'police_file_'.$new_accident->id.'_'.time().'.'.$request->file('police_file')->extension(), 'public');
                $new_accident->police_serial = $request->police_serial;
                $new_accident->police_file_date = $request->police_file_date;
                $new_accident->report_base = 0;
            }

            $new_accident->save();

            if ($request->has('damage_picture1')) {
                $new_accident->damage_picture1 = $request->file('damage_picture1')->storeAs('receipts_files/'.$new_accident->id, 'damage_picture1_'.$new_accident->id.'_'.time().'.'.$request->file('damage_picture1')->extension(), 'public');
            }

            if ($request->has('damage_picture2')) {
                $new_accident->damage_picture2 = $request->file('damage_picture2')->storeAs('receipts_files/'.$new_accident->id, 'damage_picture2_'.$new_accident->id.'_'.time().'.'.$request->file('damage_picture2')->extension(), 'public');
            }

            $new_accident->save();
            $sum = 0;
            foreach (json_decode($request->items_damge) as $key => $item) {
                $damage = Damage::find($item->id);
                $new_accident->damages()->attach($item->id, [
                    'value' => $item->value,
                    'unit' => $damage->unit,
                    'amount' => $item->amount,
                ]);
                $sum += $item->amount;
            }

            $ojrate_nasb = $sum/100*20;
            $new_accident->ojrate_nasb = $ojrate_nasb;

            $sum += $ojrate_nasb;
            $new_accident->sum = $sum;
            $new_accident->withoutAction();
            $new_accident->save();
            $msg = "درخواست شما بابت پرداخت خسارت وارده به ابنیه فنی و تاسیسات راه با کد یکتا ".$new_accident->id." ثبت شد.\n".verta()->now()->format('Y/m/d H:i') ;
            Sms::sendSms($request->phone_number, $msg);
            auth()->user()->addActivityComplete(1123);
        });
    }

    public function details(Accident $accident)
    {
        return response()->json(
            $accident->load('damages')->toArray(),
            200
        );
    }

    public function update(Accident $accident, Request $request, NominatimService $nominatimService)
    {
        DB::transaction(function () use ($request, $accident, $nominatimService) {
            $accident->province_fa = Province::where('id', $request->province_id)->first()->name_fa;
            $accident->province_id = $request->province_id;

            $accident->city_fa = City::where('id', $request->city_id)->first()->name_fa;
            $accident->city_id = $request->city_id;

            $accident->axis_name = $request->axis_name;
            $accident->driver_name = $request->driver_name;
            $accident->plaque = $request->plaque;
            $accident->driver_national_code = $request->national_code;
            $accident->driver_phone_number = $request->phone_number;

            $accident->lat = $request->lat;
            $accident->lng = $request->lng;

            $accident->accident_type = $request->accident_type;
            $accident->accident_type_fa = DailyAccidentSettings::where('type', 'accident_type')->where('name', $request->accident_type)->first()->value;
            $accident->accident_date = $request->accident_date;
            $accident->accident_time = $request->accident_time;

            $accident->way_id = $nominatimService->get_way_id_from_nominatim($request->lat, $request->lng);

            $accident->save();

            if ($request->report_base) {
                \File::delete('storage/'.$accident->police_file);
                $accident->police_file = null;
                $accident->police_serial = null;
                $accident->report_base = 1;
            } else {
                if ($accident->report_base) {
                    if ($request->has('police_file')) {
                        \File::delete('storage/'.$accident->police_file);
                        $accident->police_file = $request->file('police_file')->storeAs('receipts_files/'.$accident->id, 'police_file_'.$accident->id.'_'.time().'.'.$request->file('police_file')->extension(), 'public');
                    } else {
                        abort(401, 'please send the file');
                    }
                } else {
                    if ($request->has('police_file')) {
                        \File::delete('storage/'.$accident->police_file);
                        $accident->police_file = $request->file('police_file')->storeAs('receipts_files/'.$accident->id, 'police_file_'.$accident->id.'_'.time().'.'.$request->file('police_file')->extension(), 'public');
                    }
                }

                $accident->police_file_date = $request->police_file_date;
                $accident->police_serial = $request->police_serial;
                $accident->report_base = 0;
            }

            $accident->save();

            if ($request->has('damage_picture1')) {
                \File::delete('storage/'.$accident->damage_picture1);
                $accident->damage_picture1 = $request->file('damage_picture1')->storeAs('receipts_files/'.$accident->id, 'damage_picture1_'.$accident->id.'_'.time().'.'.$request->file('damage_picture1')->extension(), 'public');
            } elseif ($request->has('damage_picture1_is_delete')) {
                \File::delete('storage/'.$accident->damage_picture1);
                $accident->damage_picture1 = null;
            }

            if ($request->has('damage_picture2')) {
                \File::delete('storage/'.$accident->damage_picture2);
                $accident->damage_picture2 = $request->file('damage_picture2')->storeAs('receipts_files/'.$accident->id, 'damage_picture2_'.$accident->id.'_'.time().'.'.$request->file('damage_picture2')->extension(), 'public');
            } elseif ($request->has('damage_picture2_is_delete')) {
                \File::delete('storage/'.$accident->damage_picture2);
                $accident->damage_picture2 = null;
            }

            $accident->save();
            $sum = 0;
            $accident->damages()->detach();
            foreach (json_decode($request->items_damge) as $key => $item) {
                $damage = Damage::find($item->id);
                $accident->damages()->attach($item->id, [
                    'value' => $item->value,
                    'unit' => $damage->unit,
                    'amount' => $item->amount,
                ]);
                $sum += $item->amount;
            }

            
            $ojrate_nasb = $sum/100*20;
            $accident->ojrate_nasb = $ojrate_nasb;

            $sum += $ojrate_nasb;
            $accident->sum = $sum;

            $accident->save();

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

    public function delete(Accident $accident)
    {
        \File::delete('storage/receipts_files/'.$accident->id);

        $accident->damages()->detach();
        $accident->delete();
        auth()->user()->addActivityComplete(1125);

        return response()->json([
            'message' => 'item is deleted.'
        ]);
    }

    public function getAccidentDamages(Accident $accident)
    {
        return response()->json(
            $accident->damages,
            200
        );
    }

    public function sendToInsurance(Request $request, Accident $accident)
    {
        DB::transaction(function () use ($request, $accident) {
            $accident->sendToInsurance();
            $accident->save();

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

        $account_data = Province::where('id', $accident->province_id)->first();

        return view('receipt.insurance_letter', [
            'account_data' => $account_data,
            'data' => $accident->load('damages')->toArray(),
        ]);
    }

    // public function receiveInsuranceBill(Request $request, Accident $accident)
    // {

    //     DB::transaction(function () use ($request, $accident) {
    //         $accident->deposit_insurance_image = $request->file('deposit_insurance_image')->storeAs('receipts_files/'.$accident->id, 'deposit_insurance_image_'.$accident->id.'_'.time().'.'.$request->file('deposit_insurance_image')->extension(), 'public');

    //         $accident->deposit_insurance_amount = $request->deposit_insurance_amount;

    //         $accident->receiveInsuranceBill();
    //         $accident->save();

    //         auth()->user()->addActivityComplete(1126);
    //     });

    //     $account_data = Province::where('id', $accident->province_id)->first();

    //     return view('receipt.insurance_letter', [
    //         'account_data' => $account_data,
    //         'data' => $accident->load('damages')->toArray(),
    //     ]);
    // }

    public function uploadPaymentInfo(Request $request, Accident $accident)
    {
        $request->validate([
            'deposit_insurance_image' => 'file',
            'deposit_insurance_amount' => 'required_with:deposit_insurance_image',

            'deposit_daghi_image' => 'file',
            'deposit_daghi_amount' => 'required_with:deposit_daghi_image',
        ]);

        DB::transaction(function () use ($request, $accident) {
            if ($request->has('deposit_insurance_status')) {
                if ($request->has('deposit_insurance_image')) {
                    $accident->deposit_insurance_image = $request->file('deposit_insurance_image')->storeAs('receipts_files/'.$accident->id, 'deposit_insurance_image_'.$accident->id.'_'.time().'.'.$request->file('deposit_insurance_image')->extension(), 'public');
                }

                $accident->deposit_insurance_amount = $request->deposit_insurance_amount;
            } else {
                $accident->deposit_insurance_image = null;
                $accident->deposit_insurance_amount = null;
            }

            if ($request->has('deposit_daghi_status')) {
                if ($request->has('deposit_daghi_image')) {
                    $accident->deposit_daghi_image = $request->file('deposit_daghi_image')->storeAs('receipts_files/'.$accident->id, 'deposit_daghi_image_'.$accident->id.'_'.time().'.'.$request->file('deposit_daghi_image')->extension(), 'public');
                }

                $accident->deposit_daghi_amount = $request->deposit_daghi_amount;
            } else {
                $accident->deposit_daghi_image = null;
                $accident->deposit_daghi_amount = null;
            }

            $accident->receiveInsuranceAndDaqiBill();

            $accident->save();

            auth()->user()->addActivityComplete(1132);
            return response()->json([], 200);
        });
    }

    public function invoiceBill(Request $request, Accident $accident, PaymentService $paymentService)
    {
        try {
            DB::transaction(function () use ($request, $accident, $paymentService) {
                
                $final_amount = $accident->sum - ($accident->deposit_insurance_amount + $accident->deposit_daghi_amount);

                if ($final_amount < 0) {
                    return response()->json([], 422);
                }

                $accident->final_amount = $final_amount;

                $accident->bill_code = $paymentService->invoiceBillApi($accident->driver_national_code, $final_amount);

                $accident->invoiceBill();

                $accident->save();

                $msg = "فاکتور با شناسه پرداخت \n" . explode("/", $accident->bill_code)[0]. "\n در سامانه سازمان راهداری ثبت شد. برای پرداخت از لینک زیر اقدام نمایید.\n\n".env("PAYMENT_LINK")."/#/pay/".explode("/", $accident->bill_code)[0]."/$final_amount";

                Sms::sendSms($accident->driver_phone_number, $msg);

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

            return response()->json($accident, 200);
        } catch (\Throwable $th) {
            return response()->json([
                'message' => $th->getMessage(),
            ], 500);
        }
    }

    public function sendSmsAgain(Request $request, Accident $accident)
    {
        $msg = "فاکتور با شناسه پرداخت \n" . explode("/", $accident->bill_code)[0]. "\n در سامانه سازمان راهداری ثبت شد. برای پرداخت از لینک زیر اقدام نمایید.\n\n".env("PAYMENT_LINK")."/#/pay/".explode("/", $accident->bill_code)[0]."/$accident->final_amount";

        Sms::sendSms($accident->driver_phone_number, $msg);
        
        return $msg;
    }

    public function callPaymentStatus(Request $request, Accident $accident, PaymentService $paymentService)
    {
        try {
            DB::transaction(function () use ($request, $accident, $paymentService) {
                if ($accident->final_amount > 0) {

                    $response = json_decode($paymentService->callPaymentStatusBillApi(explode("/", $accident->bill_code)[0]));

                    if ($response->isPayed) {
                        $accident->payBill();
                        $accident->save();
                    } 
                }else{
                    $accident->payBill();
                    $accident->save();
                    
                }

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

            return response()->json($accident, 200);
        } catch (\Throwable $th) {
            return response()->json([
                'message' => $th->getMessage(),
            ], 500);
        }
    }

    public function documentRelease(Request $request, Accident $accident)
    {
        DB::transaction(function () use ($request, $accident) {
            $accident->documentRelease();
            $accident->save();

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


        return view('receipt.release_document', [
            'data' => $accident->toArray(),
        ]);
    }

    public function invoiceBillApi($driver_national_code, $final_amount)
    {
        try {
            $post = array(
                'username' => env("PAYMENT_USERNAME"),
                'password' => env("PAYMENT_PASSWORD"),
                'amount'   => $final_amount,
                'serial'   => "12345",
                'type'   => 1,
                'instanceid'   => 123,
                'ownerid'   => $driver_national_code,
                'calculationBox'   =>  "{\"rows\":[{\"amount\":". $final_amount .",\"code\":\"7070021060000015\"}]}"
            );

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, "http://payment.rmto.ir/acc/rest/payid/gen");
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
            $response = curl_exec($ch);
            curl_close($ch);
            return $response;
        } catch (\Throwable $th) {
            abort(500);
        }
    }

    public function callPaymentStatusBillApi($bill_code)
    {
        try {
            $post = array(
                // 'username' => env("PAYMENT_USERNAME"),
                // 'password' => env("PAYMENT_PASSWORD"),
                // 'amount'   => $final_amount,
                // 'serial'   => "12345",
                // 'type'   => 1,
                // 'instanceid'   => 123,
                // 'ownerid'   => $driver_national_code,
                // 'calculationBox'   =>  "{\"rows\":[{\"amount\":". $final_amount .",\"code\":\"7070021060000015\"}]}"
            );

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, "http://payment.rmto.ir/acc/rest/payid/track2/".env("PAYMENT_USERNAME")."/".env("PAYMENT_PASSWORD")."/".$bill_code);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            // curl_setopt($ch, CURLOPT_POST, true);
            // curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
            $response = curl_exec($ch);
            curl_close($ch);

            return $response;
        } catch (\Throwable $th) {
            abort(500);
        }
    }
}
