<?php

namespace App\Http\Controllers;

use App\Models\Document;
use App\Models\Dossier;
use App\Models\ShockPoint;
use App\Models\TypeDocument;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ShockPointController extends Controller
{
    /**
     * SVG Zone names mapping (predefined zones)
     * Used to auto-create missing zones in database
     */
    private $svgZoneNames = [
        1 => 'Pare-chocs Avant',
        2 => 'Calandre',
        3 => 'Capot',
        4 => 'Toit',
        5 => 'Toit Ouvrant',
        6 => 'Coffre',
        7 => 'Pare-chocs Arrière',
        8 => 'Aile Avant Droite',
        9 => 'Roue Avant Droite',
        10 => 'Porte Avant Droite',
        11 => 'Porte Arrière Droite',
        12 => 'Aile Arrière Droite',
        13 => 'Roue Arrière Droite',
        14 => 'Feu Arrière Droit',
        15 => 'Vitre Avant Droite',
        16 => 'Vitre Arrière Droite',
        17 => 'Aile Avant Gauche',
        18 => 'Roue Avant Gauche',
        19 => 'Porte Avant Gauche',
        20 => 'Porte Arrière Gauche',
        21 => 'Aile Arrière Gauche',
        22 => 'Roue Arrière Gauche',
        23 => 'Feu Arrière Gauche',
        24 => 'Vitre Avant Gauche',
        25 => 'Vitre Arrière Gauche',
        26 => 'Phare Avant Gauche',
        27 => 'Phare Avant Droit',
        28 => 'Pare-brise',
        29 => 'Lunette Arrière',
        30 => 'Rétroviseur Droit',
        31 => 'Bas de Caisse Droit',
        32 => 'Bas de Caisse Gauche',
        33 => 'Plaque Immatriculation Avant',
        34 => 'Rétroviseur Gauche',
        35 => 'Plaque Immatriculation Arrière',
    ];

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $shockpoints = ShockPoint::all();
        return view('configuration.Types.point.index', compact('shockpoints'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create($id)
    {
        $dossier = Dossier::where('id', $id)->with('shockpoint')->first();
        
        if ($dossier->update != 0 && Auth::user()->role_id != 4 || $dossier->dossier_status_id == 3 && Auth::user()->role_id != 4) {
            return redirect()->route('Dossier.show', $dossier->id)->with('error', 'Dossier est interdit de le modifier Envoyer une demande a Admin ');
        }
        
        // Get all shock points from database for the sidebar
        $allShockPoints = ShockPoint::orderBy('point')->get();
        
        return view('dossiers.chock', compact('dossier', 'allShockPoints'));
    }

    /**
     * Store a newly created resource in storage.
     * AUTO-CREATES missing shock points in database
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $dossier = Dossier::whereId($request->dossier_id)->first();
        
        if (!$dossier) {
            return redirect()->back()->with('error', 'Dossier non trouvé');
        }
        
        if ($dossier->update != 0 && Auth::user()->role_id != 4 || $dossier->dossier_status_id == 3 && Auth::user()->role_id != 4) {
            return redirect()->route('Dossier.show', $dossier->id)->with('error', 'Dossier est interdit de le modifier Envoyer une demande a Admin ');
        }

        // Detach existing shock points
        $dossier->shockpoint()->detach();
        
        $createdPoints = [];
        $attachedCount = 0;
        
        // Process points (from SVG zones or existing database points)
        if ($request->has('points') && !empty($request->points)) {
            $points = array_filter(array_map("intval", explode(",", $request->points)));
            
            foreach ($points as $pointId) {
                if ($pointId <= 0) continue;
                
                // Try to find existing point
                $spoint = ShockPoint::find($pointId);
                
                // AUTO-CREATE if point doesn't exist in database
                if (!$spoint) {
                    $spoint = $this->createMissingPoint($pointId);
                    if ($spoint) {
                        $createdPoints[] = $spoint->point;
                    }
                }
                
                // Attach to dossier if point exists or was created
                if ($spoint) {
                    $dossier->shockpoint()->syncWithoutDetaching($spoint);
                    $attachedCount++;
                }
            }
        }
        
        // Process new custom points - create them in database then attach
        if ($request->has('custom_points') && !empty($request->custom_points)) {
            $customPoints = json_decode($request->custom_points, true);
            
            if (is_array($customPoints) && count($customPoints) > 0) {
                foreach ($customPoints as $pointName) {
                    $pointName = trim($pointName);
                    if (empty($pointName)) continue;
                    
                    // Check if point already exists (case-insensitive)
                    $existingPoint = ShockPoint::whereRaw('LOWER(point) = ?', [strtolower($pointName)])->first();
                    
                    if ($existingPoint) {
                        // Use existing point
                        $dossier->shockpoint()->syncWithoutDetaching($existingPoint);
                        $attachedCount++;
                    } else {
                        // Create new shock point in database
                        $newPoint = ShockPoint::create([
                            'point' => $pointName
                        ]);
                        
                        // Attach to dossier
                        $dossier->shockpoint()->syncWithoutDetaching($newPoint);
                        $createdPoints[] = $pointName;
                        $attachedCount++;
                        
                        Log::info("Created custom shock point: {$pointName} (ID: {$newPoint->id})");
                    }
                }
            }
        }
        
        // Save the SVG image
        if ($request->img) {
            $this->saveSvgImage($request->img, $dossier);
        }
        
        // Clear sidebar cache
        if (class_exists('\App\Services\SidebarCache')) {
            \App\Services\SidebarCache::clear();
        }
        
        // Build success message
        $message = "{$attachedCount} point(s) de choc enregistré(s)";
        if (!empty($createdPoints)) {
            $message .= ". Nouveaux points créés: " . implode(', ', $createdPoints);
        }
        
        return redirect()->route('Dossier.show', $dossier->id)->with('success', $message);
    }

    /**
     * Create a missing shock point in database
     * Uses predefined SVG zone names or generates a generic name
     *
     * @param int $pointId
     * @return ShockPoint|null
     */
    private function createMissingPoint($pointId)
    {
        try {
            // Get the name from SVG zones mapping or generate generic name
            $pointName = $this->svgZoneNames[$pointId] ?? 'Zone ' . $pointId;
            
            // Use insertOrIgnore to handle race conditions
            DB::table('shock_points')->insertOrIgnore([
                'id' => $pointId,
                'point' => $pointName,
                'created_at' => now(),
                'updated_at' => now(),
            ]);
            
            // Fetch and return the point
            $point = ShockPoint::find($pointId);
            
            if ($point) {
                Log::info("Auto-created missing shock point: ID={$pointId}, Name={$pointName}");
            }
            
            return $point;
            
        } catch (\Exception $e) {
            Log::error("Failed to create shock point {$pointId}: " . $e->getMessage());
            return null;
        }
    }

    /**
     * Save the SVG image to storage
     *
     * @param string $imgData
     * @param Dossier $dossier
     * @return void
     */
    private function saveSvgImage($imgData, $dossier)
    {
        try {
            $type = TypeDocument::whereId('18')->first();
            
            if (!$type) {
                Log::warning("TypeDocument 18 not found for shock point image");
                return;
            }
            
            $array = explode(",", $imgData);
            
            if (count($array) > 1) {
                $image = base64_decode($array[1]);
                $filename = uniqid() . '.png';
                $path = 'documents/' . $dossier->ref . '/' . $type->type . '/' . $filename;
                
                Storage::disk('s3')->put($path, $image);

                Document::updateOrCreate(
                    ['dossier_id' => $dossier->id, 'type_document_id' => $type->id],
                    ['path' => $path]
                );
            }
        } catch (\Exception $e) {
            Log::error("Failed to save shock point image: " . $e->getMessage());
        }
    }

    /**
     * Seed all SVG zones into database (utility method)
     * Can be called via route or artisan command
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function seedSvgZones()
    {
        $created = 0;
        $existing = 0;
        
        foreach ($this->svgZoneNames as $id => $name) {
            $exists = ShockPoint::find($id);
            
            if (!$exists) {
                DB::table('shock_points')->insertOrIgnore([
                    'id' => $id,
                    'point' => $name,
                    'created_at' => now(),
                    'updated_at' => now(),
                ]);
                $created++;
            } else {
                $existing++;
            }
        }

        return response()->json([
            'success' => true,
            'created' => $created,
            'existing' => $existing,
            'total' => count($this->svgZoneNames),
            'message' => "{$created} zones créées, {$existing} existantes"
        ]);
    }

    /**
     * Get all shock points as JSON (for AJAX)
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function getAll()
    {
        $points = ShockPoint::orderBy('id', 'asc')->get();
        return response()->json($points);
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\ShockPoint  $shockPoint
     * @return \Illuminate\Http\Response
     */
    public function show(ShockPoint $shockPoint)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\ShockPoint  $shockPoint
     * @return \Illuminate\Http\Response
     */
    public function edit(ShockPoint $shockPoint)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\ShockPoint  $shockPoint
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, ShockPoint $shockPoint)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\ShockPoint  $shockPoint
     * @return \Illuminate\Http\Response
     */
    public function destroy(ShockPoint $shockPoint)
    {
        //
    }
}