<?php

namespace App\Http\Controllers;

use App\City;
use App\Area;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Yajra\DataTables\Facades\DataTables;

class WorkCitiesController extends Controller
{
    /**
     * Sanitize input data to prevent XSS attacks
     */
    private function sanitizeInput($input)
    {
        if (is_string($input)) {
            return htmlspecialchars(strip_tags(trim($input)), ENT_QUOTES, 'UTF-8');
        }
        return $input;
    }

    /**
     * Display a listing of cities and areas.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        if (!auth()->user()->can('business_settings.access')) {
            abort(403, 'Unauthorized action.');
        }

        $business_id = request()->session()->get('user.business_id');
        $cities = City::forBusiness($business_id)->get();
        $areas = Area::forBusiness($business_id)->with('city')->get();

        return view('work-cities.index', compact('cities', 'areas'));
    }

    /**
     * Store a newly created city.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function storeCity(Request $request)
    {
        if (!auth()->user()->can('business_settings.access')) {
            abort(403, 'Unauthorized action.');
        }

        try {
            $business_id = request()->session()->get('user.business_id');
            
            $request->validate([
                'city_name' => 'required|string|max:255',
            ]);

            // Generate unique 5-digit city ID
            $city_id = $this->generateUniqueId('cities', 'city_id', $business_id);

            $city = City::create([
                'city_name' => $request->city_name,
                'city_id' => $city_id,
                'business_id' => $business_id,
            ]);

            $output = [
                'success' => 1,
                'msg' => __('lang_v1.city_added_successfully'),
                'city' => $city
            ];
        } catch (\Exception $e) {
            \Log::emergency('File:' . $e->getFile() . 'Line:' . $e->getLine() . 'Message:' . $e->getMessage());
            $output = [
                'success' => 0,
                'msg' => __('messages.something_went_wrong')
            ];
        }

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

    /**
     * Store a newly created area.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function storeArea(Request $request)
    {
        if (!auth()->user()->can('business_settings.access')) {
            abort(403, 'Unauthorized action.');
        }

        try {
            $business_id = request()->session()->get('user.business_id');
            
            $request->validate([
                'brick_name' => 'required|string|max:255',
                'city_id' => 'required|exists:cities,city_id',
                'status' => 'required|in:active,inactive',
            ]);

            // Generate unique 5-digit brick ID
            $brick_id = $this->generateUniqueId('areas', 'brick_id', $business_id);

            $area = Area::create([
                'brick_id' => $brick_id,
                'brick_name' => $request->brick_name,
                'city_id' => $request->city_id,
                'status' => $request->status,
                'business_id' => $business_id,
            ]);

            $output = [
                'success' => 1,
                'msg' => __('lang_v1.area_added_successfully'),
                'area' => $area->load('city')
            ];
        } catch (\Exception $e) {
            \Log::emergency('File:' . $e->getFile() . 'Line:' . $e->getLine() . 'Message:' . $e->getMessage());
            $output = [
                'success' => 0,
                'msg' => __('messages.something_went_wrong')
            ];
        }

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

    /**
     * Update the specified city.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function updateCity(Request $request, $id)
    {
        if (!auth()->user()->can('business_settings.access')) {
            abort(403, 'Unauthorized action.');
        }

        try {
            $business_id = request()->session()->get('user.business_id');
            
            $city = City::where('city_id', $id)
                ->where('business_id', $business_id)
                ->firstOrFail();

            $request->validate([
                'city_name' => 'required|string|max:255',
            ]);

            $city->update([
                'city_name' => $request->city_name,
            ]);

            $output = [
                'success' => 1,
                'msg' => __('lang_v1.city_updated_successfully'),
                'city' => $city
            ];
        } catch (\Exception $e) {
            \Log::emergency('File:' . $e->getFile() . 'Line:' . $e->getLine() . 'Message:' . $e->getMessage());
            $output = [
                'success' => 0,
                'msg' => __('messages.something_went_wrong')
            ];
        }

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

    /**
     * Update the specified area.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function updateArea(Request $request, $id)
    {
        if (!auth()->user()->can('business_settings.access')) {
            abort(403, 'Unauthorized action.');
        }

        try {
            $business_id = request()->session()->get('user.business_id');
            
            $area = Area::where('id', $id)
                ->where('business_id', $business_id)
                ->firstOrFail();

            $request->validate([
                'brick_name' => 'required|string|max:255',
                'city_id' => 'required|exists:cities,city_id',
                'status' => 'required|in:active,inactive',
            ]);

            $area->update([
                'brick_name' => $request->brick_name,
                'city_id' => $request->city_id,
                'status' => $request->status,
            ]);

            $output = [
                'success' => 1,
                'msg' => __('lang_v1.area_updated_successfully'),
                'area' => $area->load('city')
            ];
        } catch (\Exception $e) {
            \Log::emergency('File:' . $e->getFile() . 'Line:' . $e->getLine() . 'Message:' . $e->getMessage());
            $output = [
                'success' => 0,
                'msg' => __('messages.something_went_wrong')
            ];
        }

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

    /**
     * Remove the specified city.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroyCity($id)
    {
        if (!auth()->user()->can('business_settings.access')) {
            abort(403, 'Unauthorized action.');
        }

        try {
            $business_id = request()->session()->get('user.business_id');
            
            $city = City::where('city_id', $id)
                ->where('business_id', $business_id)
                ->firstOrFail();

            // Check if city has areas
            if ($city->areas()->count() > 0) {
                $output = [
                    'success' => 0,
                    'msg' => __('lang_v1.city_has_areas_cannot_delete')
                ];
            } else {
                $city->delete();
                $output = [
                    'success' => 1,
                    'msg' => __('lang_v1.city_deleted_successfully')
                ];
            }
        } catch (\Exception $e) {
            \Log::emergency('File:' . $e->getFile() . 'Line:' . $e->getLine() . 'Message:' . $e->getMessage());
            $output = [
                'success' => 0,
                'msg' => __('messages.something_went_wrong')
            ];
        }

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

    /**
     * Remove the specified area.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroyArea($id)
    {
        if (!auth()->user()->can('business_settings.access')) {
            abort(403, 'Unauthorized action.');
        }

        try {
            $business_id = request()->session()->get('user.business_id');
            
            $area = Area::where('id', $id)
                ->where('business_id', $business_id)
                ->firstOrFail();

            $area->delete();

            $output = [
                'success' => 1,
                'msg' => __('lang_v1.area_deleted_successfully')
            ];
        } catch (\Exception $e) {
            \Log::emergency('File:' . $e->getFile() . 'Line:' . $e->getLine() . 'Message:' . $e->getMessage());
            $output = [
                'success' => 0,
                'msg' => __('messages.something_went_wrong')
            ];
        }

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

    /**
     * Search cities for autocomplete in contact form.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function searchCities(Request $request)
    {
        try {
            $business_id = request()->session()->get('user.business_id');
            
            // Get cities with their areas (bricks)
            $cities = City::where('business_id', $business_id)
                ->with(['areas' => function($query) {
                    $query->select(['brick_id', 'brick_name', 'city_id']);
                }])
                ->select(['city_id', 'city_name'])
                ->get();

            return response()->json($cities);
        } catch (\Exception $e) {
            \Log::emergency('File:' . $e->getFile() . 'Line:' . $e->getLine() . 'Message:' . $e->getMessage());
            return response()->json([
                'success' => 0,
                'msg' => $e->getMessage()
            ]);
        }
    }

    /**
     * Get brick names (areas) for a specific city.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function getBrickNames(Request $request)
    {
        if (!auth()->user()->can('business_settings.access')) {
            \Log::warning('Unauthorized access attempt to getBrickNames', [
                'user_id' => auth()->id(),
                'ip' => request()->ip(),
                'user_agent' => request()->userAgent()
            ]);
            abort(403, 'Unauthorized action.');
        }

        try {
            $business_id = request()->session()->get('user.business_id');
            
            // Validate and sanitize input
            $request->validate([
                'city_id' => 'required|integer|exists:cities,id',
                'search' => 'nullable|string|max:255|regex:/^[a-zA-Z0-9\s\-_\.]+$/'
            ]);
            
            $city_id = $this->sanitizeInput($request->get('city_id'));
            $search = $this->sanitizeInput($request->get('search', ''));
            
            if (!$city_id) {
                return response()->json([
                    'success' => 0,
                    'msg' => 'City ID is required'
                ]);
            }

            $query = Area::forBusiness($business_id)
                ->where('city_id', $city_id)
                ->active(); // Only return active areas
            
            // If search term is provided, filter by brick name
            if (!empty($search)) {
                $query->where('brick_name', 'like', '%' . $search . '%');
            }
            
            $areas = $query->select(['id', 'brick_name', 'brick_id'])
                ->orderBy('brick_name', 'asc')
                ->get();

            return response()->json([
                'success' => 1,
                'data' => $areas
            ]);
        } catch (\Exception $e) {
            \Log::emergency('File:' . $e->getFile() . 'Line:' . $e->getLine() . 'Message:' . $e->getMessage());
            return response()->json([
                'success' => 0,
                'msg' => __('messages.something_went_wrong')
            ]);
        }
    }

    /**
     * Get brick ID for a specific brick name.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function getBrickId(Request $request)
    {
        if (!auth()->user()->can('business_settings.access')) {
            \Log::warning('Unauthorized access attempt to getBrickId', [
                'user_id' => auth()->id(),
                'ip' => request()->ip(),
                'user_agent' => request()->userAgent()
            ]);
            abort(403, 'Unauthorized action.');
        }

        try {
            $business_id = request()->session()->get('user.business_id');
            
            // Validate and sanitize input
            $request->validate([
                'brick_name' => 'required|string|max:255|regex:/^[a-zA-Z0-9\s\-_\.]+$/'
            ]);
            
            $brick_name = $this->sanitizeInput($request->get('brick_name'));
            
            if (!$brick_name) {
                return response()->json([
                    'success' => 0,
                    'msg' => 'Brick name is required'
                ]);
            }

            $area = Area::forBusiness($business_id)
                ->where('brick_name', $brick_name)
                ->active() // Only work with active areas
                ->select(['id', 'brick_name', 'brick_id'])
                ->first();

            if ($area) {
                return response()->json([
                    'success' => 1,
                    'data' => $area
                ]);
            } else {
                return response()->json([
                    'success' => 0,
                    'msg' => 'Brick not found'
                ]);
            }
        } catch (\Exception $e) {
            \Log::emergency('File:' . $e->getFile() . 'Line:' . $e->getLine() . 'Message:' . $e->getMessage());
            return response()->json([
                'success' => 0,
                'msg' => __('messages.something_went_wrong')
            ]);
        }
    }

    /**
     * Generate unique 5-digit ID for cities or areas
     *
     * @param string $table
     * @param string $column
     * @param int $business_id
     * @return string
     */
    private function generateUniqueId($table, $column, $business_id)
    {
        do {
            $id = str_pad(rand(10000, 99999), 5, '0', STR_PAD_LEFT);
            $exists = \DB::table($table)
                ->where($column, $id)
                ->where('business_id', $business_id)
                ->exists();
        } while ($exists);

        return $id;
    }
}
