<?php

namespace App\Http\Controllers;

use App\Models\Company;
use App\Models\Coa;
use App\Models\Department;
use App\Models\Journal;
use App\Models\RnDGeneralJournal;
use App\Models\RnDGeneralJournalDetail;
use App\Models\DeleteLog;
use App\Models\Periode;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Auth;
use DB;
use Carbon\Carbon;

class RnDGeneralJournalController extends Controller
{
    public function index($dateStart,$dateEnd)
    {
        $rndgeneralJournals = RnDGeneralJournal::whereBetween('document_date',[$dateStart,$dateEnd])
        ->whereIn('department_id',$this->getDepartment())->get();
        $periods = Periode::all();
        foreach($rndgeneralJournals as $gj){
            $gj->closed =  Module::checkPeriodeBack($periods,$gj->document_date);
        }
        return response()->json(["rndgeneralJournals" => $rndgeneralJournals,"role" => $this->getRole()]);
    }

    public function store(Request $request)
    {
        $request->validate([
            'document_date' => 'required|date',
            'department_id' => 'required|exists:department,id',
            'notes' => 'nullable|string',
            'details' => 'required|array|min:1',
            'details.*.coa_id' => 'required|exists:coa,id',
            'details.*.nominal_debet' => 'nullable|numeric|min:0',
            'details.*.nominal_credit' => 'nullable|numeric|min:0',
            'details.*.notes' => 'nullable|string',
        ]);

        DB::beginTransaction();
        try {
            $company = Company::select('companyCode')->first();
            $department = Department::findOrFail($request->department_id);
            $date = Carbon::parse($request->document_date);
            $nobukti = Module::generateDocumentNumber($company->companyCode, $department->department_code, $date->month, $date->year, "GJNR", 1);
            $totalDebet = 0;$totalCredit = 0;

            $gj = RnDGeneralJournal::create([
                "rnd_general_journal_number" => $nobukti,
                'document_date' => $request->document_date,
                'department_id' => $request->department_id,
                'note' => $request->notes,
                'company_code' => $company->companyCode,
                'created_by' => Auth::user()->id,
                'updated_by' => Auth::user()->id,
            ]);

            $ctr=1;
            foreach ($request->details as $detail) {
                $totalDebet += $detail["nominal_debet"] ?? 0;
                $totalCredit += $detail["nominal_credit"] ?? 0;

                $gj->details()->create([
                    'general_journal_id' => $gj->id,
                    'coa_id' => $detail['coa_id'],
                    'nominal_debet' => $detail['nominal_debet'] ?? 0,
                    'nominal_credit' => $detail['nominal_credit'] ?? 0,
                    'note' => $detail['notes'],
                    'row_number' => $ctr,
                    'company_code' => $company->companyCode,
                    'department_id' => $request->department_id,
                    'created_by' => Auth::user()->id,
                    'updated_by' => Auth::user()->id,
                ]);

                Journal::create([
                    "document_number" => $gj->rnd_general_journal_number,
                    "document_date" => $request->document_date,
                    "account_number" => $detail['coa_id'],
                    "notes" => $detail['notes'],
                    'debet_nominal' => $detail['nominal_debet'] ?? 0,
                    'credit_nominal' => $detail['nominal_credit'] ?? 0,
                    'debet_nominal_base' => $detail['nominal_debet'] ?? 0,
                    'credit_nominal_base' => $detail['nominal_credit'] ?? 0,
                    'company_code' => $company->companyCode,
                    'department_id' => $request->department_id,
                    'created_by' => Auth::user()->id,
                    'updated_by' => Auth::user()->id,
                ]);
                $ctr++;
            }

            $gj->nominal_debet = $totalDebet;
            $gj->nominal_credit = $totalCredit;
            $gj->save();

            DB::commit();
            return response()->json(null, 201);
        } catch (\Exception $e) {
            DB::rollback();
            Log::error('Error creating rnd general journal', ['error' => $e->getMessage(), 'data' => $request->all(), 'user' => Auth::user()->name ?? 'system']);
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

    public function show($id, Request $request)
    {
        try {
            $rndgeneralJournal = RnDGeneralJournal::with('details','department')->findOrFail($id);
            return response()->json($rndgeneralJournal);
        } catch (\Exception $e) {
            Log::error('Error fetching RnD General Journal', ['id' => $id, 'error' => $e->getMessage(), 'user' => Auth::user()->name ?? 'system']);
            return response()->json(['error' => 'RnD General Journal not found'], 404);
        }
    }

    public function update(Request $request, $id)
    {
        $request->validate([
            'document_date' => 'required|date',
            'department_id' => 'required|exists:department,id',
            'notes' => 'nullable|string',
            'details' => 'required|array|min:1',
            'details.*.coa_id' => 'required|exists:coa,id',
            'details.*.nominal_debet' => 'nullable|numeric|min:0',
            'details.*.nominal_credit' => 'nullable|numeric|min:0',
            'details.*.notes' => 'nullable|string',
        ]);

        DB::beginTransaction();
        try {
            $gj = RnDGeneralJournal::findOrFail($id);
            $gj->note = $request->notes;
            $gj->updated_by = Auth::user()->id;
            $gj->save();

            $ctr=1;
            $gj->details()->delete();
            Journal::where("document_number",$gj->rnd_general_journal_number)->delete();
            $totalDebet = 0;$totalCredit = 0;
            foreach ($request->details as $detail) {
                $totalDebet += $detail["nominal_debet"] ?? 0;
                $totalCredit += $detail["nominal_credit"] ?? 0;

                $gj->details()->create([
                    'general_journal_id' => $gj->id,
                    'coa_id' => $detail['coa_id'],
                    'nominal_debet' => $detail['nominal_debet'] ?? 0,
                    'nominal_credit' => $detail['nominal_credit'] ?? 0,
                    'note' => $detail['notes'],
                    'row_number' => $ctr,
                    'company_code' => $gj->company_code,
                    'department_id' => $gj->department_id,
                    'created_by' => $gj->created_by,
                    'updated_by' => Auth::user()->id,
                ]);

                Journal::create([
                    "document_number" => $gj->rnd_general_journal_number,
                    "document_date" => $gj->document_date,
                    "account_number" => $detail['coa_id'],
                    "notes" => $detail['notes'],
                    'debet_nominal' => $detail['nominal_debet'] ?? 0,
                    'credit_nominal' => $detail['nominal_credit'] ?? 0,
                    'debet_nominal_base' => $detail['nominal_debet'] ?? 0,
                    'credit_nominal_base' => $detail['nominal_credit'] ?? 0,
                    'company_code' => $gj->company_code,
                    'department_id' => $gj->department_id,
                    'created_by' => $gj->created_by,
                    'updated_by' => Auth::user()->id,
                ]);
                $ctr++;
            }

            $gj->nominal_debet = $totalDebet;
            $gj->nominal_credit = $totalCredit;
            $gj->save();
            DB::commit();
            return response()->json(null, 201);
        } catch (\Exception $e) {
            DB::rollback();
            Log::error('Error update rnd general journal', ['error' => $e->getMessage(), 'data' => $request->all(), 'user' => Auth::user()->name ?? 'system']);
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

    public function destroy($id, Request $request)
    {
        DB::beginTransaction();
        try {
            $gj = RnDGeneralJournal::findOrFail($id);
            Journal::where("document_number",$gj->rnd_general_journal_number)->delete();

            DeleteLog::create([
                'document_number' => $gj->rnd_general_journal_number,
                'document_date' => $gj->document_date,
                'delete_notes' => $request->delete_notes ?? 'No notes provided',
                'company_code' => null,
                'department_code' => $gj->department_id,
                'deleted_by' => Auth::check() ? Auth::user()->name : 'system',
                'type' => 'RnD General Journal',
            ]);

            $gj->details()->delete();
            $gj->delete();

            DB::commit();
            return response()->json(null, 204);
        } catch (\Exception $e) {
            DB::rollback();
            Log::error('Error deleting rnd general journal', ['id' => $id, 'error' => $e->getMessage(), 'user' => Auth::user()->name ?? 'system']);
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

    public function getMasterData()
    {
        try {
            $Listdepartment = $this->getDepartment();
            $user = Auth::user();
            $company = Company::first();
            $departments = Department::whereIn("id",$Listdepartment)->get();
            $date = Carbon::now();
            $nobukti = Module::generateDocumentNumber($company->companyCode, $departments->first()->department_code, $date->month, $date->year, "GJNR", 0);

            return response()->json([
                'departments' => $departments,
                'coas' => Coa::with('coaType')
                // whereHas('coaType', function ($query) {
                //     $query->where('account_sub_type', '!=', 'PM');
                // })
                ->orderBy('account_number','asc')
                ->get(),
                'nobukti' => $nobukti,
                'role' => $this->getRole(),
            ], 200);
        } catch (\Exception $e) {
            \Log::error('Master Data Error', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'user_id' => Auth::id()
            ]);
            return response()->json(['error' => 'Failed to load master data'], 500);
        }
    }

    public function getNomorBukti(Request $request)
    {
        $request->validate([
            'department_id' => 'required|exists:department,id',
            'document_date' => 'required|date',
        ]);

        try {
            $company = Company::select('companyCode')->first();
            $department = Department::findOrFail($request->department_id);
            $date = Carbon::parse($request->document_date);
            $nobukti = Module::generateDocumentNumber($company->companyCode, $department->department_code, $date->month, $date->year, "GJNR", 0);
            return response()->json($nobukti);
        } catch (\Exception $e) {
            Log::error('Error generating document number', ['error' => $e->getMessage(), 'data' => $request->all(), 'user' => Auth::user()->name ?? 'system']);
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

    public function print(Request $request){
        $rndgeneralJournal = RnDGeneralJournal::with(['details.coa'])->where("id",$request->id)->firstOrFail();
        $imagePath = storage_path('app/images/logo-only.png');
        $imageData = file_get_contents($imagePath);$doNumber = "";$doDate = "";
        
        $username = Auth::user()->name;
        if($request->mode == 1){
            $pdf = \PDF::loadView('print.general_journal_rnd_a4_pdf', compact('rndgeneralJournal','imageData','username'))->setPaper('A4');
        }else{
            $pdf = \PDF::loadView('print.general_journal_rnd_pdf', compact('rndgeneralJournal','imageData','username'))->setPaper('A5', 'landscape');
        }
        
        return ["data" => "data:application/pdf;base64,".base64_encode($pdf->stream()),"role" => $this->getRole()];
    }

    public function increasePrintNumber($id){
        $do = RnDGeneralJournal::find($id);
        $do->print_number = ($do->print_number ?? 0) + 1;
        $do->save();
        return response()->json(null);
    }
}
