<?php

namespace App\Http\Controllers\Employee;

use App\Http\Controllers\Controller;
use App\Models\Client;
use App\Models\Conveyance;
use App\Models\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use App\Models\ClientRequest;
use Illuminate\Support\Facades\Mail;
use App\Mail\NewClientRequestMail;
use Illuminate\Support\Facades\Log;


class ConveyanceController extends Controller
{
    /**
     * Employee – list current month conveyances (view & correction).
     */
    /**
     * Employee – Current Active Month View
     */
    public function index()
    {
        $user = Auth::user();
        $today = Carbon::today();

        // 1. Determine Window
        if ($today->day <= 10) {
            $currentWindowMonth = $today->copy()->subMonthNoOverflow();
        } else {
            $currentWindowMonth = $today->copy();
        }

        $cutoffDate = $currentWindowMonth->copy()->addMonthNoOverflow()->startOfMonth()->addDays(9);
        $monthStart = $currentWindowMonth->copy()->startOfMonth();
        $monthEnd = $currentWindowMonth->copy()->endOfMonth();
        $currentMonthLabel = $currentWindowMonth->format('F Y');

        // 2. Fetch Conveyances for this specific CURRENT window
        $conveyances = Conveyance::with('client')
            ->where('user_id', $user->id)
            ->whereBetween('date', [$monthStart, $monthEnd])
            ->orderBy('date', 'desc')
            ->orderBy('id', 'desc')
            ->get();

        $totals = [
            'submitted' => $conveyances->where('status', 'submitted')->sum(fn($c) => $c->total_amount),
            'draft' => $conveyances->where('status', 'draft')->sum(fn($c) => $c->total_amount),
        ];

        return view('employee.conveyance.index', compact(
            'today',
            'cutoffDate',
            'monthStart',
            'monthEnd',
            'currentMonthLabel',
            'conveyances',
            'totals'
        ));
    }

    /**
     * Employee – History Listing
     */
    public function history(Request $request)
    {
        $user = Auth::user();
        $today = Carbon::today();

        // 1. Get Sessions for dropdown
        $sessions = Session::orderBy('start_date', 'desc')->get();

        // 2. Determine Target Session
        // Default to active session if not provided
        $targetSessionId = $request->input('session_id');

        if ($targetSessionId) {
            $currentSession = $sessions->firstWhere('id', $targetSessionId);
        } else {
            $currentSession = $sessions->firstWhere('is_active', true);
        }

        // Fallback if no active session found (rare)
        if (!$currentSession) {
            $currentSession = $sessions->first();
        }

        // Determine current window to label it or exclude it if needed
        if ($today->day <= 10) {
            $currentWindowMonth = $today->copy()->subMonthNoOverflow();
        } else {
            $currentWindowMonth = $today->copy();
        }
        $currentMonthKey = $currentWindowMonth->format('Y-m');

        // Fetch submitted months for history filtered by SESSION
        $query = Conveyance::where('user_id', $user->id)
            ->where('status', 'submitted');

        if ($currentSession) {
            $query->where('session_id', $currentSession->id);
        }

        $historySummary = $query->select('date', 'amount', 'return_amount', 'is_return', 'status')
            ->get()
            ->groupBy(function ($c) {
                return $c->date->format('Y-m');
            })
            ->map(function ($rows, $ym) use ($currentMonthKey) {
                return [
                    'month_key' => $ym,
                    'month_label' => Carbon::createFromFormat('Y-m', $ym)->format('F Y'),
                    'total' => $rows->sum(fn($c) => $c->total_amount),
                    'is_current' => ($ym === $currentMonthKey)
                ];
            })
            ->sortByDesc('month_key');

        return view('employee.conveyance.history', compact('historySummary', 'sessions', 'currentSession'));
    }

    public function showMonth($month)
    {
        $user = Auth::user();
        $today = Carbon::today();

        try {
            $targetMonth = Carbon::createFromFormat('Y-m', $month)->startOfMonth();
        } catch (\Exception $e) {
            return redirect()->route('employee.conveyance.index')
                ->with('error', 'Invalid month format.');
        }

        // Determine Current Window (for Edit/Draft logic)
        if ($today->day <= 10) {
            $currentWindowMonth = $today->copy()->subMonthNoOverflow();
        } else {
            $currentWindowMonth = $today->copy();
        }
        $cutoffDate = $currentWindowMonth->copy()->addMonthNoOverflow()->startOfMonth()->addDays(9);

        // Check if viewing current window or past
        $isCurrentWindow = $targetMonth->isSameMonth($currentWindowMonth);

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

        // Fetch Conveyances
        $conveyances = Conveyance::with('client')
            ->where('user_id', $user->id)
            ->whereBetween('date', [$monthStart, $monthEnd])
            ->orderBy('date', 'desc')
            ->orderBy('id', 'desc')
            ->get();

        $monthTotalSubmitted = $conveyances
            ->where('status', 'submitted')
            ->sum(fn($c) => $c->total_amount);

        $monthTotalDraft = $conveyances
            ->where('status', 'draft')
            ->sum(fn($c) => $c->total_amount);

        // Re-fetch history for sidebar navigation
        $historySummary = Conveyance::where('user_id', $user->id)
            ->where('status', 'submitted')
            ->select('date', 'amount', 'return_amount', 'is_return', 'status')
            ->get()
            ->groupBy(function ($c) {
                return $c->date->format('Y-m');
            })
            ->map(function ($rows, $ym) {
                return [
                    'month_key' => $ym,
                    'month_label' => Carbon::createFromFormat('Y-m', $ym)->format('F Y'),
                    'total' => $rows->sum(fn($c) => $c->total_amount)
                ];
            })
            ->sortByDesc('month_key');


        return view('employee.conveyance.view', compact(
            'today',
            'cutoffDate',
            'targetMonth',
            'monthStart',
            'monthEnd',
            'currentMonthLabel',
            'isCurrentWindow',
            'conveyances',
            'monthTotalSubmitted',
            'monthTotalDraft',
            'historySummary'
        ));
    }


    /**
     * Show add conveyance sheet for employee.
     */
    public function create()
    {
        $user = Auth::user();

        $activeSession = Session::active();
        if (!$activeSession) {
            abort(403, 'No active financial session found.');
        }

        $today = Carbon::today();

        if ($today->day <= 10) {
            $targetMonth = $today->copy()->subMonthNoOverflow();
        } else {
            $targetMonth = $today->copy();
        }

        $monthStart = $targetMonth->copy()->startOfMonth();
        $monthEnd = $targetMonth->copy()->endOfMonth();

        // Last date to submit this month's conveyance = 10th of NEXT month
        $cutoffDate = $targetMonth->copy()->addMonthNoOverflow()->startOfMonth()->addDays(9);

        $targetMonthLabel = $targetMonth->format('F Y');

        $clients = Client::where('is_active', true)->orderBy('name')->get();

        return view('employee.conveyance.create', [
            'activeSession' => $activeSession,
            'clients' => $clients,
            'targetMonthLabel' => $targetMonthLabel,
            'monthStart' => $monthStart,
            'monthEnd' => $monthEnd,
            'cutoffDate' => $cutoffDate,
        ]);
    }

    /**
     * Store conveyance rows (AJAX) – supports draft & final submit.
     */
    public function store(Request $request)
    {
        $user = Auth::user();

        $activeSession = Session::active();
        if (!$activeSession) {
            return $this->jsonError('No active financial session found.', 403);
        }

        $today = Carbon::today();

        if ($today->day <= 10) {
            $targetMonth = $today->copy()->subMonthNoOverflow();
        } else {
            $targetMonth = $today->copy();
        }

        $monthStart = $targetMonth->copy()->startOfMonth();
        $monthEnd = $targetMonth->copy()->endOfMonth();
        $cutoffDate = $targetMonth->copy()->addMonthNoOverflow()->startOfMonth()->addDays(9);

        if ($today->greaterThan($cutoffDate)) {
            return $this->jsonError('Conveyance submission window has closed for this month.');
        }

        $validator = Validator::make($request->all(), [
            'save_mode' => ['required', 'in:draft,final'],
            'rows' => ['required', 'array', 'min:1'],
            'rows.*.date' => ['required', 'date'],
            'rows.*.from' => ['required', 'string', 'max:255'],
            'rows.*.to' => ['required', 'string', 'max:255'],
            'rows.*.client_id' => ['required', 'exists:clients,id'],
            'rows.*.mode' => ['nullable', 'string', 'max:255'],
            'rows.*.amount' => ['required', 'numeric', 'min:0.1'],
            'rows.*.remarks' => ['nullable', 'string', 'max:255'],
            'rows.*.return' => ['nullable', 'boolean'],

            // NEW: these will be filled when user selects "different fare"
            'rows.*.return_amount' => ['nullable', 'numeric', 'min:0.1'],
            'rows.*.return_remarks' => ['nullable', 'string', 'max:255'],
        ]);

        $validator->after(function ($v) use ($monthStart, $monthEnd) {
            $rows = $v->getData()['rows'] ?? [];
            foreach ($rows as $index => $row) {
                if (empty($row['date']))
                    continue;

                $d = Carbon::parse($row['date']);

                if ($d->lessThan($monthStart) || $d->greaterThan($monthEnd)) {
                    $v->errors()->add(
                        "rows.$index.date",
                        'Date must be within ' . $monthStart->format('d M Y') . ' and ' . $monthEnd->format('d M Y')
                    );
                }
            }
        });

        if ($validator->fails()) {
            if ($request->expectsJson()) {
                return response()->json([
                    'status' => 'error',
                    'errors' => $validator->errors(),
                ], 422);
            }

            return redirect()->back()->withErrors($validator)->withInput();
        }

        $data = $validator->validated();
        $rows = $data['rows'];
        $saveMode = $data['save_mode'];
        $status = $saveMode === 'draft' ? 'draft' : 'submitted';

        DB::transaction(function () use ($rows, $user, $activeSession, $status) {
            $insert = [];

            foreach ($rows as $row) {
                $insert[] = [
                    'user_id' => $user->id,
                    'session_id' => $activeSession->id,
                    'date' => Carbon::parse($row['date'])->toDateString(),
                    'from_location' => $row['from'],
                    'to_location' => $row['to'],
                    'client_id' => $row['client_id'] ?? null,
                    'mode' => $row['mode'] ?? null,
                    'amount' => $row['amount'],
                    'remarks' => $row['remarks'] ?? null,

                    // NEW: return flags + fields
                    'is_return' => !empty($row['return']),
                    'return_amount' => isset($row['return_amount']) && $row['return_amount'] !== ''
                        ? $row['return_amount']
                        : null,
                    'return_remarks' => $row['return_remarks'] ?? null,

                    'status' => $status,
                    'created_at' => now(),
                    'updated_at' => now(),
                ];
            }

            Conveyance::insert($insert);
        });

        $msg = $status === 'draft'
            ? 'Draft saved successfully.'
            : 'Conveyance submitted successfully.';

        if ($request->expectsJson()) {
            return response()->json([
                'status' => 'ok',
                'message' => $msg,
                'saveMode' => $saveMode,
            ]);
        }

        return redirect()
            ->back()
            ->with('success', $msg);
    }

    /**
     * Show edit form for a single conveyance row (only if own + draft + within window).
     */
    public function edit(Conveyance $conveyance)
    {
        $user = Auth::user();

        if ($conveyance->user_id !== $user->id) {
            abort(403, 'You are not allowed to edit this entry.');
        }

        $activeSession = Session::active();
        if (!$activeSession) {
            abort(403, 'No active financial session found.');
        }

        $today = Carbon::today();

        if ($today->day <= 10) {
            $targetMonth = $today->copy()->subMonthNoOverflow();
        } else {
            $targetMonth = $today->copy();
        }

        $monthStart = $targetMonth->copy()->startOfMonth();
        $monthEnd = $targetMonth->copy()->endOfMonth();
        $cutoffDate = $targetMonth->copy()->addMonthNoOverflow()->startOfMonth()->addDays(9);
        $targetMonthLabel = $targetMonth->format('F Y');

        // Editing allowed only if:
        // - row date is within current target month
        // - today <= cutoff
        // - (Status check relaxed: allow draft OR submitted if within window)
        if (
            $conveyance->date->lt($monthStart) ||
            $conveyance->date->gt($monthEnd) ||
            $today->gt($cutoffDate)
        ) {
            return redirect()
                ->route('employee.conveyance.index')
                ->withErrors(['error' => 'This entry can no longer be edited.']);
        }

        $clients = Client::where('is_active', true)->orderBy('name')->get();

        return view('employee.conveyance.edit', [
            'activeSession' => $activeSession,
            'conveyance' => $conveyance,
            'clients' => $clients,
            'targetMonthLabel' => $targetMonthLabel,
            'monthStart' => $monthStart,
            'monthEnd' => $monthEnd,
            'cutoffDate' => $cutoffDate,
        ]);
    }

    /**
     * Update a single conveyance row.
     */
    public function update(Request $request, Conveyance $conveyance)
    {
        $user = Auth::user();

        if ($conveyance->user_id !== $user->id) {
            abort(403, 'You are not allowed to update this entry.');
        }

        $activeSession = Session::active();
        if (!$activeSession) {
            return redirect()->route('employee.conveyance.index')
                ->withErrors(['error' => 'No active financial session found.']);
        }

        $today = Carbon::today();

        if ($today->day <= 10) {
            $targetMonth = $today->copy()->subMonthNoOverflow();
        } else {
            $targetMonth = $today->copy();
        }

        $monthStart = $targetMonth->copy()->startOfMonth();
        $monthEnd = $targetMonth->copy()->endOfMonth();
        $cutoffDate = $targetMonth->copy()->addMonthNoOverflow()->startOfMonth()->addDays(9);

        if (
            $conveyance->date->lt($monthStart) ||
            $conveyance->date->gt($monthEnd) ||
            $today->gt($cutoffDate)
        ) {
            return redirect()->route('employee.conveyance.index')
                ->withErrors(['error' => 'This entry can no longer be edited.']);
        }

        $data = $request->validate([
            'date' => ['required', 'date'],
            'from' => ['required', 'string', 'max:255'],
            'to' => ['required', 'string', 'max:255'],
            'client_id' => ['required', 'exists:clients,id'],
            'mode' => ['nullable', 'string', 'max:255'],
            'amount' => ['required', 'numeric', 'min:0.1'],
            'remarks' => ['nullable', 'string', 'max:255'],
            'is_return' => ['nullable', 'boolean'],
            'update_mode' => ['required', 'in:draft,final'],

            // NEW
            'return_amount' => ['nullable', 'numeric', 'min:0.1'],
            'return_remarks' => ['nullable', 'string', 'max:255'],
        ]);

        $newDate = Carbon::parse($data['date']);
        if ($newDate->lt($monthStart) || $newDate->gt($monthEnd)) {
            return back()
                ->withErrors(['date' => 'Date must be within ' . $monthStart->format('d M Y') . ' and ' . $monthEnd->format('d M Y')])
                ->withInput();
        }

        // Decide new status
        $newStatus = $conveyance->status;

        // If user explicitly clicks "Submit (Final)", status becomes submitted
        if ($data['update_mode'] === 'final') {
            $newStatus = 'submitted';
        }
        // If user clicks "Save Draft", status becomes draft (even if it was submitted before)
        elseif ($data['update_mode'] === 'draft') {
            $newStatus = 'draft';
        }

        $conveyance->update([
            'date' => $newDate->toDateString(),
            'from_location' => $data['from'],
            'to_location' => $data['to'],
            'client_id' => $data['client_id'] ?? null,
            'mode' => $data['mode'] ?? null,
            'amount' => $data['amount'],
            'remarks' => $data['remarks'] ?? null,

            'is_return' => !empty($data['is_return']),
            'return_amount' => isset($data['return_amount']) && $data['return_amount'] !== ''
                ? $data['return_amount']
                : null,
            'return_remarks' => $data['return_remarks'] ?? null,

            'status' => $newStatus,
        ]);

        $msg = $newStatus === 'submitted'
            ? 'Entry updated and submitted successfully.'
            : 'Draft updated successfully.';

        return redirect()
            ->route('employee.conveyance.index')
            ->with('success', $msg);
    }


    /**
     * Delete a conveyance row (only draft + within window).
     */
    public function destroy(Conveyance $conveyance)
    {
        $user = Auth::user();

        if ($conveyance->user_id !== $user->id) {
            abort(403, 'You are not allowed to delete this entry.');
        }

        $today = Carbon::today();

        if ($today->day <= 10) {
            $targetMonth = $today->copy()->subMonthNoOverflow();
        } else {
            $targetMonth = $today->copy();
        }

        $monthStart = $targetMonth->copy()->startOfMonth();
        $monthEnd = $targetMonth->copy()->endOfMonth();
        $cutoffDate = $targetMonth->copy()->addMonthNoOverflow()->startOfMonth()->addDays(9);

        // ✅ We removed the "status !== draft" check → now both draft + submitted can be deleted
        if (
            $conveyance->date->lt($monthStart) ||
            $conveyance->date->gt($monthEnd) ||
            $today->gt($cutoffDate)
        ) {
            return redirect()->route('employee.conveyance.index')
                ->withErrors(['error' => 'This entry can no longer be deleted.']);
        }

        $conveyance->delete();

        return redirect()
            ->route('employee.conveyance.index')
            ->with('success', 'Entry deleted.');
    }


    /**
     * Submit a single conveyance row from index (draft → submitted).
     */
    public function submitRow(Conveyance $conveyance)
    {
        $user = Auth::user();

        if ($conveyance->user_id !== $user->id) {
            abort(403, 'You are not allowed to submit this entry.');
        }

        $activeSession = Session::active();
        if (!$activeSession) {
            return redirect()->route('employee.conveyance.index')
                ->withErrors(['error' => 'No active financial session found.']);
        }

        $today = Carbon::today();

        if ($today->day <= 10) {
            $targetMonth = $today->copy()->subMonthNoOverflow();
        } else {
            $targetMonth = $today->copy();
        }

        $monthStart = $targetMonth->copy()->startOfMonth();
        $monthEnd = $targetMonth->copy()->endOfMonth();
        $cutoffDate = $targetMonth->copy()->addMonthNoOverflow()->startOfMonth()->addDays(9);

        if (
            $conveyance->date->lt($monthStart) ||
            $conveyance->date->gt($monthEnd) ||
            $today->gt($cutoffDate)
        ) {
            return redirect()->route('employee.conveyance.index')
                ->withErrors(['error' => 'This entry can no longer be submitted.']);
        }

        if ($conveyance->status === 'submitted') {
            return redirect()->route('employee.conveyance.index')
                ->with('success', 'This entry is already submitted.');
        }

        $conveyance->update([
            'status' => 'submitted',
            'updated_at' => now(),
        ]);

        return redirect()
            ->route('employee.conveyance.index')
            ->with('success', 'Entry submitted successfully.');
    }
    /**
     * Submit all draft entries of current claim month for this employee.
     */
    public function submitAllDraft()
    {
        $user = Auth::user();

        $activeSession = Session::active();
        if (!$activeSession) {
            return redirect()->route('employee.conveyance.index')
                ->withErrors(['error' => 'No active financial session found.']);
        }

        $today = Carbon::today();

        if ($today->day <= 10) {
            $targetMonth = $today->copy()->subMonthNoOverflow();
        } else {
            $targetMonth = $today->copy();
        }

        $monthStart = $targetMonth->copy()->startOfMonth();
        $monthEnd = $targetMonth->copy()->endOfMonth();
        $cutoffDate = $targetMonth->copy()->addMonthNoOverflow()->startOfMonth()->addDays(9);

        if ($today->gt($cutoffDate)) {
            return redirect()->route('employee.conveyance.index')
                ->withErrors(['error' => 'Conveyance submission window has closed for this month.']);
        }

        // Submit all draft rows of this month for this user
        $affected = Conveyance::where('user_id', $user->id)
            ->whereBetween('date', [$monthStart, $monthEnd])
            ->where('status', 'draft')
            ->update([
                'status' => 'submitted',
                'updated_at' => now(),
            ]);

        if ($affected === 0) {
            return redirect()->route('employee.conveyance.index')
                ->with('success', 'No draft entries found to submit.');
        }

        return redirect()
            ->route('employee.conveyance.index')
            ->with('success', "Submitted {$affected} draft entr" . ($affected > 1 ? 'ies' : 'y') . ' successfully.');
    }


    protected function jsonError(string $message, int $code = 422)
    {
        if (request()->expectsJson()) {
            return response()->json([
                'status' => 'error',
                'message' => $message,
            ], $code);
        }

        return redirect()->back()->withErrors(['error' => $message]);
    }



    /**
     * Store a new client request from employee (AJAX).
     */
    public function storeClientRequest(Request $request)
    {
        $user = Auth::user();

        $data = $request->validate([
            'client_name' => ['required', 'string', 'max:255'],
            'notes' => ['nullable', 'string', 'max:2000'],
        ]);

        $clientRequest = ClientRequest::create([
            'user_id' => $user->id,
            'client_name' => $data['client_name'],
            'notes' => $data['notes'] ?? null,
            'status' => 'pending',
        ]);

        // Send email to admin(s)
        $adminEmail = config('mail.admin_address', env('ADMIN_EMAIL'));

        if ($adminEmail) {
            try {
                Mail::to($adminEmail)->send(new NewClientRequestMail($clientRequest));
            } catch (\Throwable $e) {
                // Don't break the UI if mail fails – just log
                Log::error('Failed to send NewClientRequestMail', [
                    'error' => $e->getMessage(),
                ]);
            }
        }

        if ($request->expectsJson()) {
            return response()->json([
                'status' => 'ok',
                'message' => 'Client request submitted to Admin.',
            ]);
        }

        return redirect()->back()->with('success', 'Client request submitted to Admin.');
    }



}
