<?php

namespace Modules\MedBilling\Http\Controllers;

use App\SellingPriceGroup;
use Illuminate\Http\Request;
use Modules\MedBilling\Entities\MedbillPayer;
use Yajra\DataTables\Facades\DataTables;

/** Payer master CRUD (SIFA P4-T1). Business-scoped; guarded by medbill.payers.manage. */
class PayerController extends MedBillingBaseController
{
    public function index(Request $request)
    {
        $this->guard('medbill.payers.manage');

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

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

        return view('medbilling::payers.index');
    }

    public function create()
    {
        $this->guard('medbill.payers.manage');

        return view('medbilling::payers.form', [
            'payer'        => new MedbillPayer(),
            'priceGroups'  => $this->priceGroups(),
            'payerTypes'   => MedbillPayer::PAYER_TYPES,
            'submissions'  => MedbillPayer::CLAIM_SUBMISSIONS,
        ]);
    }

    public function edit($id)
    {
        $this->guard('medbill.payers.manage');

        $payer = MedbillPayer::forBusiness($this->businessId())->findOrFail($id);

        return view('medbilling::payers.form', [
            'payer'       => $payer,
            'priceGroups' => $this->priceGroups(),
            'payerTypes'  => MedbillPayer::PAYER_TYPES,
            'submissions' => MedbillPayer::CLAIM_SUBMISSIONS,
        ]);
    }

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

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

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

            return $this->fail();
        }
    }

    public function update(Request $request, $id)
    {
        $this->guard('medbill.payers.manage');
        $payer = MedbillPayer::forBusiness($this->businessId())->findOrFail($id);
        $data = $this->validated($request);

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

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

            return $this->fail();
        }
    }

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

        try {
            $payer = MedbillPayer::forBusiness($this->businessId())->findOrFail($id);
            if ($payer->policies()->exists() || $payer->claims()->exists()) {
                return $this->fail(__('medbilling::lang.payer_in_use'));
            }
            $payer->delete();

            return $this->ok(__('medbilling::lang.payer_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:60',
            'payer_type'                => 'required|in:insurance,corporate,government,other',
            'default_price_group_id'    => 'nullable|integer',
            'claim_submission'          => 'required|in:portal,email,edi,paper',
            'pre_auth_required_default' => 'nullable|boolean',
            'settlement_terms_days'     => 'nullable|integer|min:0',
            'is_active'                 => 'nullable|boolean',
            'contact_phone'             => 'nullable|string|max:60',
            'contact_email'             => 'nullable|string|max:191',
            'contact_address'           => 'nullable|string|max:255',
        ]);

        return [
            'name'                      => $data['name'],
            'code'                      => $data['code'] ?? null,
            'payer_type'                => $data['payer_type'],
            'default_price_group_id'    => ! empty($data['default_price_group_id']) ? (int) $data['default_price_group_id'] : null,
            'claim_submission'          => $data['claim_submission'],
            'pre_auth_required_default' => $request->boolean('pre_auth_required_default'),
            'settlement_terms_days'     => $data['settlement_terms_days'] ?? null,
            'is_active'                 => $request->boolean('is_active', true),
            'contact'                   => array_filter([
                'phone'   => $data['contact_phone'] ?? null,
                'email'   => $data['contact_email'] ?? null,
                'address' => $data['contact_address'] ?? null,
            ]),
        ];
    }

    /** Selling price groups for this business (payer price-list picker). */
    private function priceGroups(): array
    {
        return SellingPriceGroup::where('business_id', $this->businessId())
            ->where('is_active', 1)
            ->pluck('name', 'id')
            ->toArray();
    }
}
