<?php

namespace App\Http\Controllers\Modules\Dashboard;

use App\Http\Controllers\Controller;
use App\Http\Traits\HasRoleViews;
use App\Models\CustomerVendor;
use App\Models\EmployeeDetails;
use App\Models\EmployeeDailyReport;
use App\Models\EmployeeLeave;
use App\Models\EmployeeSalaryDetail;
use App\Models\Rfq;
use App\Models\Quotation;
use App\Models\SalesOrder;
use App\Models\TaxInvoice;
use App\Models\PurchaseRFQ;
use App\Models\PurchaseQuotation;
use App\Models\PurchaseOrder;
use App\Models\Grn;
use App\Models\RouteCard;
use App\Models\RouteCardProcess;
use App\Models\ManufacturingPlan;
use App\Models\SkuMaster;
use App\Models\SkuMovement;
use App\Models\Machines;
use App\Models\QualityControl;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

/**
 * Unified Dashboard Controller
 *
 * Handles various dashboard views for all roles.
 * Reference: SuperAdminDashboardController
 */
class DashboardController extends Controller
{
    use HasRoleViews;

    /**
     * Main comprehensive dashboard
     */
    public function allDashboard()
    {
        $today = now()->toDateString();
        $currentMonth = now()->month;
        $currentYear = now()->year;

        // === CUSTOMER/VENDOR METRICS ===
        $totalCustomers = CustomerVendor::where('company_role', 'Customer')
            ->orWhere('company_role', 'Both')->count();
        $totalVendors = CustomerVendor::where('company_role', 'Vendor')
            ->orWhere('company_role', 'Both')->count();
        $totalCustomerMonthly = CustomerVendor::whereMonth('created_at', $currentMonth)
            ->whereYear('created_at', $currentYear)->count();
        $totalCustomerAnnual = CustomerVendor::whereYear('created_at', $currentYear)->count();

        // === SALES METRICS ===
        $totalRfqs = Rfq::count();
        $pendingRfqs = Rfq::where('status', 'pending')->count();
        $approvedRfqs = Rfq::where('status', 'approved')->count();

        $totalQuotations = Quotation::count();
        $pendingQuotations = Quotation::where('status', 'pending')->count();
        $approvedQuotations = Quotation::where('status', 'approved')->count();

        $totalSalesOrders = SalesOrder::count();
        $pendingSalesOrders = SalesOrder::where('status', 'pending')->count();
        $approvedSalesOrders = SalesOrder::where('status', 'approved')->count();

        $totalInvoices = TaxInvoice::count();
        $monthlyRevenue = TaxInvoice::whereMonth('invoice_date', $currentMonth)
            ->whereYear('invoice_date', $currentYear)
            ->sum('total_amount');
        $annualRevenue = TaxInvoice::whereYear('invoice_date', $currentYear)->sum('total_amount');

        // === PURCHASE METRICS ===
        $totalPurchaseRfqs = PurchaseRFQ::count();
        $pendingPurchaseRfqs = PurchaseRFQ::where('status', 'pending')->count();
        $totalPurchaseQuotations = PurchaseQuotation::count();
        $totalPurchaseOrders = PurchaseOrder::count();
        $pendingPurchaseOrders = PurchaseOrder::where('status', 'pending')->count();
        $totalGrns = Grn::count();

        // === MANUFACTURING METRICS ===
        $totalRouteCards = RouteCard::count();
        $pendingRouteCards = RouteCard::where('status', 'pending')->count();
        $inProductionRouteCards = RouteCard::where('status', 'in-production')->count();
        $completedRouteCards = RouteCard::where('status', 'completed')->count();

        $totalTasks = RouteCardProcess::count();
        $completedTasks = RouteCardProcess::whereNotNull('actual_end')->count();
        $dayTasksPercent = $totalTasks > 0 ? round(($completedTasks / $totalTasks) * 100, 1) : 0;
        $runningProjects = RouteCard::whereIn('status', ['in-production', 'ready'])->count();

        // === INVENTORY METRICS ===
        $totalSkus = SkuMaster::count();
        $lowStockItems = SkuMaster::whereColumn('current_stock', '<=', 'min_order_level')->count();
        $outOfStockItems = SkuMaster::where('current_stock', 0)->count();
        $totalStockValue = SkuMaster::selectRaw('SUM(current_stock * default_price) as value')->value('value') ?? 0;

        // === MACHINE METRICS ===
        $totalMachines = Machines::count();

        // === EMPLOYEE METRICS ===
        $totalEmployees = EmployeeDetails::count();
        $employeePresent = EmployeeDailyReport::whereDate('date', $today)
            ->distinct('employee_id')->count('employee_id');
        $employeeLeave = EmployeeLeave::where('status', 'approved')
            ->whereDate('leave_from', '<=', $today)
            ->whereDate('leave_to', '>=', $today)
            ->count();

        // === PENDING APPROVALS ===
        $pendingBills = $pendingPurchaseOrders;
        $totalPendingApprovals = $pendingRfqs + $pendingQuotations + $pendingSalesOrders +
            $pendingPurchaseRfqs + $pendingRouteCards;

        // === CHARTS DATA ===
        $salesTrend = collect(range(5, 0))->map(function ($i) {
            $date = now()->subMonths($i);
            $revenue = TaxInvoice::whereMonth('invoice_date', $date->month)
                ->whereYear('invoice_date', $date->year)
                ->sum('total_amount');
            return ['month' => $date->format('M Y'), 'revenue' => $revenue];
        });

        $orderStatusData = [
            'Pending' => $pendingSalesOrders,
            'Approved' => $approvedSalesOrders,
            'Completed' => SalesOrder::where('status', 'completed')->count(),
        ];

        // Recent Activities
        $recentRfqs = Rfq::latest()->take(3)->get()->map(fn($r) => [
            'type' => 'RFQ', 'title' => $r->rfq_no, 'status' => $r->status,
            'date' => $r->created_at, 'icon' => 'fa-file-alt', 'color' => 'primary',
        ]);
        $recentQuotations = Quotation::latest()->take(3)->get()->map(fn($q) => [
            'type' => 'Quotation', 'title' => $q->quotation_no, 'status' => $q->status,
            'date' => $q->created_at, 'icon' => 'fa-file-invoice', 'color' => 'success',
        ]);
        $recentSalesOrders = SalesOrder::latest()->take(3)->get()->map(fn($s) => [
            'type' => 'Sales Order', 'title' => $s->sales_order_no, 'status' => $s->status,
            'date' => $s->created_at, 'icon' => 'fa-shopping-cart', 'color' => 'info',
        ]);
        $recentActivities = $recentRfqs->concat($recentQuotations)->concat($recentSalesOrders)
            ->sortByDesc('date')->take(10)->values();

        // Top Customers
        $topCustomers = TaxInvoice::select('company_id', DB::raw('SUM(total_amount) as total_revenue'))
            ->with('company:id,company')
            ->groupBy('company_id')
            ->orderByDesc('total_revenue')
            ->take(5)
            ->get();

        // Production Status
        $productionStatus = [
            'Pending' => $pendingRouteCards,
            'In Production' => $inProductionRouteCards,
            'Completed' => $completedRouteCards,
        ];

        return $this->roleView('dashboard.alldashboard', compact(
            'totalCustomers', 'totalVendors', 'totalCustomerMonthly', 'totalCustomerAnnual',
            'totalRfqs', 'pendingRfqs', 'approvedRfqs',
            'totalQuotations', 'pendingQuotations', 'approvedQuotations',
            'totalSalesOrders', 'pendingSalesOrders', 'approvedSalesOrders',
            'totalInvoices', 'monthlyRevenue', 'annualRevenue',
            'totalPurchaseRfqs', 'pendingPurchaseRfqs', 'totalPurchaseQuotations',
            'totalPurchaseOrders', 'pendingPurchaseOrders', 'totalGrns',
            'totalRouteCards', 'pendingRouteCards', 'inProductionRouteCards', 'completedRouteCards',
            'dayTasksPercent', 'runningProjects',
            'totalSkus', 'lowStockItems', 'outOfStockItems', 'totalStockValue',
            'totalMachines', 'totalEmployees', 'employeePresent', 'employeeLeave',
            'pendingBills', 'totalPendingApprovals',
            'salesTrend', 'orderStatusData', 'recentActivities', 'topCustomers', 'productionStatus'
        ));
    }

    /**
     * Employee-focused dashboard
     */
    public function employeeDashboard()
    {
        $today = now()->toDateString();

        $totalEmployees = EmployeeDetails::count();
        $presentToday = EmployeeDailyReport::whereDate('date', $today)
            ->distinct('employee_id')->count('employee_id');
        $onLeaveToday = EmployeeLeave::where('status', 'approved')
            ->whereDate('leave_from', '<=', $today)
            ->whereDate('leave_to', '>=', $today)
            ->count();
        $absentToday = $totalEmployees - $presentToday - $onLeaveToday;

        $attendanceMonthly = EmployeeDailyReport::selectRaw('MONTH(date) as month, COUNT(DISTINCT employee_id) as present_count')
            ->whereYear('date', now()->year)
            ->groupBy('month')
            ->orderBy('month')
            ->pluck('present_count', 'month')
            ->toArray();

        $departmentDist = EmployeeDetails::selectRaw('department, COUNT(*) as total')
            ->groupBy('department')
            ->pluck('total', 'department')
            ->toArray();

        return $this->roleView('dashboard.employeedashboard', compact(
            'totalEmployees', 'presentToday', 'onLeaveToday', 'absentToday',
            'attendanceMonthly', 'departmentDist'
        ));
    }

    /**
     * Machine-focused dashboard
     */
    public function machineDashboard()
    {
        $allMachines = Machines::all();
        $totalMachines = $allMachines->count();

        $runningNow = ManufacturingPlan::where('status', 'running')
            ->whereDate('start_date', '<=', now())
            ->where(function ($q) {
                $q->whereNull('end_date')->orWhereDate('end_date', '>=', now());
            })
            ->distinct('machine')->count('machine');

        $underMaintenance = ManufacturingPlan::where('status', 'maintenance')
            ->whereDate('start_date', '<=', now())
            ->where(function ($q) {
                $q->whereNull('end_date')->orWhereDate('end_date', '>=', now());
            })
            ->count();

        $issuesToday = ManufacturingPlan::where('status', 'issue')
            ->whereDate('plan_date', now())
            ->count();

        $productionLast7 = ManufacturingPlan::selectRaw('DATE(plan_date) as date, COUNT(*) as output')
            ->whereDate('plan_date', '>=', now()->subDays(6))
            ->groupBy('date')
            ->orderBy('date')
            ->pluck('output', 'date')
            ->toArray();

        $machineStatus = [
            'Running' => $runningNow,
            'Maintenance' => $underMaintenance,
            'Idle' => max($totalMachines - $runningNow - $underMaintenance, 0),
        ];

        $activeProcesses = RouteCardProcess::where('status', 'in_progress')
            ->with('routeCard')
            ->get()
            ->groupBy('machine');

        $currentOperators = ManufacturingPlan::where('status', 'running')
            ->whereDate('plan_date', now())
            ->with('operator:id,name,designation,profile_picture')
            ->get()
            ->map(fn($plan) => [
                'name' => optional($plan->operator)->name ?? 'N/A',
                'role' => optional($plan->operator)->designation ?? 'Operator',
                'status' => 'Available',
                'profile_picture' => optional($plan->operator)->profile_picture ?? 'img/undraw_profile.svg',
            ])
            ->unique('name')
            ->take(5);

        return $this->roleView('dashboard.machinedashboard', compact(
            'totalMachines', 'runningNow', 'underMaintenance', 'issuesToday',
            'productionLast7', 'machineStatus', 'currentOperators', 'activeProcesses', 'allMachines'
        ));
    }

    /**
     * Stock/Inventory-focused dashboard
     */
    public function stockDashboard()
    {
        $totalItems = SkuMaster::count();
        $lowStock = SkuMaster::whereColumn('current_stock', '<=', 'min_order_level')->count();
        $outOfStock = SkuMaster::where('current_stock', 0)->count();

        $movementData = SkuMovement::selectRaw('DATE(date) as dt, SUM(CASE WHEN type="IN" THEN quantity ELSE -quantity END) as qty')
            ->whereDate('date', '>=', now()->subDays(30))
            ->groupBy('dt')
            ->orderBy('dt')
            ->pluck('qty', 'dt')
            ->toArray();

        $distribution = SkuMaster::selectRaw('category, SUM(current_stock) as total')
            ->groupBy('category')
            ->pluck('total', 'category')
            ->toArray();

        return $this->roleView('dashboard.stockdashboard', compact(
            'totalItems', 'lowStock', 'outOfStock', 'movementData', 'distribution'
        ));
    }

    /**
     * Account/Financial dashboard
     */
    public function accountDashboard()
    {
        $revenue = TaxInvoice::whereMonth('invoice_date', now()->month)
            ->whereYear('invoice_date', now()->year)
            ->sum('total_amount');

        $prevMonthRevenue = TaxInvoice::whereMonth('invoice_date', now()->subMonth()->month)
            ->whereYear('invoice_date', now()->subMonth()->year)
            ->sum('total_amount');

        $expenses = PurchaseOrder::whereMonth('created_at', now()->month)
            ->whereYear('created_at', now()->year)
            ->sum('grand_total');

        $prevMonthExpenses = PurchaseOrder::whereMonth('created_at', now()->subMonth()->month)
            ->whereYear('created_at', now()->subMonth()->year)
            ->sum('grand_total');

        $grossProfit = $revenue - $expenses;
        $prevMonthProfit = $prevMonthRevenue - $prevMonthExpenses;

        $productionCost = EmployeeSalaryDetail::whereMonth('created_at', now()->month)
            ->whereYear('created_at', now()->year)
            ->sum('net_salary');

        // Growth calculations
        $revenueGrowth = $prevMonthRevenue > 0
            ? (($revenue - $prevMonthRevenue) / $prevMonthRevenue * 100) : 0;
        $revenueGrowth = ($revenueGrowth >= 0 ? '+' : '') . number_format($revenueGrowth, 1) . '%';

        $expensesGrowth = $prevMonthExpenses > 0
            ? (($expenses - $prevMonthExpenses) / $prevMonthExpenses * 100) : 0;
        $expensesGrowth = ($expensesGrowth >= 0 ? '+' : '') . number_format($expensesGrowth, 1) . '%';

        $profitGrowth = $prevMonthProfit != 0
            ? (($grossProfit - $prevMonthProfit) / abs($prevMonthProfit) * 100) : 0;
        $profitGrowth = ($profitGrowth >= 0 ? '+' : '') . number_format($profitGrowth, 1) . '%';

        // Chart data
        $months = collect(range(0, 5))->map(fn($i) => now()->subMonths($i)->format('M Y'))->reverse()->values();
        $chartRevenue = $months->map(function ($month) {
            $date = Carbon::parse($month);
            return TaxInvoice::whereMonth('invoice_date', $date->month)
                ->whereYear('invoice_date', $date->year)
                ->sum('total_amount');
        });
        $chartExpenses = $months->map(function ($month) {
            $date = Carbon::parse($month);
            return PurchaseOrder::whereMonth('created_at', $date->month)
                ->whereYear('created_at', $date->year)
                ->sum('grand_total');
        });

        // Financial summary
        $outstandingInvoices = TaxInvoice::sum('total_amount');
        $pendingPurchaseAmount = PurchaseOrder::where('status', 'pending')->sum('grand_total');
        $netCashFlow = $revenue - $expenses;

        $summary = [
            ['title' => 'Outstanding Invoices', 'value' => '₹' . number_format($outstandingInvoices)],
            ['title' => 'Pending Bills', 'value' => '₹' . number_format($pendingPurchaseAmount)],
            ['title' => 'Net Cash Flow', 'value' => '₹' . number_format($netCashFlow)],
        ];

        $pendingInvoices = TaxInvoice::where('total_amount', '>', 0)
            ->orderBy('invoice_date', 'desc')->take(5)->get();

        return $this->roleView('dashboard.accountdashboard', compact(
            'revenue', 'expenses', 'grossProfit', 'productionCost',
            'revenueGrowth', 'expensesGrowth', 'profitGrowth',
            'months', 'chartRevenue', 'chartExpenses', 'summary', 'pendingInvoices'
        ));
    }

    /**
     * Manufacturing-focused dashboard
     */
    public function manufacturingDashboard()
    {
        $totalProduction = ManufacturingPlan::count();
        $totalMachines = Machines::count();
        $runningPlans = ManufacturingPlan::where('status', 'running')->count();
        $machineUtilization = $totalMachines > 0 ? round(($runningPlans / $totalMachines) * 100) : 0;

        $totalChecked = QualityControl::count();
        $totalPassed = QualityControl::where('status', 'pass')->count();
        $qualityRate = $totalChecked > 0 ? round(($totalPassed / $totalChecked) * 100, 1) : 100;

        $availability = $machineUtilization;
        $completedPlans = ManufacturingPlan::where('status', 'completed')->count();
        $performance = $totalProduction > 0 ? round(($completedPlans / $totalProduction) * 100) : 0;
        $oeeRate = round(($availability * $performance * $qualityRate) / 10000, 1);

        $productionTrend = ManufacturingPlan::selectRaw('DATE(plan_date) as day, COUNT(*) as output')
            ->whereDate('plan_date', '>=', now()->subDays(6))
            ->groupBy('day')->orderBy('day')->pluck('output', 'day')->toArray();

        $defectTrend = QualityControl::selectRaw('DATE(created_at) as day, COUNT(*) as defects')
            ->where('status', 'fail')
            ->whereDate('created_at', '>=', now()->subDays(6))
            ->groupBy('day')->orderBy('day')->pluck('defects', 'day')->toArray();

        $machineStatus = [
            'Running' => ManufacturingPlan::where('status', 'running')->count(),
            'Maintenance' => ManufacturingPlan::where('status', 'maintenance')->count(),
            'Idle' => max($totalMachines - $runningPlans, 0),
        ];

        $productionByLine = ManufacturingPlan::selectRaw('machine, COUNT(*) as total')
            ->whereNotNull('machine')
            ->where('machine', '!=', '')
            ->groupBy('machine')->pluck('total', 'machine')->toArray();

        // Recent Alerts
        $recentAlerts = collect();
        $qcFailures = QualityControl::where('status', 'fail')
            ->whereDate('created_at', '>=', now()->subDays(7))
            ->orderBy('created_at', 'desc')
            ->take(3)
            ->get()
            ->map(fn($qc) => [
                'type' => 'Error',
                'message' => 'Quality check failed - ' . ($qc->remarks ?? 'QC ID: ' . $qc->id),
                'time' => $qc->created_at->diffForHumans(),
            ]);
        $recentAlerts = $recentAlerts->concat($qcFailures);

        $lowStockAlerts = SkuMaster::whereColumn('current_stock', '<=', 'min_order_level')
            ->where('current_stock', '>', 0)
            ->take(2)
            ->get()
            ->map(fn($sku) => [
                'type' => 'Warning',
                'message' => 'Low stock alert: ' . ($sku->item_name ?? $sku->description),
                'time' => 'Current stock: ' . $sku->current_stock,
            ]);
        $recentAlerts = $recentAlerts->concat($lowStockAlerts)->take(5)->values()->toArray();

        return $this->roleView('dashboard.manufacturingdashboard', compact(
            'totalProduction', 'machineUtilization', 'qualityRate', 'oeeRate',
            'productionTrend', 'defectTrend', 'machineStatus', 'productionByLine', 'recentAlerts'
        ));
    }
}
