<?php

namespace App\Http\Controllers;

use App\Models\DeptWorkflow;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class DeptWorkflowController extends Controller
{

    // ===================== INDEX ======================
public function index(Request $request)
{
    try {

        $query = DeptWorkflow::query();

        // Filters
        if ($request->filled('Dpt_Id')) {
            $query->where('Dpt_Id', $request->Dpt_Id);
        }

        if ($request->filled('wef_date')) {
            $query->whereDate('Wef_Date', $request->wef_date);
        }

        // Search
        if ($request->filled('search')) {
            $search = $request->search;

            $query->where(function ($q) use ($search) {
                $q->where('Trn_Stage', 'like', "%$search%")
                    ->orWhere('Trn_Method', 'like', "%$search%")
                    ->orWhere('Trn_Tet', 'like', "%$search%")
                    ->orWhere('Dpt_Id', 'like', "%$search%")
                    ->orWhere('Emp_Id', 'like', "%$search%")
                    ->orWhere('Dsg_Id', 'like', "%$search%");
            });
        }

        $perPage = $request->get('per_page', 15);

        $groups = $query->select('Dpt_Id', DB::raw('DATE(Wef_Date) as wef_date_str'))
            ->distinct()
            ->orderBy('Dpt_Id')
            ->orderBy('wef_date_str', 'desc')
            ->paginate($perPage, ['Dpt_Id', 'wef_date_str']);

        $data = $this->groupWorkflowData($groups);

        return response()->json([
            'success' => true,
            'data' => $data,
            'pagination' => [
                'current_page' => $groups->currentPage(),
                'per_page' => $groups->perPage(),
                'total' => $groups->total(),
                'last_page' => $groups->lastPage(),
            ]
        ]);

    } catch (\Exception $e) {

        return response()->json([
            'success' => false,
            'message' => $e->getMessage()
        ], 500);
    }
}


public function all()
{
    try {

        $groups = DeptWorkflow::select('Dpt_Id', DB::raw('DATE(Wef_Date) as wef_date_str'))
            ->distinct()
            ->orderBy('Dpt_Id')
            ->orderBy('wef_date_str', 'desc')
            ->get();

        $data = $this->groupWorkflowData($groups);

        return response()->json([
            'success' => true,
            'data' => $data
        ]);

    } catch (\Exception $e) {

        return response()->json([
            'success' => false,
            'message' => $e->getMessage()
        ], 500);
    }
}


public function departmentWise($dptId)
{
    try {

        $latest = DeptWorkflow::where('Dpt_Id', $dptId)
            ->orderBy('Wef_Date', 'desc')
            ->first();

        if (!$latest) {
            return response()->json([
                'success' => false,
                'message' => 'No data found'
            ], 404);
        }

        $items = DeptWorkflow::where('Dpt_Id', $dptId)
            ->where('Wef_Date', $latest->Wef_Date)
            ->orderBy('Trn_SrNo')
            ->get();

        $data = $this->formatGroup($items);

        return response()->json([
            'success' => true,
            'data' => $data
        ]);

    } catch (\Exception $e) {

        return response()->json([
            'success' => false,
            'message' => $e->getMessage()
        ], 500);
    }
}

    // ===================== STORE ======================
    public function store(Request $request)
    {
        DB::beginTransaction();

        try {

            $validator = Validator::make($request->all(), [
                'Dpt_Id' => 'required|integer|exists:dept_master,Dpt_id',
                'Wef_Date' => 'required|date_format:Y-m-d',
                'stages' => 'required|array|min:1',

                'stages.*.stage_name' => 'required|string',
                'stages.*.designation_id' => 'required|integer|exists:designation_master,Dsg_id',
                'stages.*.Trans_srno' => 'required|integer',
                'stages.*.emp_id' => 'required|integer|exists:employee_master,Emp_Id',
                'stages.*.trn_method' => 'required|string',
                'stages.*.trn_tet' => 'required|string',
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'errors' => $validator->errors()
                ], 422);
            }

            foreach ($request->stages as $stage) {

                DeptWorkflow::create([
                    'Dpt_Id' => $request->Dpt_Id,
                    'Wef_Date' => $request->Wef_Date,
                    'Trn_Stage' => $stage['stage_name'],
                    'Dsg_Id' => $stage['designation_id'],
                    'Trn_SrNo' => $stage['Trans_srno'],
                    'Emp_Id' => $stage['emp_id'],
                    'Trn_Method' => $stage['trn_method'],
                    'Trn_Tet' => $stage['trn_tet'],
                ]);
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Workflow created successfully'
            ]);

        } catch (\Exception $e) {

            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 500);
        }
    }


    // ===================== SHOW ======================
    public function show($id)
    {
        $record = DeptWorkflow::find($id);

        if (!$record) {
            return response()->json([
                'success' => false,
                'message' => 'Record not found'
            ], 404);
        }

        $items = DeptWorkflow::where('Dpt_Id', $record->Dpt_Id)
            ->where('Wef_Date', $record->Wef_Date)
            ->orderBy('Trn_SrNo')
            ->get();

        return response()->json([
            'success' => true,
            'data' => $items
        ]);
    }


    // ===================== UPDATE ======================
    public function update(Request $request, $id)
    {
        $record = DeptWorkflow::find($id);

        if (!$record) {
            return response()->json([
                'success' => false,
                'message' => 'Record not found'
            ], 404);
        }

        DB::beginTransaction();

        try {

            DeptWorkflow::where('Dpt_Id', $record->Dpt_Id)
                ->where('Wef_Date', $record->Wef_Date)
                ->delete();

            foreach ($request->stages as $stage) {

                DeptWorkflow::create([
                    'Dpt_Id' => $request->Dpt_Id,
                    'Wef_Date' => $request->Wef_Date,
                    'Trn_Stage' => $stage['stage_name'],
                    'Dsg_Id' => $stage['designation_id'],
                    'Trn_SrNo' => $stage['Trans_srno'],
                    'Emp_Id' => $stage['emp_id'],
                    'Trn_Method' => $stage['trn_method'],
                    'Trn_Tet' => $stage['trn_tet'],
                ]);
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Workflow updated successfully'
            ]);

        } catch (\Exception $e) {

            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 500);
        }
    }


    // ===================== DELETE ======================
    public function destroy($id)
    {
        $record = DeptWorkflow::find($id);

        if (!$record) {
            return response()->json([
                'success' => false,
                'message' => 'Record not found'
            ], 404);
        }

        DeptWorkflow::where('Dpt_Id', $record->Dpt_Id)
            ->where('Wef_Date', $record->Wef_Date)
            ->delete();

        return response()->json([
            'success' => true,
            'message' => 'Deleted successfully'
        ]);
    }


    private function groupWorkflowData($groups)
{
    $collection = collect();

    foreach ($groups as $group) {

        $items = DeptWorkflow::where('Dpt_Id', $group->Dpt_Id)
            ->whereDate('Wef_Date', $group->wef_date_str)
            ->orderBy('Trn_SrNo')
            ->get();

        $collection = $collection->merge($items);
    }

    return $this->formatGroup($collection);
}


private function formatGroup($items)
{
    $designationIds = $items->pluck('Dsg_Id')->unique()->filter()->values()->toArray();
    $employeeIds = $items->pluck('Emp_Id')->unique()->filter()->values()->toArray();

    $designations = DB::table('designation_master')
        ->whereIn('Dsg_id', $designationIds)
        ->get()
        ->keyBy('Dsg_id');

    $employees = DB::table('employee_master')
        ->whereIn('Emp_Id', $employeeIds)
        ->get()
        ->keyBy('Emp_Id');

    $groupedData = [];

    foreach ($items as $item) {

        $key = $item->Dpt_Id . '|' . $item->Wef_Date->format('Y-m-d');

        if (!isset($groupedData[$key])) {
            $groupedData[$key] = [
                'dwf_id' => $item->DWF_Id,
                'dept_id' => $item->Dpt_Id,
                'wef_date' => $item->Wef_Date,
                'formatted_wef_date' => Carbon::parse($item->Wef_Date)->format('d-m-Y'),
                'stages' => []
            ];
        }

        $groupedData[$key]['stages'][] = [
            'stage_name' => $item->Trn_Stage,
            'designation_id' => $item->Dsg_Id,
            'Trans_srno' => $item->Trn_SrNo,
            'emp_id' => $item->Emp_Id,
            'trn_method' => $item->Trn_Method,
            'trn_tet' => $item->Trn_Tet,
            'designation' => $designations->get($item->Dsg_Id),
            'employee' => $employees->get($item->Emp_Id),
        ];
    }

    return array_values($groupedData);
}

}
