<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Conveyance;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\EmployeeConveyanceMonthSummaryExport;
use App\Exports\EmployeeConveyanceMonthFullExport;

class EmployeeMonthReportController extends Controller
{
    /**
     * Main page – employee + month comparison.
     */
    public function index(Request $request)
    {
        // All employees for dropdown
        $employees = User::where('role', 'employee')
            ->orderBy('name')
            ->get();

        // Months list – last 12 months including current
        $monthsOptions = [];
        $cursor = Carbon::today()->startOfMonth();
        for ($i = 0; $i < 12; $i++) {
            $key = $cursor->format('Y-m'); // e.g. 2025-01
            $monthsOptions[$key] = $cursor->format('F Y'); // January 2025
            $cursor->subMonthNoOverflow();
        }

        $monthsOptions = array_reverse($monthsOptions, true); // oldest → newest

        $selectedEmployeeId = $request->query('employee_id');
        $selectedMonthsKeys = (array) $request->query('months', []);

        // Simple validation
        $selectedEmployee = null;
        if ($selectedEmployeeId) {
            $selectedEmployee = User::where('role', 'employee')->find($selectedEmployeeId);
        }

        // Keep only valid months that exist in options
        $selectedMonthsKeys = array_values(array_filter(
            $selectedMonthsKeys,
            fn ($key) => isset($monthsOptions[$key])
        ));

        $monthsData = [];
        $maxDays    = 31;

        if ($selectedEmployee && !empty($selectedMonthsKeys)) {
            [$monthsData, $maxDays] = $this->buildEmployeeMonthData(
                $selectedEmployee->id,
                $selectedMonthsKeys
            );
        }

        return view('admin.conveyance.employee_month_report', [
            'employees'         => $employees,
            'monthsOptions'     => $monthsOptions,
            'selectedEmployee'  => $selectedEmployee,
            'selectedEmployeeId'=> $selectedEmployeeId,
            'selectedMonthsKeys'=> $selectedMonthsKeys,
            'monthsData'        => $monthsData,
            'maxDays'           => $maxDays,
        ]);
    }

    /**
     * Export only month summary grid.
     */
    public function exportSummary(Request $request)
    {
        [$selectedEmployee, $monthsData] = $this->prepareExportData($request);

        if (!$selectedEmployee || empty($monthsData)) {
            return back()->withErrors(['error' => 'Please select an employee and at least one month before exporting.']);
        }

        $fileName = 'conv-summary-' . $selectedEmployee->name . '-' . now()->format('Ymd_His') . '.xlsx';

        return Excel::download(
            new EmployeeConveyanceMonthSummaryExport($selectedEmployee, $monthsData),
            $fileName
        );
    }

    /**
     * Export month summary + full day-wise tables.
     */
    public function exportFull(Request $request)
    {
        [$selectedEmployee, $monthsData] = $this->prepareExportData($request);

        if (!$selectedEmployee || empty($monthsData)) {
            return back()->withErrors(['error' => 'Please select an employee and at least one month before exporting.']);
        }

        $fileName = 'conv-full-' . $selectedEmployee->name . '-' . now()->format('Ymd_His') . '.xlsx';

        return Excel::download(
            new EmployeeConveyanceMonthFullExport($selectedEmployee, $monthsData),
            $fileName
        );
    }

    /**
     * Shared helper for exports – reuse same logic as index.
     */
    protected function prepareExportData(Request $request): array
    {
        $employees = User::where('role', 'employee')->orderBy('name')->get();

        // Same months as index
        $monthsOptions = [];
        $cursor = Carbon::today()->startOfMonth();
        for ($i = 0; $i < 12; $i++) {
            $key = $cursor->format('Y-m');
            $monthsOptions[$key] = $cursor->format('F Y');
            $cursor->subMonthNoOverflow();
        }
        $monthsOptions = array_reverse($monthsOptions, true);

        $employeeId = $request->query('employee_id');
        $selectedEmployee = null;
        if ($employeeId) {
            $selectedEmployee = User::where('role', 'employee')->find($employeeId);
        }

        $selectedMonthsKeys = (array) $request->query('months', []);
        $selectedMonthsKeys = array_values(array_filter(
            $selectedMonthsKeys,
            fn ($key) => isset($monthsOptions[$key])
        ));

        $monthsData = [];
        if ($selectedEmployee && !empty($selectedMonthsKeys)) {
            [$monthsData, $maxDays] = $this->buildEmployeeMonthData(
                $selectedEmployee->id,
                $selectedMonthsKeys
            );
        }

        return [$selectedEmployee, $monthsData];
    }

    /**
     * Core logic: build month-wise + day-wise data for a single employee.
     *
     * @param int   $employeeId
     * @param array $monthKeys  e.g. ['2025-01', '2025-02']
     * @return array [monthsData, maxDays]
     */
    protected function buildEmployeeMonthData(int $employeeId, array $monthKeys): array
    {
        $monthsData = [];
        $maxDays = 0;

        foreach ($monthKeys as $key) {
            try {
                [$year, $month] = explode('-', $key);
                $start = Carbon::createFromDate((int)$year, (int)$month, 1)->startOfDay();
            } catch (\Throwable $e) {
                continue; // skip bad key
            }

            $end          = $start->copy()->endOfMonth();
            $daysInMonth  = $start->daysInMonth;
            $maxDays      = max($maxDays, $daysInMonth);

            // Fetch all submitted rows for that employee & month
            $rows = Conveyance::with('client')
                ->where('user_id', $employeeId)
                ->whereBetween('date', [$start, $end])
                ->where('status', 'submitted')
                ->orderBy('date')
                ->orderBy('id')
                ->get();

            // Build daily totals
            $daily = []; // date => [ 'total' => float, 'return_diff' => bool ]

            for ($day = 1; $day <= $daysInMonth; $day++) {
                $current = $start->copy()->day($day);
                $dateKey = $current->toDateString();

                $dayRows = $rows->filter(function ($row) use ($dateKey) {
                    return $row->date->toDateString() === $dateKey;
                });

                if ($dayRows->isEmpty()) {
                    continue;
                }

                $total = 0.0;
                $returnDiff = false;

                foreach ($dayRows as $c) {
                    $onward = (float) $c->amount;
                    $return = 0.0;

                    if ($c->is_return) {
                        $return = $c->return_amount !== null
                            ? (float) $c->return_amount
                            : $onward;

                        if (
                            $c->return_amount !== null &&
                            (float)$c->return_amount !== $onward
                        ) {
                            $returnDiff = true;
                        }
                    }

                    $total += $onward + $return;
                }

                $daily[$dateKey] = [
                    'total'       => $total,
                    'return_diff' => $returnDiff,
                ];
            }

            $monthsData[] = [
                'key'          => $key,
                'label'        => $start->format('F Y'),
                'start'        => $start,
                'end'          => $end,
                'days_in_month'=> $daysInMonth,
                'daily'        => $daily,
                'rows'         => $rows,
            ];
        }

        if ($maxDays === 0) {
            $maxDays = 31;
        }

        return [$monthsData, $maxDays];
    }
}
