<?php

namespace Modules\Bms\Http\Controllers;

use Illuminate\Http\Request;
use Modules\Bms\Entities\BmsArea;
use Modules\Bms\Entities\BmsHall;
use Modules\Bms\Entities\BmsHallMedia;
use Modules\Bms\Entities\BmsVenue;
use Modules\Bms\Services\Contracts\MediaServiceContract;
use Yajra\DataTables\Facades\DataTables;

class HallController extends BmsBaseController
{
    public function index()
    {
        $this->guard('bms.halls.view');

        if (request()->ajax()) {
            $venueTypes = $this->venueTypes();

            $halls = BmsHall::where('bms_halls.business_id', $this->businessId())
                ->leftJoin('bms_venues', 'bms_venues.id', '=', 'bms_halls.venue_id')
                ->select([
                    'bms_halls.id', 'bms_halls.name', 'bms_halls.venue_type',
                    'bms_halls.capacity_min', 'bms_halls.capacity_max',
                    'bms_halls.min_budget', 'bms_halls.is_active',
                    'bms_venues.name as venue_name',
                ])
                ->withCount('media'); // after select() so the count subquery is retained

            return DataTables::of($halls)
                ->editColumn('venue_name', fn ($h) => $h->venue_name ?? '—')
                ->editColumn('venue_type', fn ($h) => $venueTypes[$h->venue_type] ?? $h->venue_type)
                ->addColumn('capacity', fn ($h) => $h->capacity_min.' – '.$h->capacity_max)
                ->editColumn('min_budget', fn ($h) => '<span class="display_currency" data-currency_symbol="true">'.$h->min_budget.'</span>')
                ->editColumn('is_active', fn ($h) => $h->is_active
                    ? '<span class="label label-success">'.__('bms::lang.active').'</span>'
                    : '<span class="label label-default">'.__('bms::lang.inactive').'</span>')
                ->addColumn('action', function ($h) {
                    $media = '<button data-href="'.route('bms.halls.media', $h->id).'" class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-info bms-modal-btn"><i class="fa fa-image"></i> '.__('bms::lang.media').' ('.$h->media_count.')</button>';
                    $edit = '<button data-href="'.route('bms.halls.edit', $h->id).'" class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-primary bms-modal-btn"><i class="glyphicon glyphicon-edit"></i> '.__('messages.edit').'</button>';
                    $del = '<button data-href="'.route('bms.halls.destroy', $h->id).'" class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-error bms-delete"><i class="glyphicon glyphicon-trash"></i> '.__('messages.delete').'</button>';
                    return $media.' '.$edit.' '.$del;
                })
                ->rawColumns(['action', 'is_active', 'min_budget'])
                ->make(true);
        }

        return view('bms::halls.index');
    }

    public function create()
    {
        $this->guard('bms.halls.manage');
        return view('bms::halls.create', $this->formData());
    }

    public function store(Request $request)
    {
        $this->guard('bms.halls.manage');
        $data = $this->validatedData($request);

        try {
            $venue = BmsVenue::where('business_id', $this->businessId())->findOrFail($data['venue_id']);
            $payload = $this->buildPayload($request, $data, $venue);
            $payload['business_id'] = $this->businessId();
            BmsHall::create($payload);
            BmsArea::syncFromLocations($this->businessId());
            return $this->ok(__('bms::lang.added_success'));
        } catch (\Exception $e) {
            \Log::emergency($e->getMessage());
            return $this->fail();
        }
    }

    public function edit($id)
    {
        $this->guard('bms.halls.manage');
        $hall = BmsHall::where('business_id', $this->businessId())->findOrFail($id);
        return view('bms::halls.edit', array_merge($this->formData(), ['hall' => $hall]));
    }

    public function update(Request $request, $id)
    {
        $this->guard('bms.halls.manage');
        $data = $this->validatedData($request);

        try {
            $hall = BmsHall::where('business_id', $this->businessId())->findOrFail($id);
            $venue = BmsVenue::where('business_id', $this->businessId())->findOrFail($data['venue_id']);
            $hall->update($this->buildPayload($request, $data, $venue));
            BmsArea::syncFromLocations($this->businessId());
            return $this->ok(__('bms::lang.updated_success'));
        } catch (\Exception $e) {
            \Log::emergency($e->getMessage());
            return $this->fail();
        }
    }

    public function destroy($id)
    {
        $this->guard('bms.halls.manage');
        try {
            BmsHall::where('business_id', $this->businessId())->findOrFail($id)->delete();
            BmsArea::syncFromLocations($this->businessId());
            return $this->ok(__('bms::lang.deleted_success'));
        } catch (\Exception $e) {
            \Log::emergency($e->getMessage());
            return $this->fail();
        }
    }

    // ---- Media manager ---------------------------------------------------

    public function media($id)
    {
        $this->guard('bms.halls.manage');
        $hall = BmsHall::where('business_id', $this->businessId())->with('media')->findOrFail($id);
        $media = app(MediaServiceContract::class);
        return view('bms::halls.media', compact('hall', 'media'));
    }

    public function storeMedia(Request $request, $id)
    {
        $this->guard('bms.halls.manage');
        $request->validate([
            'file'       => 'required_without:url|file|max:51200', // 50 MB
            'url'        => 'nullable|url', // hosted/CDN/YouTube (video or 360)
            'type'       => 'required|in:image,video,360',
            'title'      => 'nullable|string|max:191',
            'event_type' => 'nullable|in:Wedding,Engagement,Corporate,Birthday,Other',
        ]);

        try {
            $hall = BmsHall::where('business_id', $this->businessId())->findOrFail($id);
            $row = [
                'business_id' => $this->businessId(),
                'hall_id'     => $hall->id,
                'type'        => $request->input('type'),
                'title'       => $request->input('title'),
                'event_type'  => $request->input('event_type') ?: null,
                'is_cover'    => ! $hall->media()->where('is_cover', true)->exists(),
                'sort_order'  => (int) $hall->media()->max('sort_order') + 1,
            ];
            if ($request->hasFile('file')) {
                $stored = app(MediaServiceContract::class)->store($this->businessId(), "halls/{$hall->id}", $request->file('file'));
                $row['disk'] = $stored['disk'];
                $row['path'] = $stored['path'];
                $row['url'] = $stored['url'];
            } else {
                $row['url'] = $request->input('url');
            }

            BmsHallMedia::create($row);

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

    public function destroyMedia($id, $mediaId)
    {
        $this->guard('bms.halls.manage');
        try {
            $item = BmsHallMedia::where('business_id', $this->businessId())
                ->where('hall_id', $id)->findOrFail($mediaId);
            app(MediaServiceContract::class)->delete($item->disk, $item->path);
            $item->delete();
            return $this->ok(__('bms::lang.deleted_success'));
        } catch (\Exception $e) {
            \Log::emergency($e->getMessage());
            return $this->fail();
        }
    }

    // ---- helpers ---------------------------------------------------------

    protected function formData(): array
    {
        $venues = BmsVenue::where('business_id', $this->businessId())
            ->orderBy('name')->pluck('name', 'id')->toArray();

        $managers = \App\User::where('business_id', $this->businessId())
            ->where('allow_login', 1)
            ->get(['id', 'first_name', 'surname', 'username'])
            ->mapWithKeys(fn ($u) => [$u->id => trim(($u->first_name ?? '').' '.($u->surname ?? '')) ?: $u->username])
            ->toArray();

        return [
            'venues'     => $venues,
            'managers'   => $managers,
            'venueTypes' => $this->venueTypes(),
            'fnbLevels'  => $this->fnbLevels(),
            'features'   => $this->featureKeys(),
        ];
    }

    protected function validatedData(Request $request): array
    {
        return $this->validate($request, [
            'venue_id'          => 'required|integer',
            'name'              => 'required|string|max:191',
            'name_ar'           => 'nullable|string|max:191',
            'code'              => 'nullable|string|max:60',
            'capacity_min'      => 'nullable|integer|min:0',
            'capacity_max'      => 'nullable|integer|min:0',
            'venue_type'        => 'required|in:open,closed,both',
            'fnb_levels'        => 'nullable|array',
            'fnb_levels.*'      => 'string',
            'area_sqm'          => 'nullable|numeric|min:0',
            'hall_manager_ids'  => 'nullable|array',
            'hall_manager_ids.*'=> 'integer',
            'features'          => 'nullable|array',
            'description'       => 'nullable|string',
            'description_ar'    => 'nullable|string',
            'is_active'         => 'nullable',
        ]);
    }

    protected function buildPayload(Request $request, array $data, BmsVenue $venue): array
    {
        // features arrive as a list of checked keys -> store as { key: true }
        $features = [];
        foreach ((array) $request->input('features', []) as $key) {
            $features[$key] = true;
        }

        $managerIds = array_values(array_map('intval', (array) ($data['hall_manager_ids'] ?? [])));

        return [
            'venue_id'         => $venue->id,
            'location_id'      => $venue->location_id,
            'area_id'          => $venue->area_id,
            'name'             => $data['name'],
            'name_ar'          => $data['name_ar'] ?? null,
            'code'             => $data['code'] ?? null,
            'capacity_min'     => (int) ($data['capacity_min'] ?? 0),
            'capacity_max'     => (int) ($data['capacity_max'] ?? 0),
            'venue_type'       => $data['venue_type'],
            'fnb_levels'       => array_values((array) ($data['fnb_levels'] ?? [])),
            'area_sqm'         => $data['area_sqm'] ?? null,
            'hall_manager_ids' => $managerIds,
            'hall_manager_id'  => $managerIds[0] ?? null, // keep the single column in sync
            'features'         => $features,
            'description'      => $data['description'] ?? null,
            'description_ar'   => $data['description_ar'] ?? null,
            'is_active'        => $request->boolean('is_active'),
        ];
        // min_budget / base_price are derived from the hall's packages
        // (BmsHall::recomputePricing), not entered here.
    }
}
