<?php

namespace App\Services\ConstructionDepartment;

use App\Models\Status;
use App\Models\RoadType;
use App\Models\Multifactor;
use Illuminate\Http\Request;
use App\Services\CommonService;
use App\Services\CurlAPiService;
use App\Models\ServiceCredential;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use App\Services\AapaleSarkarLoginCheckService;
use App\Models\ConstructionDepartment\ConstructionRoadCutting;
use App\Models\ConstructionDepartment\ConstructionRoadCuttingRoadDetail;


class RoadCuttingService
{
    protected $curlAPiService;
    protected $aapaleSarkarLoginCheckService;
    protected $commonservice;

    public function __construct(CurlAPiService $curlAPiService, AapaleSarkarLoginCheckService $aapaleSarkarLoginCheckService, CommonService $commonservice)
    {
        $this->curlAPiService = $curlAPiService;
        $this->aapaleSarkarLoginCheckService = $aapaleSarkarLoginCheckService;
        $this->commonservice = $commonservice;
    }

    public function store($request)
    {

        DB::beginTransaction();

        try {

            $user = Auth::user();
            $request['user_id'] = Auth::user()->id;
            $request['service_id'] = "187";

            if ($request->hasFile('upload_prescribed_formats')) {
                $request['upload_prescribed_format'] = $request->upload_prescribed_formats->store('construction-department/road-cutting', 'public');
            }

            if ($request->hasFile('upload_gov_instructed_docs')) {
                $request['upload_gov_instructed_doc'] = $request->upload_gov_instructed_docs->store('construction-department/road-cutting', 'public');
            }

            if ($request->hasFile('upload_related_docs')) {
                $request['upload_related_doc'] = $request->upload_related_docs->store('construction-department/road-cutting', 'public');
            }

            if ($request->hasFile('upload_gps_docs')) {
                $request['upload_gps_doc'] = $request->upload_gps_docs->store('construction-department/road-cutting', 'public');
            }


            $data = $request->except([
                'application_no',
                'roadtype',
                'startpoint',
                'endpoint',
                'road_length',
                'defect_factor'
            ]);
            $constructionRoadCutting = ConstructionRoadCutting::create($data);

            if ($constructionRoadCutting) {
                $applicationNo = 'MBMC/' . $request['service_id'] . '/' . $constructionRoadCutting->id . '/' . date('dmY');
                $constructionRoadCutting->update(['application_no' => $applicationNo]);
            }

            foreach ($request->roadtype as $index => $type) {
                ConstructionRoadCuttingRoadDetail::create([
                    'construction_road_cutting_id' => $constructionRoadCutting->id,
                    'roadtype' => $type,
                    'startpoint' => $request->startpoint[$index],
                    'endpoint' => $request->endpoint[$index],
                    'length' => $request->road_length[$index],
                    'defect_factor' => $request->defect_factor[$index],
                ]);
            }
            $status = Status::create([
                'service_id' => 187,
                'department_id' => 10,
                'table_id' => $constructionRoadCutting->id,
                'user_id' => Auth::user()->id
            ]);

            $this->commonservice->store_approval_hierarchies($constructionRoadCutting, $user, $status);
            $this->calculateGrossTotal($constructionRoadCutting->id);
            DB::commit();
            return response()->json(['success' => 'Record stored successfully']);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

    public function edit($id)
    {
        return ConstructionRoadCutting::find($id);
    }


    public function update($request, $id)
    {
        
        DB::beginTransaction();

        try {
            $constructionRoadCutting = ConstructionRoadCutting::findOrFail($id);

            $multidata = ConstructionRoadCuttingRoadDetail::where('construction_road_cutting_id', $constructionRoadCutting->id)->get();
            $status_id = $constructionRoadCutting->statuses()
                ->where('service_id', $constructionRoadCutting->service_id)
                ->first()?->id;
                
            $groupedData = [];
            $totalri = 0;
            $landrentTotal = 0;
            $totallength = 0;
            $combinedTotalRI = 0;
            $combinedLength = 0;
            $combinedSecurty = 0;
            $totalgrand = 0;
            $cgstamount = 0;
            $sgst = 0;

          

            if ($request->hasFile('upload_prescribed_formats')) {
                if ($constructionRoadCutting->upload_prescribed_format && Storage::exists($constructionRoadCutting->upload_prescribed_format)) {
                    Storage::delete($constructionRoadCutting->upload_prescribed_format);
                }
                $request['upload_prescribed_format'] = $request->upload_prescribed_formats->store('construction-department/road-cutting', 'public');
            }

            if ($request->hasFile('upload_gov_instructed_docs')) {
                if ($constructionRoadCutting->upload_gov_instructed_doc && Storage::exists($constructionRoadCutting->upload_gov_instructed_doc)) {
                    Storage::delete($constructionRoadCutting->upload_gov_instructed_doc);
                }
                $request['upload_gov_instructed_doc'] = $request->upload_gov_instructed_docs->store('construction-department/road-cutting', 'public');
            }



            if ($request->hasFile('upload_related_docs')) {
                if ($constructionRoadCutting->upload_related_doc && Storage::exists($constructionRoadCutting->upload_related_doc)) {
                    Storage::delete($constructionRoadCutting->upload_related_doc);
                }
                $request['upload_related_doc'] = $request->upload_related_docs->store('construction-department/road-cutting', 'public');
            }


            if ($request->hasFile('upload_gps_docs')) {
                if ($constructionRoadCutting->upload_gps_doc && Storage::exists($constructionRoadCutting->upload_gps_doc)) {
                    Storage::delete($constructionRoadCutting->upload_gps_doc);
                }
                $request['upload_gps_doc'] = $request->upload_gps_docs->store('construction-department/road-cutting', 'public');
            }








            if ($request->hasFile('upload_photos')) {
                $request['upload_photo'] = $request->upload_photos->store('construction-department/road-cutting', 'public');
            }




            $totalgrand = $this->calculateGrossTotal($id);
            $user = Auth::user();
            $status = ($user && method_exists($user, 'hasRole') && $user->hasRole('JuniorEngineer')) ? 1 : 0;
            // $constructionRoadCutting->amount = $totalgrand;
            $constructionRoadCutting->save();

            $updateData = $request->except(['roadtype', 'startpoint', 'endpoint', 'road_length', 'defect_factor', 'detail_ids']);
            $updateData['status'] = $status;


            $updateData['is_startdate_enddate'] =
            ($request->filled('start_date') && $request->filled('end_date')) ? 1 : 0;
           //$updateData['amount'] = $totalgrand;

           



            $constructionRoadCutting->update($updateData);
            if ($constructionRoadCutting->wasChanged('ward_area') && $status_id) {
                $resetResponse = $this->commonservice->reset_next_approvers($status_id)->getData(true);

                if (isset($resetResponse['status']) && $resetResponse['status'] === false) {
                    DB::rollBack();
                    return [
                        'status' => false,
                        'message' => $resetResponse['message'] ,
                    ];
                }
            }

            $existingIds = ConstructionRoadCuttingRoadDetail::where('construction_road_cutting_id', $id)->pluck('id')->toArray();
            $formIds = $request->detail_ids ?? [];

            $idsToDelete = array_diff($existingIds, $formIds);
            ConstructionRoadCuttingRoadDetail::whereIn('id',$idsToDelete)->delete();

            foreach ($request->roadtype as $index => $type) {
                $detailId = $formIds[$index] ?? null;

                $detailData = [
                    'construction_road_cutting_id' => $constructionRoadCutting->id,
                    'roadtype' => $type,
                    'startpoint' => $request->startpoint[$index],
                    'endpoint' => $request->endpoint[$index],
                    'length' => $request->road_length[$index],
                    'defect_factor' => $request->defect_factor[$index],
                ];

                if ($detailId && in_array($detailId, $existingIds)) {
                    ConstructionRoadCuttingRoadDetail::where('id', $detailId)->update($detailData);
                } else {
                    ConstructionRoadCuttingRoadDetail::create($detailData);
                }
            }

            DB::commit();

           return [
                'status' => true,
                'message' => 'Road cutting details updated successfully.',
            ];
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Road cutting update failed: ' . $e->getMessage());
            return [
                'status' => false,
                'message' => 'Failed to update road cutting details.',
                'error' => $e->getMessage(),
            ];
        }
    }


    // public static function calculateGrossTotal_old($id)
    // {
    //     $data = ConstructionRoadCutting::findOrFail($id);
    //     $multidata = ConstructionRoadCuttingRoadDetail::where('construction_road_cutting_id', $data->id)->get();
    //     $grossTotal = 0;
    //     foreach ($multidata as $item) {
    //         $roadtype = RoadType::find($item->roadtype);
    //         $multifactor = Multifactor::find($item->defect_factor);

    //         $length = (float) $item->length;
    //         $rate = $roadtype ? (float) $roadtype->rate : 0;
    //         $year = $multifactor ? (float) $multifactor->year : 1;

    //         $riCharge = $length * $rate * $year;
    //         $landrent = $length * 200;

    //         $noofchamber = (int) $data->no_chamber;
    //         $chamberfee = $noofchamber * 30000;
    //         $totalBeforeGst = $riCharge + $landrent + $chamberfee;
    //         $cgst = $totalBeforeGst * 0.09;
    //         $sgst = $totalBeforeGst * 0.09;
    //         $gstTotal = $cgst + $sgst;
    //         $deposit = $riCharge * 0.10;

    //         $grandTotal = $totalBeforeGst + $gstTotal + $deposit;

    //         $grossTotal += $grandTotal;
    //     }
    //     $data->amount = $grossTotal;
    //     $data->save();
    //     return $grossTotal;
    // }


    public static function calculateGrossTotal($id)
{
    $data = ConstructionRoadCutting::findOrFail($id);

    // fetch all items
    $multidata = ConstructionRoadCuttingRoadDetail::where('construction_road_cutting_id', $data->id)->get();

    if ($multidata->isEmpty()) {
        return 0;
    }

    // CHAMBER FEE (only once for entire calculation)
    $noofchamber = (int) $data->no_chamber;
    $chamberfee = $noofchamber * 30000;

    // Group by Road Type (same as Blade)
    $grouped = $multidata->groupBy('roadtype');

    $grossTotal = 0;
    $roadTypeCounter = 0;

    foreach ($grouped as $roadtypeId => $groupItems) {

        $roadTypeCounter++;

        // Chamber fee applies only to FIRST road type
        $effectiveChamberFee = ($roadTypeCounter == 1) ? $chamberfee : 0;

        $itemCounter = 0;

        foreach ($groupItems as $item) {
            $itemCounter++;

            $roadtype = RoadType::find($item->roadtype);
            $multifactor = Multifactor::find($item->defect_factor);

            $length = (float) $item->length;
            $rate = $roadtype ? (float) $roadtype->rate : 0;
            $year = $multifactor ? (float) $multifactor->year : 1;

            $riCharge = $length * $rate * $year;
            $landrent = $length * 200;

            // chamber fee only for the FIRST ITEM of the FIRST ROAD TYPE
            $itemChamberFee = ($itemCounter == 1) ? $effectiveChamberFee : 0;

            // Total before GST
            $totalBeforeGst = $riCharge + $landrent + $itemChamberFee;

            $cgst = $totalBeforeGst * 0.09;
            $sgst = $totalBeforeGst * 0.09;
            $gstTotal = $cgst + $sgst;

            // Security deposit 10% only on RI charges
            $deposit = $riCharge * 0.10;

            // Final Grand Total for this row
            $grandTotal = $totalBeforeGst + $gstTotal + $deposit;

            $grossTotal += $grandTotal;
        }
    }

    // Save
    $data->amount = $grossTotal;
    $data->save();

    return $grossTotal;
}


    

}
