<?php

namespace Modules\MedAccounting\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Modules\MedAccounting\Entities\MedaccCostCenter;
use Yajra\DataTables\Facades\DataTables;

/**
 * Cost-centre CRUD (SIFA P7-T2). Business-scoped; guarded by
 * medacc.costcenters.manage. A cost centre may bind to an existing ClinicCore
 * department or ERP location via ref_id (offered fail-soft when those tables
 * exist).
 */
class CostCenterController extends MedAccountingBaseController
{
    public function index(Request $request)
    {
        $this->guard('medacc.costcenters.manage');

        if ($request->ajax()) {
            $query = MedaccCostCenter::forBusiness($this->businessId())
                ->select(['id', 'name', 'code', 'type', 'is_active']);

            return DataTables::of($query)
                ->editColumn('type', fn ($r) => __('medaccounting::lang.cc_type_' . $r->type))
                ->editColumn('is_active', fn ($r) => $r->is_active
                    ? '<span class="label label-success">' . __('medaccounting::lang.active') . '</span>'
                    : '<span class="label label-default">' . __('medaccounting::lang.inactive') . '</span>')
                ->addColumn('action', function ($r) {
                    return '<button class="btn btn-xs btn-default medacc-modal-btn" data-href="'
                        . route('medacc.costcenters.edit', $r->id) . '"><i class="fa fa-edit"></i> ' . __('messages.edit') . '</button> '
                        . '<button class="btn btn-xs btn-danger medacc-delete-btn" data-href="'
                        . route('medacc.costcenters.destroy', $r->id) . '"><i class="fa fa-trash"></i></button>';
                })
                ->rawColumns(['is_active', 'action'])
                ->make(true);
        }

        return view('medaccounting::cost_centers.index');
    }

    public function create()
    {
        $this->guard('medacc.costcenters.manage');

        return view('medaccounting::cost_centers.form', [
            'costCenter'  => new MedaccCostCenter(),
            'types'       => MedaccCostCenter::TYPES,
            'departments' => $this->departmentOptions(),
        ]);
    }

    public function edit($id)
    {
        $this->guard('medacc.costcenters.manage');
        $cc = MedaccCostCenter::forBusiness($this->businessId())->findOrFail($id);

        return view('medaccounting::cost_centers.form', [
            'costCenter'  => $cc,
            'types'       => MedaccCostCenter::TYPES,
            'departments' => $this->departmentOptions(),
        ]);
    }

    public function store(Request $request)
    {
        $this->guard('medacc.costcenters.manage');
        $data = $this->validated($request);

        try {
            $data['business_id'] = $this->businessId();
            MedaccCostCenter::create($data);

            return $this->ok(__('medaccounting::lang.cost_center_saved'));
        } catch (\Exception $e) {
            \Log::emergency($e->getMessage());

            return $this->fail();
        }
    }

    public function update(Request $request, $id)
    {
        $this->guard('medacc.costcenters.manage');
        $cc = MedaccCostCenter::forBusiness($this->businessId())->findOrFail($id);
        $data = $this->validated($request);

        try {
            $cc->update($data);

            return $this->ok(__('medaccounting::lang.cost_center_saved'));
        } catch (\Exception $e) {
            \Log::emergency($e->getMessage());

            return $this->fail();
        }
    }

    public function destroy($id)
    {
        $this->guard('medacc.costcenters.manage');

        try {
            $cc = MedaccCostCenter::forBusiness($this->businessId())->findOrFail($id);
            if ($cc->lines()->exists()) {
                return $this->fail(__('medaccounting::lang.cost_center_in_use'));
            }
            $cc->delete();

            return $this->ok(__('medaccounting::lang.cost_center_deleted'));
        } catch (\Exception $e) {
            return $this->fail();
        }
    }

    private function validated(Request $request): array
    {
        $data = $this->validate($request, [
            'name'      => 'required|string|max:191',
            'code'      => 'nullable|string|max:40',
            'type'      => 'required|in:department,facility,project,other',
            'ref_id'    => 'nullable|integer',
            'is_active' => 'nullable|boolean',
        ]);

        return [
            'name'      => $data['name'],
            'code'      => $data['code'] ?? null,
            'type'      => $data['type'],
            'ref_id'    => ! empty($data['ref_id']) ? (int) $data['ref_id'] : null,
            'is_active' => $request->boolean('is_active', true),
        ];
    }

    /** ClinicCore departments for the ref picker (fail-soft when absent). */
    private function departmentOptions(): array
    {
        if (! Schema::hasTable('clc_departments')) {
            return [];
        }

        try {
            return DB::table('clc_departments')
                ->where('business_id', $this->businessId())
                ->orderBy('name')
                ->pluck('name', 'id')
                ->toArray();
        } catch (\Throwable $e) {
            return [];
        }
    }
}
