<?php

namespace App\Modules\HR\Core\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Modules\HR\Core\Models\Designation;
use App\Modules\PLATFORM\Settings\Models\Branch;
use App\Modules\HR\Payroll\Models\Addition;
use App\Modules\HR\Payroll\Models\Deduction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Yajra\DataTables\Facades\DataTables;

class DesignationController extends Controller
{
    public function index(Request $request)
    {
        if ($request->ajax()) {
            $query = Designation::with('branch');

            return DataTables::of($query)
                ->addIndexColumn()
                ->addColumn('branch', fn ($row) => $row->branch?->name ?? '-')
                ->editColumn('is_managerial', function ($row) {
                    return $row->is_managerial
                        ? '<span class="badge bg-info">Yes</span>'
                        : '<span class="badge bg-secondary">No</span>';
                })
                ->editColumn('status', function ($row) {
                    return $row->status
                        ? '<span class="badge bg-success">Active</span>'
                        : '<span class="badge bg-danger">Inactive</span>';
                })
                ->addColumn('action', function ($row) {
                    return view('core::designations/partials/actions', compact('row'))->render();
                })
                ->rawColumns(['is_managerial', 'status', 'action'])
                ->make(true);
        }

        return view('core::designations/index');
    }

    public function create()
    {
        return view('core::designations/create', [
            'branches' => Branch::where('status', true)->orderBy('name')->get(),
            'additions' => Addition::where('status', true)->orderBy('sort_order')->orderBy('name')->get(),
            'deductions' => Deduction::where('status', true)->orderBy('sort_order')->orderBy('name')->get(),
        ]);
    }

    public function store(Request $request)
    {
        $request->validate([
            'code'  => 'required|string|max:50',
            'name' => 'required|string|max:150',
            'level' => 'required|integer|min:1',
            'budget' => 'required|integer|min:1',
            'carder' => 'nullable',
            'branch_id' => 'nullable|exists:branches,id',
            'additions' => 'nullable|array',
            'additions.*' => 'exists:additions,id',
            'deductions' => 'nullable|array',
            'deductions.*' => 'exists:deductions,id',
        ], [
            'code.required'       => 'The designation code field is required.',
            'code.max'            => 'The designation code must not exceed 50 characters.',
            'name.required'      => 'The name field is required.',
            'name.max'           => 'The name must not exceed 150 characters.',
            'level.required'      => 'The level field is required.',
            'level.integer'       => 'The level must be an integer.',
            'level.min'           => 'The level must be at least 1.',
            'budget.required'      => 'The budget field is required.',
            'budget.integer'       => 'The budget must be an integer.',
            'budget.min'           => 'The budget must be at least 1.',
            'branch_id.exists'    => 'The selected branch is invalid.',
            'additions.*.exists'  => 'One or more selected additions are invalid.',
            'deductions.*.exists' => 'One or more selected deductions are invalid.',
        ]);

        $designation = Designation::create([
            'branch_id'     => $request->branch_id,
            'code'          => $request->code,
            'name'         => $request->name,
            'level'         => $request->level,
            'carder'  => $request->carder,
            'budget'         => $request->budget,
            'is_managerial' => $request->boolean('is_managerial'),
            'status'        => $request->boolean('status'),
        ]);

        // Sync additions and deductions
        if ($request->has('additions')) {
            $designation->additions()->sync($request->additions);
        }
        if ($request->has('deductions')) {
            $designation->deductions()->sync($request->deductions);
        }

        return response()->json([
            'status'  => true,
            'message' => 'Designation created successfully',
        ]);
    }

    public function edit(Designation $designation)
    {
        $designation->load(['additions', 'deductions']);

        return view('core::designations/edit', [
            'designation' => $designation,
            'branches'    => Branch::where('status', true)->orderBy('name')->get(),
            'additions' => Addition::where('status', true)->orderBy('sort_order')->orderBy('name')->get(),
            'deductions' => Deduction::where('status', true)->orderBy('sort_order')->orderBy('name')->get(),
        ]);
    }

    public function update(Request $request, Designation $designation)
    {
        $request->validate([
            'code'  => 'required|string|max:50',
            'name' => 'required|string|max:150',
            'level' => 'required|integer|min:1',
            'budget' => 'required|integer|min:1',
            'carder' => 'nullable',
            'branch_id' => 'nullable|exists:branches,id',
            'additions' => 'nullable|array',
            'additions.*' => 'exists:additions,id',
            'deductions' => 'nullable|array',
            'deductions.*' => 'exists:deductions,id',
        ], [
            'code.required'       => 'The designation code field is required.',
            'code.max'            => 'The designation code must not exceed 50 characters.',
            'name.required'      => 'The name field is required.',
            'name.max'           => 'The name must not exceed 150 characters.',
            'level.required'      => 'The level field is required.',
            'level.integer'       => 'The level must be an integer.',
            'level.min'           => 'The level must be at least 1.',
            'budget.required'      => 'The budget field is required.',
            'budget.integer'       => 'The budget must be an integer.',
            'budget.min'           => 'The budget must be at least 1.',
            'branch_id.exists'    => 'The selected branch is invalid.',
            'additions.*.exists'  => 'One or more selected additions are invalid.',
            'deductions.*.exists' => 'One or more selected deductions are invalid.',
        ]);

        $designation->update([
            'branch_id'     => $request->branch_id,
            'code'          => $request->code,
            'name'          => $request->name,
            'level'         => $request->level,
            'carder'  => $request->carder,
            'budget'        => $request->budget,
            'is_managerial' => $request->boolean('is_managerial'),
            'status'        => $request->boolean('status'),
        ]);

        // Sync additions and deductions
        $designation->additions()->sync($request->additions ?? []);
        $designation->deductions()->sync($request->deductions ?? []);

        return response()->json([
            'status'  => true,
            'message' => 'Designation updated successfully',
        ]);
    }

    public function destroy(Designation $designation)
    {
        // Check if designation is used in employees table
        $employeeCount = DB::table('employees')
            ->where('designation_id', $designation->id)
            ->count();

        if ($employeeCount > 0) {
            return response()->json([
                'status'  => false,
                'message' => 'Cannot delete this designation because it is being used by ' . $employeeCount . ' employee(s).',
            ], 422);
        }

        // Check if designation has additions
        $additionsCount = DB::table('designation_additions')
            ->where('designation_id', $designation->id)
            ->count();

        if ($additionsCount > 0) {
            return response()->json([
                'status'  => false,
                'message' => 'Cannot delete this designation because it has ' . $additionsCount . ' addition(s) attached.',
            ], 422);
        }

        // Check if designation has deductions
        $deductionsCount = DB::table('designation_deductions')
            ->where('designation_id', $designation->id)
            ->count();

        if ($deductionsCount > 0) {
            return response()->json([
                'status'  => false,
                'message' => 'Cannot delete this designation because it has ' . $deductionsCount . ' deduction(s) attached.',
            ], 422);
        }

        $designation->delete();

        return response()->json([
            'status'  => true,
            'message' => 'Designation deleted successfully',
        ]);
    }

    public function status(Designation $designation)
    {
        $designation->update([
            'status' => ! $designation->status,
        ]);

        return response()->json([
            'status'  => true,
            'message' => 'Status updated successfully',
        ]);
    }

    /**
     * Get payroll details (additions and deductions) for a designation
     * Used for auto-populating employee form when designation is selected
     */
    public function getPayrollDetails(Designation $designation)
    {
        $designation->load(['additions', 'deductions']);

        return response()->json([
            'additions' => $designation->additions->map(function ($addition) {
                return [
                    'id' => $addition->id,
                    'name' => $addition->name,
                    'code' => $addition->code,
                    'calculation_type' => strtolower($addition->calculation_type),
                    'amount' => $addition->fixed_amount ?? 0,
                ];
            }),
            'deductions' => $designation->deductions->map(function ($deduction) {
                return [
                    'id' => $deduction->id,
                    'name' => $deduction->name,
                    'code' => $deduction->code,
                    'calculation_type' => strtolower($deduction->calculation_type),
                    'amount' => $deduction->fixed_amount ?? 0,
                ];
            }),
        ]);
    }
}
