<?php

namespace App\Http\Controllers;

use App\Models\TripReport;
use App\Models\Log;
use Illuminate\Http\Request;
use App\Traits\ApiResponse;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class TripReportController extends Controller
{
    use ApiResponse;

    /**
     * Store a newly created trip report.
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'description' => 'nullable|string',
            'start_date' => 'required|string',
            'end_date' => 'nullable|string',
            'visibility' => 'required|in:private,friends,public',
            'logs' => 'required|array|min:1',
            'logs.*.mountain_id' => 'required|integer|exists:mountains,id',
            'logs.*.done' => 'required|integer|in:0,1',
            'logs.*.date_climbed' => 'required|string',
            'logs.*.description' => 'nullable|string',
        ]);

        DB::beginTransaction();
        try {
            // Convert dates from DD/MM/YYYY format to Y-m-d for database
            $startDate = Carbon::createFromFormat('d/m/Y', $validated['start_date'])->format('Y-m-d');
            $endDate = isset($validated['end_date']) && $validated['end_date'] 
                ? Carbon::createFromFormat('d/m/Y', $validated['end_date'])->format('Y-m-d')
                : null;

            // Create the trip report
            $tripReport = TripReport::create([
                'user_id' => auth()->id(),
                'description' => $validated['description'] ?? null,
                'start_date' => $startDate,
                'end_date' => $endDate,
                'visibility' => $validated['visibility'],
            ]);

            // Create logs for the trip report using createMany
            $logsData = array_map(function ($logData) {
                return [
                    'user_id' => auth()->id(),
                    'mountain_id' => $logData['mountain_id'],
                    'done' => $logData['done'],
                    'date_climbed' => $logData['date_climbed'],
                    'description' => $logData['description'] ?? null,
                ];
            }, $validated['logs']);

            $tripReport->logs()->createMany($logsData);

            DB::commit();

           
            return response()->json([
                'message' => 'Trip report created successfully'
            ], 201);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'message' => 'Failed to create trip report',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Display a listing of the user's trip reports.
     */
    public function index()
    {
        $tripReports = TripReport::where('user_id', auth()->id())
            ->with(['logs.mountain'])
            ->orderBy('created_at', 'desc')
            ->get();

        return response()->json($tripReports);
    }

    /**
     * Display the specified trip report.
     */
    public function show($id)
    {
        $tripReport = TripReport::where('user_id', auth()->id())
            ->with(['logs.mountain', 'user'])
            ->findOrFail($id);

        return response()->json($tripReport);
    }

    /**
     * Update the specified trip report.
     */
    public function update(Request $request, $id)
    {
        $tripReport = TripReport::where('user_id', auth()->id())->findOrFail($id);

        $validated = $request->validate([
            'description' => 'nullable|string',
            'start_date' => 'sometimes|required|string',
            'end_date' => 'nullable|string',
            'visibility' => 'sometimes|required|in:private,friends,public',
            'logs' => 'sometimes|required|array|min:1',
            'logs.*.mountain_id' => 'required|integer|exists:mountains,id',
            'logs.*.done' => 'required|integer|in:0,1',
            'logs.*.date_climbed' => 'required|string',
            'logs.*.description' => 'nullable|string',
        ]);

        DB::beginTransaction();
        try {
            // Update trip report
            $updateData = [
                'description' => $validated['description'] ?? $tripReport->description,
                'visibility' => $validated['visibility'] ?? $tripReport->visibility,
            ];

            // Convert dates from DD/MM/YYYY format to Y-m-d for database if provided
            if (isset($validated['start_date'])) {
                $updateData['start_date'] = Carbon::createFromFormat('d/m/Y', $validated['start_date'])->format('Y-m-d');
            }

            if (isset($validated['end_date'])) {
                $updateData['end_date'] = $validated['end_date']
                    ? Carbon::createFromFormat('d/m/Y', $validated['end_date'])->format('Y-m-d')
                    : null;
            }

            // Update trip report
            $tripReport->update($updateData);

            // Update logs if provided
            if (isset($validated['logs'])) {
                // Delete existing logs associated with this trip report
                $tripReport->logs()->delete();

                // Create new logs using createMany
                $logsData = array_map(function ($logData) {
                    return [
                        'user_id' => auth()->id(),
                        'mountain_id' => $logData['mountain_id'],
                        'done' => $logData['done'],
                        'date_climbed' => $logData['date_climbed'],
                        'description' => $logData['description'] ?? null,
                    ];
                }, $validated['logs']);

                $tripReport->logs()->createMany($logsData);
            }

            DB::commit();

            $tripReport->load(['logs.mountain']);

            // Format dates for response (DD/MM/YYYY)
            $responseData = $tripReport->toArray();
            $responseData['start_date'] = $tripReport->start_date->format('d/m/Y');
            $responseData['end_date'] = $tripReport->end_date ? $tripReport->end_date->format('d/m/Y') : null;

            return response()->json([
                'message' => 'Trip report updated successfully',
                'trip_report' => $responseData,
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'message' => 'Failed to update trip report',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Remove the specified trip report.
     */
    public function destroy($id)
    {
        $tripReport = TripReport::where('user_id', auth()->id())->findOrFail($id);
        
        DB::beginTransaction();
        try {
            // Unlink logs from trip report (set trip_report_id to null) but don't delete the logs
            $tripReport->logs()->update(['trip_report_id' => null]);
            
            // Delete the trip report
            $tripReport->delete();

            DB::commit();

            return response()->json([
                'message' => 'Trip report deleted successfully',
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'message' => 'Failed to delete trip report',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Get trip reports for friends (visibility: friends or public)
     */
    public function friends()
    {
        // This would require friendship logic - implement based on your friendship system
        // For now, return friends' trip reports with visibility 'friends' or 'public'
        $user = auth()->user();
        
        // Get friend IDs (this depends on your friendship implementation)
        // Example: $friendIds = $user->friends()->pluck('id');
        
        // Placeholder - implement based on your friendship model
        $tripReports = TripReport::whereIn('visibility', ['friends', 'public'])
            ->where('user_id', '!=', auth()->id())
            ->with(['logs.mountain', 'user'])
            ->orderBy('created_at', 'desc')
            ->get();

        return response()->json($tripReports);
    }

    /**
     * Get public trip reports for a specific mountain
     */
    public function forMountain($mountainId)
    {
        $tripReports = TripReport::where('visibility', 'public')
            ->whereHas('logs', function ($query) use ($mountainId) {
                $query->where('mountain_id', $mountainId);
            })
            ->with(['logs.mountain', 'user'])
            ->orderBy('created_at', 'desc')
            ->get();

        return response()->json($tripReports);
    }
}

