<?php

namespace Modules\Vrc\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Modules\Vrc\Entities\VrcService;
use Modules\Vrc\Entities\VrcServicePackage;
use Modules\Vrc\Entities\VrcServicePackageItem;
use Modules\Vrc\Services\Catalog\PackageExpander;
use Modules\Vrc\Services\Finance\TotalsBuilder;
use Yajra\DataTables\Facades\DataTables;

class ServicePackageController extends VrcBaseController
{
    public function __construct(
        protected PackageExpander $expander,
        protected TotalsBuilder $totals
    ) {
    }

    public function index()
    {
        $this->guard('vrc.service.view');

        if (request()->ajax()) {
            $packages = VrcServicePackage::where('business_id', $this->businessId())
                ->withCount('items')
                ->select(['id', 'name', 'name_ar', 'price', 'is_active']);

            return DataTables::of($packages)
                ->editColumn('price', fn ($p) => $p->price !== null ? $p->price : __('vrc::lang.sum_of_items'))
                ->editColumn('is_active', fn ($p) => $p->is_active
                    ? '<span class="label label-success">' . __('vrc::lang.active') . '</span>'
                    : '<span class="label label-default">' . __('vrc::lang.inactive') . '</span>')
                ->addColumn('action', function ($p) {
                    if (! auth()->user()->can('vrc.service.manage')) {
                        return '';
                    }
                    return '<button data-href="' . route('vrc.service-packages.edit', $p->id) . '" class="btn btn-xs btn-primary vrc-modal-btn"><i class="fa fa-edit"></i> ' . __('messages.edit') . '</button> '
                        . '<button data-href="' . route('vrc.service-packages.destroy', $p->id) . '" class="btn btn-xs btn-danger vrc-delete"><i class="fa fa-trash"></i></button>';
                })
                ->rawColumns(['is_active', 'action'])
                ->make(true);
        }

        return view('vrc::packages.index');
    }

    public function create()
    {
        $this->guard('vrc.service.manage');
        return view('vrc::packages.create', ['services' => $this->serviceOptions()]);
    }

    public function store(Request $request)
    {
        $this->guard('vrc.service.manage');
        $data = $this->rules($request);

        DB::beginTransaction();
        try {
            $package = VrcServicePackage::create([
                'business_id' => $this->businessId(),
                'name'        => $data['name'],
                'name_ar'     => $data['name_ar'] ?? null,
                'price'       => $request->filled('price') ? (float) $request->price : null,
                'is_active'   => $request->boolean('is_active', true),
            ]);
            $this->syncItems($package, $request);
            DB::commit();
            return $this->ok(__('vrc::lang.added_success'));
        } catch (\Exception $e) {
            DB::rollBack();
            \Log::emergency($e->getMessage());
            return $this->fail();
        }
    }

    public function edit($id)
    {
        $this->guard('vrc.service.manage');
        $package = VrcServicePackage::with('items')->where('business_id', $this->businessId())->findOrFail($id);
        return view('vrc::packages.edit', ['package' => $package, 'services' => $this->serviceOptions()]);
    }

    public function update(Request $request, $id)
    {
        $this->guard('vrc.service.manage');
        $data = $this->rules($request);

        DB::beginTransaction();
        try {
            $package = VrcServicePackage::where('business_id', $this->businessId())->findOrFail($id);
            $package->update([
                'name'      => $data['name'],
                'name_ar'   => $data['name_ar'] ?? null,
                'price'     => $request->filled('price') ? (float) $request->price : null,
                'is_active' => $request->boolean('is_active', true),
            ]);
            $package->items()->delete();
            $this->syncItems($package, $request);
            DB::commit();
            return $this->ok(__('vrc::lang.updated_success'));
        } catch (\Exception $e) {
            DB::rollBack();
            \Log::emergency($e->getMessage());
            return $this->fail();
        }
    }

    public function destroy($id)
    {
        $this->guard('vrc.service.manage');
        try {
            $package = VrcServicePackage::where('business_id', $this->businessId())->findOrFail($id);
            $package->items()->delete();
            $package->delete();
            return $this->ok(__('vrc::lang.deleted_success'));
        } catch (\Exception $e) {
            \Log::emergency($e->getMessage());
            return $this->fail();
        }
    }

    /**
     * Expand a package into priced lines (JSON) for line entry on a repair
     * order / estimate. Totals computed server-side via the ERP tax engine.
     */
    public function apply($id)
    {
        $this->guard('vrc.service.view');
        $bid = $this->businessId();

        $package = VrcServicePackage::with('items.service')->where('business_id', $bid)->findOrFail($id);

        $items = $package->items->map(function (VrcServicePackageItem $item) {
            $svc = $item->service;
            return [
                'service_id'          => $item->service_id,
                'name'                => $svc->name ?? '',
                'default_price'       => $svc->default_price ?? 0,
                'default_labor_hours' => $svc->default_labor_hours ?? 0,
                'taxable'             => (bool) ($svc->taxable ?? true),
                'tax_rate_id'         => $svc->tax_rate_id ?? null,
                'qty'                 => $item->qty,
                'override_price'      => $item->override_price,
            ];
        })->all();

        $lines = $this->expander->expand($items);
        $totals = $this->totals->build($bid, $lines);

        return response()->json([
            'success' => true,
            'package' => ['id' => $package->id, 'name' => $package->name, 'price' => $package->price],
            'lines'   => $totals['lines'],
            'totals'  => [
                'subtotal'       => $totals['subtotal'],
                'discount_total' => $totals['discount_total'],
                'tax_total'      => $totals['tax_total'],
                'grand_total'    => $totals['grand_total'],
            ],
        ]);
    }

    protected function syncItems(VrcServicePackage $package, Request $request): void
    {
        $serviceIds = (array) $request->input('service_id', []);
        $qtys = (array) $request->input('item_qty', []);
        $overrides = (array) $request->input('override_price', []);

        foreach ($serviceIds as $i => $serviceId) {
            if (empty($serviceId)) {
                continue;
            }
            VrcServicePackageItem::create([
                'business_id'    => $package->business_id,
                'package_id'     => $package->id,
                'service_id'     => (int) $serviceId,
                'qty'            => (float) ($qtys[$i] ?? 1),
                'override_price' => isset($overrides[$i]) && $overrides[$i] !== '' ? (float) $overrides[$i] : null,
            ]);
        }
    }

    protected function rules(Request $request): array
    {
        return $this->validate($request, [
            'name'    => 'required|string|max:191',
            'name_ar' => 'nullable|string|max:191',
            'price'   => 'nullable|numeric|min:0',
            'is_active' => 'nullable',
        ]);
    }

    protected function serviceOptions(): array
    {
        return VrcService::where('business_id', $this->businessId())
            ->where('is_active', true)->orderBy('name')->pluck('name', 'id')->toArray();
    }
}
