<?php

namespace App\Http\Controllers;

use App\Models\Elevator;
use App\Models\MaintenanceLog;
use App\Models\MaintenanceSchedule;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class MaintenanceLogController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
        $this->middleware('permission:view-maintenance-log')->only(['index', 'show']);
        $this->middleware('permission:create-maintenance-log')->only(['create', 'store']);
        $this->middleware('permission:edit-maintenance-log')->only(['edit', 'update']);
        $this->middleware('permission:delete-maintenance-log')->only('destroy');
        $this->middleware('permission:export-maintenance-log')->only('export');
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $query = MaintenanceLog::with(['elevator', 'technician', 'maintenanceSchedule']);

        // Filter by status if provided
        if ($request->has('status') && $request->status != '') {
            $query->where('status', $request->status);
        }

        // Filter by date range if provided
        if ($request->has('start_date') && $request->start_date != '') {
            $query->where('maintenance_date', '>=', $request->start_date);
        }
        if ($request->has('end_date') && $request->end_date != '') {
            $query->where('maintenance_date', '<=', $request->end_date);
        }

        // Filter by elevator if provided
        if ($request->has('elevator_id') && $request->elevator_id != '') {
            $query->where('elevator_id', $request->elevator_id);
        }

        // Filter by technician if provided
        if ($request->has('technician_id') && $request->technician_id != '') {
            $query->where('technician_id', $request->technician_id);
        }

        $logs = $query->orderBy('maintenance_date', 'desc')->paginate(15);

        // Get data for filters
        $elevators = Elevator::select('id', 'model', 'serial_number')->get();
        $technicians = User::whereHas('roles', function ($query) {
            $query->where('slug', 'technician');
        })->get();

        return view('maintenance.logs.index', compact('logs', 'elevators', 'technicians'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create(Request $request)
    {
        $scheduleId = $request->schedule_id ?? null;
        $schedule = null;

        if ($scheduleId) {
            $schedule = MaintenanceSchedule::with('elevator')->findOrFail($scheduleId);
        }

        $elevators = Elevator::select('id', 'model', 'serial_number')->get();
        $technicians = User::whereHas('roles', function ($query) {
            $query->where('slug', 'technician');
        })->get();
        $schedules = MaintenanceSchedule::where('status', 'scheduled')->get();

        return view('maintenance.logs.create', compact('elevators', 'technicians', 'schedules', 'schedule'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'maintenance_schedule_id' => 'nullable|exists:maintenance_schedules,id',
            'elevator_id' => 'required|exists:elevators,id',
            'maintenance_date' => 'required|date',
            'technician_id' => 'required|exists:users,id',
            'status' => 'required|in:completed,partial,failed',
            'issues_found' => 'nullable|string',
            'actions_taken' => 'nullable|string',
            'parts_replaced' => 'nullable|string',
            'next_maintenance_recommendation' => 'nullable|string',
        ]);

        $log = new MaintenanceLog();
        $log->maintenance_schedule_id = $request->maintenance_schedule_id;
        $log->elevator_id = $request->elevator_id;
        $log->maintenance_date = $request->maintenance_date;
        $log->technician_id = $request->technician_id;
        $log->status = $request->status;
        $log->issues_found = $request->issues_found;
        $log->actions_taken = $request->actions_taken;
        $log->parts_replaced = $request->parts_replaced;
        $log->next_maintenance_recommendation = $request->next_maintenance_recommendation;
        $log->company_id = Auth::user()->company_id;
        $log->save();

        // Update the maintenance schedule status if it exists
        if ($request->maintenance_schedule_id) {
            $schedule = MaintenanceSchedule::findOrFail($request->maintenance_schedule_id);
            $schedule->status = 'completed';
            $schedule->save();
        }

        return redirect()->route('maintenance-logs.index')
            ->with('success', 'تم إنشاء سجل الصيانة بنجاح.');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $log = MaintenanceLog::with(['elevator', 'technician', 'maintenanceSchedule'])
            ->findOrFail($id);

        return view('maintenance.logs.show', compact('log'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $log = MaintenanceLog::findOrFail($id);
        $elevators = Elevator::select('id', 'model', 'serial_number')->get();
        $technicians = User::whereHas('roles', function ($query) {
            $query->where('slug', 'technician');
        })->get();
        $schedules = MaintenanceSchedule::where('status', 'scheduled')
            ->orWhere('id', $log->maintenance_schedule_id)
            ->get();

        return view('maintenance.logs.edit', compact('log', 'elevators', 'technicians', 'schedules'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $request->validate([
            'maintenance_schedule_id' => 'nullable|exists:maintenance_schedules,id',
            'elevator_id' => 'required|exists:elevators,id',
            'maintenance_date' => 'required|date',
            'technician_id' => 'required|exists:users,id',
            'status' => 'required|in:completed,partial,failed',
            'issues_found' => 'nullable|string',
            'actions_taken' => 'nullable|string',
            'parts_replaced' => 'nullable|string',
            'next_maintenance_recommendation' => 'nullable|string',
        ]);

        $log = MaintenanceLog::findOrFail($id);

        // If the schedule is changing, update the old schedule status
        if ($log->maintenance_schedule_id && $log->maintenance_schedule_id != $request->maintenance_schedule_id) {
            $oldSchedule = MaintenanceSchedule::find($log->maintenance_schedule_id);
            if ($oldSchedule) {
                $oldSchedule->status = 'scheduled';
                $oldSchedule->save();
            }
        }

        $log->maintenance_schedule_id = $request->maintenance_schedule_id;
        $log->elevator_id = $request->elevator_id;
        $log->maintenance_date = $request->maintenance_date;
        $log->technician_id = $request->technician_id;
        $log->status = $request->status;
        $log->issues_found = $request->issues_found;
        $log->actions_taken = $request->actions_taken;
        $log->parts_replaced = $request->parts_replaced;
        $log->next_maintenance_recommendation = $request->next_maintenance_recommendation;
        $log->save();

        // Update the new maintenance schedule status if it exists
        if ($request->maintenance_schedule_id) {
            $schedule = MaintenanceSchedule::findOrFail($request->maintenance_schedule_id);
            $schedule->status = 'completed';
            $schedule->save();
        }

        return redirect()->route('maintenance-logs.index')
            ->with('success', 'تم تحديث سجل الصيانة بنجاح.');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $log = MaintenanceLog::findOrFail($id);

        // Reset the schedule status if it exists
        if ($log->maintenance_schedule_id) {
            $schedule = MaintenanceSchedule::find($log->maintenance_schedule_id);
            if ($schedule) {
                $schedule->status = 'scheduled';
                $schedule->save();
            }
        }

        $log->delete();

        return redirect()->route('maintenance-logs.index')
            ->with('success', 'تم حذف سجل الصيانة بنجاح.');
    }

    /**
     * Get elevator maintenance history.
     *
     * @param  int  $elevatorId
     * @return \Illuminate\Http\Response
     */
    public function elevatorHistory($elevatorId)
    {
        $elevator = Elevator::findOrFail($elevatorId);
        $logs = MaintenanceLog::where('elevator_id', $elevatorId)
            ->with(['technician'])
            ->orderBy('maintenance_date', 'desc')
            ->paginate(15);

        return view('maintenance.logs.elevator_history', compact('elevator', 'logs'));
    }

    /**
     * Export maintenance logs to Excel/CSV.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function export(Request $request)
    {
        $query = MaintenanceLog::with(['elevator', 'technician', 'maintenanceSchedule']);

        // Apply filters
        if ($request->has('status') && $request->status != '') {
            $query->where('status', $request->status);
        }
        if ($request->has('start_date') && $request->start_date != '') {
            $query->where('maintenance_date', '>=', $request->start_date);
        }
        if ($request->has('end_date') && $request->end_date != '') {
            $query->where('maintenance_date', '<=', $request->end_date);
        }
        if ($request->has('elevator_id') && $request->elevator_id != '') {
            $query->where('elevator_id', $request->elevator_id);
        }
        if ($request->has('technician_id') && $request->technician_id != '') {
            $query->where('technician_id', $request->technician_id);
        }

        $logs = $query->orderBy('maintenance_date', 'desc')->get();

        // Create a filename
        $filename = 'maintenance_logs_' . date('Y-m-d') . '.csv';

        // Set headers for download
        $headers = [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="' . $filename . '"',
        ];

        // Create a callback to stream the CSV
        $callback = function () use ($logs) {
            $file = fopen('php://output', 'w');

            // Add UTF-8 BOM for proper Arabic display in Excel
            fprintf($file, chr(0xEF) . chr(0xBB) . chr(0xBF));

            // Add headers
            fputcsv($file, [
                'رقم السجل',
                'المصعد',
                'تاريخ الصيانة',
                'الفني',
                'الحالة',
                'المشاكل المكتشفة',
                'الإجراءات المتخذة',
                'القطع المستبدلة',
                'توصيات الصيانة القادمة'
            ]);

            // Add data rows
            foreach ($logs as $log) {
                $status = '';
                if ($log->status == 'completed') {
                    $status = 'مكتمل';
                } elseif ($log->status == 'partial') {
                    $status = 'جزئي';
                } elseif ($log->status == 'failed') {
                    $status = 'فشل';
                }

                fputcsv($file, [
                    $log->id,
                    $log->elevator ? $log->elevator->model . ' (' . $log->elevator->serial_number . ')' : 'غير محدد',
                    $log->maintenance_date->format('Y-m-d'),
                    $log->technician ? $log->technician->name : 'غير محدد',
                    $status,
                    $log->issues_found,
                    $log->actions_taken,
                    $log->parts_replaced,
                    $log->next_maintenance_recommendation
                ]);
            }

            fclose($file);
        };

        return response()->stream($callback, 200, $headers);
    }

    /**
     * Get maintenance logs by customer for invoice creation.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function byCustomer(Request $request)
    {
        $request->validate([
            'customer_id' => 'required|exists:customers,id',
        ]);

        $logs = MaintenanceLog::with(['elevator'])
            ->whereHas('elevator', function ($query) use ($request) {
                $query->where('customer_id', $request->customer_id);
            })
            ->where('status', 'completed')
            ->whereNull('invoice_id')
            ->orderBy('maintenance_date', 'desc')
            ->get();

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