<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Conveyance;
use App\Models\Session;
use App\Models\Client;
use App\Models\User;
use App\Exports\EmployeeMasterExport;
use App\Exports\ClientConveyanceSummaryExport;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\ClientEmployeeConveyanceExport; 
use Illuminate\Support\Str; 


class AdminConveyanceReportController extends Controller
{
     

    public function clientSummary(Request $request)
    {
        $sessions = Session::orderBy('start_date', 'desc')->get();
        $clients  = Client::orderBy('name')->get();

        $month     = $request->query('month');       // Y-m
        $fromInput = $request->query('from_date');   // Y-m-d
        $toInput   = $request->query('to_date');     // Y-m-d
        $sessionId = $request->query('session_id') ? (int)$request->query('session_id') : null;
        $clientId  = $request->query('client_id') ? (int)$request->query('client_id') : null;

        $monthStart = null;
        $monthEnd   = null;
        $currentMonthLabel = 'All Time'; // Default label
        $applyDateFilter = false;        // Default to NO date filter (All Time)

        // 1) DATE FILTERS
        // A) Month selected
        if ($month) {
            try {
                $target = Carbon::createFromFormat('Y-m', $month)->startOfMonth();
                $monthStart = $target->copy()->startOfMonth();
                $monthEnd   = $target->copy()->endOfMonth();
                $currentMonthLabel = $target->format('F Y');
                $applyDateFilter = true;
            } catch (\Throwable $e) {
                // Invalid format, ignore
            }
        }
        // B) Custom Range
        elseif ($fromInput || $toInput) {
            if ($fromInput) {
                $monthStart = Carbon::parse($fromInput)->startOfDay();
            }
            if ($toInput) {
                $monthEnd = Carbon::parse($toInput)->endOfDay();
            }

            // Fallbacks if one side is missing
            if ($monthStart && !$monthEnd) {
                 // Open-ended future? Or end of today? Let's just say "From X"
                 $currentMonthLabel = 'From ' . $monthStart->format('d M Y');
            } elseif ($monthEnd && !$monthStart) {
                 $currentMonthLabel = 'Until ' . $monthEnd->format('d M Y');
            } elseif ($monthStart && $monthEnd) {
                $currentMonthLabel = $monthStart->format('d M Y') . ' – ' . $monthEnd->format('d M Y');
            }
            $applyDateFilter = true;
        }
        // C) Session Selected
        elseif ($sessionId) {
            $session = Session::find($sessionId);
            if ($session) {
                // If session has dates, we COULD filter by date, 
                // but usually "Session" just means filtering by session_id column effectively.
                // However, for display purposes we might want to show dates.
                // For now, let's keep it simple: filter query by session_id, verify Label.
                $currentMonthLabel = $session->name;
                // If you want to restrict DATES to session dates strictly:
                // $monthStart = $session->start_date ? Carbon::parse($session->start_date) : null;
                // $monthEnd = $session->end_date ? Carbon::parse($session->end_date) : null;
                // $applyDateFilter = true; 
            }
        }

        // Build query
        $q = Conveyance::with(['client', 'user', 'session'])
            ->where('status', 'submitted');

        $fromDate = $monthStart ? $monthStart->toDateString() : null;
        $toDate   = $monthEnd ? $monthEnd->toDateString() : null;

        if ($applyDateFilter) {
            if ($fromDate && $toDate) {
                $q->whereBetween('date', [$fromDate, $toDate]);
            } elseif ($fromDate) {
                $q->where('date', '>=', $fromDate);
            } elseif ($toDate) {
                $q->where('date', '<=', $toDate);
            }
        }

        if ($sessionId) {
            $q->where('session_id', $sessionId);
        }

        if ($clientId) {
            $q->where('client_id', $clientId);
        }

        $rows = $q->orderBy('date', 'asc')->get();

        // Effective total function (onward + return/custom)
        $rowTotal = function ($c) {
            $onward = (float)$c->amount;
            if ($c->is_return) {
                $return = $c->return_amount !== null
                    ? (float)$c->return_amount
                    : $onward;
                return $onward + $return;
            }
            return $onward;
        };

        $grandTotal = $rows->sum($rowTotal);

        return view('admin.conveyance.clients', [
            'rows'              => $rows,
            'sessions'          => $sessions,
            'clients'           => $clients,
            'month'             => $month,
            'fromDate'          => $fromInput,
            'toDate'            => $toInput,
            'sessionId'         => $sessionId,
            'clientId'          => $clientId,
            // Pass calculated dates for display usage
            'monthStart'        => $monthStart,
            'monthEnd'          => $monthEnd,
            'currentMonthLabel' => $currentMonthLabel,
            'grandTotal'        => $grandTotal,
        ]);
    }

/**
 * EXPORT client-wise summary with same filters
 */
public function clientSummaryExport(Request $request)
{
    $month     = $request->query('month');
    $fromInput = $request->query('from_date');
    $toInput   = $request->query('to_date');
    $sessionId = $request->query('session_id') ? (int)$request->query('session_id') : null;
    $clientId  = $request->query('client_id') ? (int)$request->query('client_id') : null;

    $fromDate = $fromInput;
    $toDate   = $toInput;

    // If month is given, override from/to with that month
    if ($month) {
        try {
            $target = Carbon::createFromFormat('Y-m', $month)->startOfMonth();
            $fromDate = $target->copy()->startOfMonth()->toDateString();
            $toDate   = $target->copy()->endOfMonth()->toDateString();
        } catch (\Throwable $e) {
            // ignore parsing errors, keep whatever from/to were
        }
    }

    // If neither month nor from/to → we assume ALL TIME (no start/end dates)
    // The query logic in generic Export class should handle null from/to as "no date range".
    if (!$month && !$fromInput && !$toInput) {
        $fromDate = null;
        $toDate   = null;
    }

    $fileName = 'client_conveyance_summary_' . now()->format('Ymd_His') . '.xlsx';

    return Excel::download(
        new ClientConveyanceSummaryExport($fromDate, $toDate, $sessionId, $clientId),
        $fileName
    );
}

    /**
     * CLIENT → EMPLOYEES (existing)
     */
    /**
     * CLIENT → EMPLOYEES (Drill-down with Persistence)
     */
    public function clientEmployees(Request $request, Client $client)
    {
        $activeSession = Session::active();
        
        // --- READ FILTERS ---
        $month     = $request->query('month');
        $fromInput = $request->query('from_date');
        $toInput   = $request->query('to_date');
        $sessionId = $request->query('session_id') ? (int)$request->query('session_id') : null;
        
        $monthStart = null;
        $monthEnd   = null;
        $currentMonthLabel = 'All Time';
        $applyDateFilter = false;

        // 1) DATE FILTERS
        if ($month) {
            try {
                $target = Carbon::createFromFormat('Y-m', $month)->startOfMonth();
                $monthStart = $target->copy()->startOfMonth();
                $monthEnd   = $target->copy()->endOfMonth();
                $currentMonthLabel = $target->format('F Y');
                $applyDateFilter = true;
            } catch (\Throwable $e) {}
        }
        elseif ($fromInput || $toInput) {
            if ($fromInput) $monthStart = Carbon::parse($fromInput)->startOfDay();
            if ($toInput)   $monthEnd   = Carbon::parse($toInput)->endOfDay();
            
            if ($monthStart && !$monthEnd) $currentMonthLabel = 'From ' . $monthStart->format('d M Y');
            elseif ($monthEnd && !$monthStart) $currentMonthLabel = 'Until ' . $monthEnd->format('d M Y');
            elseif ($monthStart && $monthEnd) $currentMonthLabel = $monthStart->format('d M Y') . ' – ' . $monthEnd->format('d M Y');
            
            $applyDateFilter = true;
        }
        elseif ($sessionId) {
            $session = Session::find($sessionId);
            if ($session) $currentMonthLabel = $session->name;
        }

        // --- QUERY ---
        $q = Conveyance::with(['client', 'user'])
            ->where('client_id', $client->id)
            ->where('status', 'submitted');

        $fromDate = $monthStart ? $monthStart->toDateString() : null;
        $toDate   = $monthEnd ? $monthEnd->toDateString() : null;

        if ($applyDateFilter) {
            if ($fromDate && $toDate) {
                $q->whereBetween('date', [$fromDate, $toDate]);
            } elseif ($fromDate) {
                $q->where('date', '>=', $fromDate);
            } elseif ($toDate) {
                $q->where('date', '<=', $toDate);
            }
        }

        if ($sessionId) {
            $q->where('session_id', $sessionId);
        }

        // Ordered by employee, then date
        $rows = $q->orderBy('date', 'asc')->orderBy('id', 'asc')->get();

        $employeeGroups = $rows->groupBy('user_id');

        $totalAmount = $rows->sum(function ($c) {
            $onward = (float) $c->amount;
            if ($c->is_return) {
                $return = $c->return_amount !== null ? (float) $c->return_amount : $onward;
                return $onward + $return;
            }
            return $onward;
        });

        $totalEntries  = $rows->count();
        $employeeCount = $employeeGroups->count();

        // Pass filters back to view so "Back" button can use them
        return view('admin.conveyance.client_employees', compact(
            'client',
            'activeSession',
            'currentMonthLabel',
            'monthStart',
            'monthEnd',
            'rows',
            'employeeGroups',
            'totalAmount',
            'totalEntries',
            'employeeCount',
            
            // Filters for persistence
            'month',
            'fromInput',
            'toInput',
            'sessionId'
        ));
    }


    /**
     * 🔁 Shared builder for Employee Master data (now with filters)
     */
    protected function buildEmployeeMasterData(Request $request): array
    {
        $activeSession = Session::active();
        $today = Carbon::today();

        // --- READ FILTERS FROM REQUEST ---
        $monthInput = $request->input('month');        // format: Y-m (e.g. 2025-11)
        $fromInput  = $request->input('from_date');    // format: Y-m-d
        $toInput    = $request->input('to_date');      // format: Y-m-d
        $nameInput  = trim((string) $request->input('name', ''));

        // --- DETERMINE DATE RANGE ---
        if ($fromInput && $toInput) {
            // Custom from–to range
            $monthStart = Carbon::parse($fromInput)->startOfDay();
            $monthEnd   = Carbon::parse($toInput)->endOfDay();
            $currentMonthLabel = $monthStart->format('d M Y') . ' – ' . $monthEnd->format('d M Y');
        } elseif ($monthInput) {
            // Specific month from dropdown
            $targetMonth = Carbon::createFromFormat('Y-m', $monthInput);
            $monthStart  = $targetMonth->copy()->startOfMonth();
            $monthEnd    = $targetMonth->copy()->endOfMonth();
            $currentMonthLabel = $targetMonth->format('F Y');
        } else {
            // Default logic: previous month if <=10th, otherwise current month
            if ($today->day <= 10) {
                $targetMonth = $today->copy()->subMonthNoOverflow();
            } else {
                $targetMonth = $today->copy();
            }

            $monthStart = $targetMonth->copy()->startOfMonth();
            $monthEnd   = $targetMonth->copy()->endOfMonth();
            $currentMonthLabel = $targetMonth->format('F Y');
        }

        // --- BUILD MONTH DROPDOWN OPTIONS (last 12 months) ---
        $months = [];
        $cursor = Carbon::today()->startOfMonth();
        for ($i = 0; $i < 12; $i++) {
            $months[] = [
                'value' => $cursor->format('Y-m'),
                'label' => $cursor->format('F Y'),
            ];
            $cursor->subMonth();
        }

        // --- EMPLOYEES (optionally filtered by name) ---
        $employeesQuery = User::where('role', 'employee');

        if ($nameInput !== '') {
            $employeesQuery->where('name', 'like', "%{$nameInput}%");
        }

        $employees = $employeesQuery
            ->orderBy('name')
            ->get();

        $employeeIds = $employees->pluck('id')->all();

        // --- ALL SUBMITTED ROWS IN RANGE (filtered by employees too) ---
        $rowsQuery = Conveyance::whereBetween('date', [$monthStart, $monthEnd])
            ->where('status', 'submitted')
            ->orderBy('date', 'asc');

        if (!empty($employeeIds)) {
            $rowsQuery->whereIn('user_id', $employeeIds);
        }

        $rows = $rowsQuery->get();

        $data       = []; // [user_id][date] => ['amount'=>, 'is_return'=>, 'return_amount'=>]
        $totals     = []; // employee month totals
        $dayTotals  = []; // per-day total across all employees
        $grandTotal = 0;  // total of everything

        foreach ($rows as $row) {
            $uid     = $row->user_id;
            $dateKey = $row->date->toDateString();

            $onward = (float) $row->amount;
            $return = $row->is_return
                ? (float) ($row->return_amount ?? $onward)
                : 0.0;

            $effectiveTotal = $onward + $return;

            // per-employee total
            if (!isset($totals[$uid])) {
                $totals[$uid] = 0;
            }
            $totals[$uid] += $effectiveTotal;

            // per-day total
            if (!isset($dayTotals[$dateKey])) {
                $dayTotals[$dateKey] = 0;
            }
            $dayTotals[$dateKey] += $effectiveTotal;

            $grandTotal += $effectiveTotal;

            // per-day, per-employee bucket
            if (!isset($data[$uid])) {
                $data[$uid] = [];
            }
            if (!isset($data[$uid][$dateKey])) {
                $data[$uid][$dateKey] = [
                    'amount'        => 0,
                    'is_return'     => false,
                    'return_amount' => null,
                ];
            }

            $data[$uid][$dateKey]['amount'] += $effectiveTotal;

            // mark return-different flag
            if ($row->is_return && $row->return_amount !== null && (float) $row->return_amount !== $onward) {
                $data[$uid][$dateKey]['is_return']     = true;
                $data[$uid][$dateKey]['return_amount'] = $row->return_amount;
            }
        }

        // Filters array to reuse in Blade
        $filters = [
            'month'     => $monthInput,
            'from_date' => $fromInput,
            'to_date'   => $toInput,
            'name'      => $nameInput,
        ];

        return compact(
            'activeSession',
            'currentMonthLabel',
            'monthStart',
            'monthEnd',
            'employees',
            'data',
            'totals',
            'dayTotals',
            'grandTotal',
            'months',
            'filters'
        );
    }

    /**
     * EMPLOYEE MASTER – HTML Grid (with filter support)
     */
    public function employeeMaster(Request $request)
    {
        $viewData = $this->buildEmployeeMasterData($request);

        return view('admin.conveyance.employee_master', $viewData);
    }

    /**
     * EMPLOYEE MASTER – Excel Export (respects same filters)
     */
    public function employeeMasterExport(Request $request)
    {
        $viewData = $this->buildEmployeeMasterData($request);

        $export   = new EmployeeMasterExport($viewData, $viewData['currentMonthLabel']);
        $fileName = 'employee-master-' . str_replace(' ', '-', strtolower($viewData['currentMonthLabel'])) . '.xlsx';

        return Excel::download($export, $fileName);
    }
    /**
     * EXPORT: Client Employees SUMMARY (Single Sheet)
     */
    public function clientEmployeesExportSummary(Request $request, Client $client)
    {
        // Reuse logic to determine dates
        list($monthStart, $monthEnd, $label, $sessionId) = $this->parseFilters($request);
        
        $s = $monthStart ?? Carbon::create(2000, 1, 1);
        $e = $monthEnd   ?? Carbon::now()->addYears(10);
        $l = $label;

        return Excel::download(
            new \App\Exports\ClientEmployeeConveyanceExport($client, $s, $e, $l),
            'CONVEYANCE_SUMMARY_' . Str::slug($client->name) . '_' . date('Ymd_His') . '.xlsx'
        );
    }

    /**
     * EXPORT: Client Employees DETAILED (Multi-Sheet: Day-wise per Employee)
     */
    public function clientEmployeesExportDetailed(Request $request, Client $client)
    {
        list($monthStart, $monthEnd, $label, $sessionId) = $this->parseFilters($request);

        return Excel::download(
            new \App\Exports\ClientEmployeeDetailedExport($client, $monthStart, $monthEnd, $label, $sessionId),
            'CONVEYANCE_DETAILED_' . Str::slug($client->name) . '_' . date('Ymd_His') . '.xlsx'
        );
    }

    /**
     * Helper to parse filters from request (DRY)
     */
    private function parseFilters(Request $request): array
    {
        $month     = $request->query('month');
        $fromInput = $request->query('from_date');
        $toInput   = $request->query('to_date');
        $sessionId = $request->query('session_id') ? (int)$request->query('session_id') : null;

        $monthStart = null;
        $monthEnd   = null;
        $label      = 'All Time';

        if ($month) {
            try {
                $target = Carbon::createFromFormat('Y-m', $month)->startOfMonth();
                $monthStart = $target->copy()->startOfMonth();
                $monthEnd   = $target->copy()->endOfMonth();
                $label = $target->format('F Y');
            } catch (\Throwable $e) {}
        } elseif ($fromInput || $toInput) {
            if ($fromInput) $monthStart = Carbon::parse($fromInput)->startOfDay();
            if ($toInput)   $monthEnd   = Carbon::parse($toInput)->endOfDay();
            
            if ($monthStart && !$monthEnd) $label = 'From ' . $monthStart->format('d M Y');
            elseif ($monthEnd && !$monthStart) $label = 'Until ' . $monthEnd->format('d M Y');
            elseif ($monthStart && $monthEnd) $label = $monthStart->format('d M Y') . ' – ' . $monthEnd->format('d M Y');
        } elseif ($sessionId) {
            $session = Session::find($sessionId);
            if ($session) $label = $session->name;
        }

        return [$monthStart, $monthEnd, $label, $sessionId];
    }
}
