<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Support\Locations;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;

class LocationsController extends Controller
{
    public function index()
    {
        $locations = Locations::all();
        return view('admin.locations.index', [
            'locations' => $locations,
        ]);
    }

    public function storeCountry(Request $request)
    {
        $data = $request->validate([
            'code' => ['required', 'string', 'min:2', 'max:3'],
            'name' => ['required', 'string', 'max:100'],
        ]);

        $code = strtoupper(trim($data['code']));
        $name = trim($data['name']);

        $locations = Locations::all();
        if (isset($locations[$code])) {
            return back()->withErrors(['code' => 'Country code already exists.'])->withInput();
        }
        $locations[$code] = [
            'name' => $name,
            'regions' => [],
        ];

        Locations::save($locations);

        return redirect()->route('admin.locations.show', ['country' => $code])->with('status', 'Country created');
    }

    public function showCountry(string $country)
    {
        $country = strtoupper($country);
        $locations = Locations::all();
        $data = $locations[$country] ?? null;
        abort_unless($data, 404);

        return view('admin.locations.edit', [
            'code' => $country,
            'country' => $data,
        ]);
    }

    public function updateCountry(Request $request, string $country)
    {
        $country = strtoupper($country);
        $data = $request->validate([
            'name' => ['required', 'string', 'max:100'],
        ]);

        $locations = Locations::all();
        abort_unless(isset($locations[$country]), 404);
        $locations[$country]['name'] = trim($data['name']);
        Locations::save($locations);

        return back()->with('status', 'Country updated');
    }

    public function deleteCountry(Request $request, string $country)
    {
        $country = strtoupper($country);
        $locations = Locations::all();
        if (!isset($locations[$country])) {
            return redirect()->route('admin.locations.index');
        }
        unset($locations[$country]);
        Locations::save($locations);
        return redirect()->route('admin.locations.index')->with('status', 'Country deleted');
    }

    public function addRegion(Request $request, string $country)
    {
        $country = strtoupper($country);
        $data = $request->validate([
            'name' => ['required', 'string', 'max:100'],
        ]);
        $name = trim($data['name']);

        $locations = Locations::all();
        abort_unless(isset($locations[$country]), 404);
        $locations[$country]['regions'] = $locations[$country]['regions'] ?? [];
        if (!isset($locations[$country]['regions'][$name])) {
            $locations[$country]['regions'][$name] = ['districts' => []];
        }
        Locations::save($locations);
        return back()->with('status', 'Region added');
    }

    public function deleteRegion(Request $request, string $country)
    {
        $country = strtoupper($country);
        $data = $request->validate([
            'region' => ['required', 'string'],
        ]);
        $region = $data['region'];

        $locations = Locations::all();
        abort_unless(isset($locations[$country]), 404);
        unset($locations[$country]['regions'][$region]);
        Locations::save($locations);
        return back()->with('status', 'Region deleted');
    }

    public function addDistrict(Request $request, string $country)
    {
        $country = strtoupper($country);
        $data = $request->validate([
            'region' => ['required', 'string'],
            'name' => ['required', 'string', 'max:100'],
        ]);
        $region = $data['region'];
        $name = trim($data['name']);

        $locations = Locations::all();
        abort_unless(isset($locations[$country]['regions'][$region]), 404);
        $locations[$country]['regions'][$region]['districts'] = $locations[$country]['regions'][$region]['districts'] ?? [];
        if (!isset($locations[$country]['regions'][$region]['districts'][$name])) {
            $locations[$country]['regions'][$region]['districts'][$name] = [];
        }
        Locations::save($locations);
        return back()->with('status', 'District added');
    }

    public function deleteDistrict(Request $request, string $country)
    {
        $country = strtoupper($country);
        $data = $request->validate([
            'region' => ['required', 'string'],
            'district' => ['required', 'string'],
        ]);
        $region = $data['region'];
        $district = $data['district'];

        $locations = Locations::all();
        abort_unless(isset($locations[$country]['regions'][$region]), 404);
        unset($locations[$country]['regions'][$region]['districts'][$district]);
        Locations::save($locations);
        return back()->with('status', 'District deleted');
    }

    public function addTown(Request $request, string $country)
    {
        $country = strtoupper($country);
        $data = $request->validate([
            'region' => ['required', 'string'],
            'district' => ['required', 'string'],
            'name' => ['required', 'string', 'max:100'],
        ]);
        $region = $data['region'];
        $district = $data['district'];
        $name = trim($data['name']);

        $locations = Locations::all();
        abort_unless(isset($locations[$country]['regions'][$region]['districts'][$district]), 404);
        $locations[$country]['regions'][$region]['districts'][$district] = $locations[$country]['regions'][$region]['districts'][$district] ?? [];
        if (!in_array($name, $locations[$country]['regions'][$region]['districts'][$district], true)) {
            $locations[$country]['regions'][$region]['districts'][$district][] = $name;
        }
        Locations::save($locations);
        return back()->with('status', 'Town added');
    }

    public function deleteTown(Request $request, string $country)
    {
        $country = strtoupper($country);
        $data = $request->validate([
            'region' => ['required', 'string'],
            'district' => ['required', 'string'],
            'town' => ['required', 'string'],
        ]);
        $region = $data['region'];
        $district = $data['district'];
        $town = $data['town'];

        $locations = Locations::all();
        abort_unless(isset($locations[$country]['regions'][$region]['districts'][$district]), 404);
        $locations[$country]['regions'][$region]['districts'][$district] = array_values(array_filter(
            $locations[$country]['regions'][$region]['districts'][$district] ?? [],
            function ($t) use ($town) { return $t !== $town; }
        ));
        Locations::save($locations);
        return back()->with('status', 'Town deleted');
    }
}
