<?php

namespace Modules\MedAccounting\Http\Controllers;

use Carbon\Carbon;
use Illuminate\Http\Request;
use Modules\MedAccounting\Entities\MedaccPeriod;
use Yajra\DataTables\Facades\DataTables;

/**
 * Accounting-period management (SIFA P7-T2). Open/close periods to lock backdated
 * posting. Business-scoped; guarded by medacc.periods.manage.
 */
class PeriodController extends MedAccountingBaseController
{
    public function index(Request $request)
    {
        $this->guard('medacc.periods.manage');

        if ($request->ajax()) {
            $query = MedaccPeriod::forBusiness($this->businessId())
                ->select(['id', 'name', 'start_date', 'end_date', 'status', 'closed_at']);

            return DataTables::of($query)
                ->editColumn('start_date', fn ($r) => optional($r->start_date)->format('Y-m-d'))
                ->editColumn('end_date', fn ($r) => optional($r->end_date)->format('Y-m-d'))
                ->editColumn('status', fn ($r) => '<span class="label label-' . ($r->status === 'open' ? 'success' : 'default') . '">'
                    . __('medaccounting::lang.period_status_' . $r->status) . '</span>')
                ->addColumn('action', function ($r) {
                    if ($r->status === 'open') {
                        return '<button class="btn btn-xs btn-warning medacc-period-toggle" data-href="'
                            . route('medacc.periods.close', $r->id) . '"><i class="fa fa-lock"></i> ' . __('medaccounting::lang.close_period') . '</button>';
                    }

                    return '<button class="btn btn-xs btn-success medacc-period-toggle" data-href="'
                        . route('medacc.periods.reopen', $r->id) . '"><i class="fa fa-unlock"></i> ' . __('medaccounting::lang.reopen_period') . '</button>';
                })
                ->rawColumns(['status', 'action'])
                ->make(true);
        }

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

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

        $start = Carbon::now()->startOfMonth();

        return view('medaccounting::periods.form', [
            'period'  => new MedaccPeriod([
                'name'       => $start->format('Y-m'),
                'start_date' => $start->toDateString(),
                'end_date'   => $start->copy()->endOfMonth()->toDateString(),
            ]),
        ]);
    }

    public function store(Request $request)
    {
        $this->guard('medacc.periods.manage');

        $data = $this->validate($request, [
            'name'       => 'required|string|max:60',
            'start_date' => 'required|date',
            'end_date'   => 'required|date|after_or_equal:start_date',
        ]);

        try {
            MedaccPeriod::create([
                'business_id' => $this->businessId(),
                'name'        => $data['name'],
                'start_date'  => $data['start_date'],
                'end_date'    => $data['end_date'],
                'status'      => 'open',
            ]);

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

            return $this->fail(str_contains($e->getMessage(), 'medacc_periods_biz_name_uq')
                ? __('medaccounting::lang.period_name_taken')
                : __('messages.something_went_wrong'));
        }
    }

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

        try {
            $period = MedaccPeriod::forBusiness($this->businessId())->findOrFail($id);
            $period->update([
                'status'    => 'closed',
                'closed_by' => $this->userId(),
                'closed_at' => Carbon::now(),
            ]);

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

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

        try {
            $period = MedaccPeriod::forBusiness($this->businessId())->findOrFail($id);
            $period->update([
                'status'    => 'open',
                'closed_by' => null,
                'closed_at' => null,
            ]);

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