<?php

namespace Modules\Bms\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Modules\Bms\Entities\BmsAsset;
use Modules\Bms\Entities\BmsBooking;
use Modules\Bms\Entities\BmsHall;
use Modules\Bms\Entities\BmsLead;
use Modules\Bms\Entities\BmsMaintenanceRequest;
use Modules\Bms\Entities\BmsMatchingSetting;
use Modules\Bms\Entities\BmsOfficeVisit;
use Modules\Bms\Entities\BmsPackage;
use Modules\Bms\Entities\BmsTask;
use Modules\Bms\Entities\BmsVenue;

class BmsController extends Controller
{
    /** BMS back-office dashboard — KPIs, revenue, pipeline & operations. */
    public function index()
    {
        if (! auth()->user()->can('bms.access')) {
            abort(403, 'Unauthorized action.');
        }

        $biz = (int) request()->session()->get('user.business_id');

        // ---- headline counts -------------------------------------------------
        $stats = [
            'venues'         => BmsVenue::where('business_id', $biz)->count(),
            'halls'          => BmsHall::where('business_id', $biz)->where('is_active', true)->count(),
            'packages'       => BmsPackage::where('business_id', $biz)->count(),
            'leads'          => BmsLead::where('business_id', $biz)->count(),
            'bookings'       => BmsBooking::where('business_id', $biz)->count(),
            'upcoming_visits' => BmsOfficeVisit::where('business_id', $biz)
                ->whereDate('visit_date', '>=', today())->whereIn('status', ['requested', 'scheduled'])->count(),
        ];

        // ---- revenue (from confirmed bookings' ERP invoices) -----------------
        $invoiceIds = BmsBooking::where('business_id', $biz)->whereNotNull('erp_invoice_id')->pluck('erp_invoice_id');
        $invoiced  = (float) DB::table('transactions')->whereIn('id', $invoiceIds)->sum('final_total');
        $collected = (float) DB::table('transaction_payments')->whereIn('transaction_id', $invoiceIds)->sum('amount');
        $revenue = [
            'invoiced'  => $invoiced,
            'collected' => $collected,
            'due'       => max(0, $invoiced - $collected),
            'collected_pct' => $invoiced > 0 ? round($collected / $invoiced * 100) : 0,
        ];

        // ---- pipeline by stage ----------------------------------------------
        $stageOrder = ['wizard_incomplete', 'wizard_complete', 'qualified_awaiting_contact',
            'contacted', 'proposal_sent', 'negotiation', 'won', 'lost'];
        $byStage = BmsLead::where('business_id', $biz)->groupBy('stage')->selectRaw('stage, count(*) c')->pluck('c', 'stage');
        $pipeline = collect($stageOrder)->map(fn ($s) => ['stage' => $s, 'count' => (int) ($byStage[$s] ?? 0)])
            ->filter(fn ($r) => $r['count'] > 0)->values();
        $pipelineMax = (int) ($pipeline->max('count') ?: 1);

        // ---- bookings by month (last 6) -------------------------------------
        $since = now()->subMonths(5)->startOfMonth();
        $bkByMonth = BmsBooking::where('business_id', $biz)->where('created_at', '>=', $since)
            ->get(['created_at'])->groupBy(fn ($b) => $b->created_at->format('Y-m'))->map->count();
        $months = collect(range(5, 0))->map(function ($i) use ($bkByMonth) {
            $m = now()->subMonths($i);
            return ['label' => $m->format('M'), 'count' => (int) ($bkByMonth[$m->format('Y-m')] ?? 0)];
        });
        $monthsMax = (int) ($months->max('count') ?: 1);

        // ---- operations ------------------------------------------------------
        $ops = [
            'tasks_total'     => BmsTask::where('business_id', $biz)->count(),
            'tasks_done'      => BmsTask::where('business_id', $biz)->where('status', 'done')->count(),
            'tasks_overdue'   => BmsTask::where('business_id', $biz)->where('status', '!=', 'done')->where('due_at', '<', now())->count(),
            'maint_open'      => BmsMaintenanceRequest::where('business_id', $biz)->whereIn('status', BmsMaintenanceRequest::OPEN_STATUSES)->count(),
            'maint_overdue'   => BmsMaintenanceRequest::where('business_id', $biz)->whereIn('status', BmsMaintenanceRequest::OPEN_STATUSES)
                ->whereNotNull('due_at')->where('due_at', '<', now())->count(),
            'assets'          => BmsAsset::where('business_id', $biz)->count(),
            'assets_value'    => (float) BmsAsset::where('business_id', $biz)->sum(DB::raw('unit_value * quantity')),
        ];
        $ops['tasks_pct'] = $ops['tasks_total'] > 0 ? round($ops['tasks_done'] / $ops['tasks_total'] * 100) : 0;

        $matching = BmsMatchingSetting::resolve($biz);

        return view('bms::dashboard.index', compact(
            'stats', 'revenue', 'pipeline', 'pipelineMax', 'months', 'monthsMax', 'ops', 'matching'
        ));
    }
}
