<?php

namespace App\Http\Controllers;

use App\Models\AppSetting;
use App\Models\FeedConfig;
use App\Models\LookupList;
use App\Models\Role;
use App\Models\SpeciesConfig;
use App\Support\Permission;
use Illuminate\Http\Request;

class SettingsController extends Controller
{
    public const LIST_TYPES = [
        'pond_type' => 'Pond Types',
        'water_source' => 'Water Sources',
        'feed_brand' => 'Feed Brands',
        'feed_type' => 'Feed Types',
        'feeding_response' => 'Feeding Response',
        'probable_cause' => 'Probable Causes (Mortality)',
        'application_method' => 'Application Methods (Treatment)',
        'harvest_type' => 'Harvest Types',
        'expense_category' => 'Expense Categories',
    ];

    public function index()
    {
        $species = SpeciesConfig::where('farm_id', 1)->get();
        $feeds = FeedConfig::where('farm_id', 1)->get();

        $lookups = LookupList::where('farm_id', 1)
            ->orderBy('list_type')
            ->orderBy('sort_order')
            ->orderBy('label')
            ->get()
            ->groupBy('list_type');

        $appSettings = AppSetting::pluck('value', 'key');

        $roles = Role::where('farm_id', 1)->orderBy('is_system', 'desc')->orderBy('name')->get();
        $permissions = Permission::GROUPS;

        return view('settings.index', compact('species', 'feeds', 'lookups', 'appSettings', 'roles', 'permissions'));
    }

    // ── Species ──────────────────────────────────────────────────────────────

    public function storeSpecies(Request $request)
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:100'],
            'target_weight_g' => ['required', 'numeric', 'min:1'],
            'safe_ph_min' => ['required', 'numeric'],
            'safe_ph_max' => ['required', 'numeric'],
            'safe_do_min_mgl' => ['required', 'numeric'],
            'safe_temp_min_c' => ['required', 'numeric'],
            'safe_temp_max_c' => ['required', 'numeric'],
            'safe_ammonia_max_ppm' => ['required', 'numeric'],
            'safe_nitrite_max_ppm' => ['required', 'numeric'],
        ]);

        SpeciesConfig::create(array_merge($validated, ['farm_id' => 1]));

        return redirect(route('settings.index').'#species')->with('success', 'Species config added.');
    }

    public function updateSpecies(Request $request, SpeciesConfig $species)
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:100'],
            'target_weight_g' => ['required', 'numeric', 'min:1'],
            'safe_ph_min' => ['required', 'numeric'],
            'safe_ph_max' => ['required', 'numeric'],
            'safe_do_min_mgl' => ['required', 'numeric'],
            'safe_temp_min_c' => ['required', 'numeric'],
            'safe_temp_max_c' => ['required', 'numeric'],
            'safe_ammonia_max_ppm' => ['required', 'numeric'],
            'safe_nitrite_max_ppm' => ['required', 'numeric'],
        ]);

        $species->update($validated);

        return redirect(route('settings.index').'#species')->with('success', 'Species config updated.');
    }

    public function destroySpecies(SpeciesConfig $species)
    {
        $species->delete();

        return redirect(route('settings.index').'#species')->with('success', 'Species config removed.');
    }

    // ── Feed configs ──────────────────────────────────────────────────────────

    public function storeFeed(Request $request)
    {
        $validated = $request->validate([
            'brand' => ['required', 'string', 'max:100'],
            'type' => ['required', 'string', 'max:100'],
            'size_mm' => ['nullable', 'numeric'],
            'bag_weight_kg' => ['required', 'numeric', 'min:0.1'],
            'notes' => ['nullable', 'string'],
        ]);

        FeedConfig::create(array_merge($validated, ['farm_id' => 1]));

        return redirect(route('settings.index').'#feeds')->with('success', 'Feed config added.');
    }

    public function updateFeed(Request $request, FeedConfig $feed)
    {
        $validated = $request->validate([
            'brand' => ['required', 'string', 'max:100'],
            'type' => ['required', 'string', 'max:100'],
            'size_mm' => ['nullable', 'numeric'],
            'bag_weight_kg' => ['required', 'numeric', 'min:0.1'],
            'notes' => ['nullable', 'string'],
        ]);

        $feed->update($validated);

        return redirect(route('settings.index').'#feeds')->with('success', 'Feed config updated.');
    }

    public function destroyFeed(FeedConfig $feed)
    {
        $feed->delete();

        return redirect(route('settings.index').'#feeds')->with('success', 'Feed config removed.');
    }

    // ── Lookup lists ──────────────────────────────────────────────────────────

    public function storeLookup(Request $request)
    {
        $request->validate([
            'list_type' => ['required', 'string', 'in:'.implode(',', array_keys(self::LIST_TYPES))],
            'value' => ['required', 'string', 'max:80', 'regex:/^[a-z0-9_]+$/'],
            'label' => ['required', 'string', 'max:100'],
            'sort_order' => ['nullable', 'integer', 'min:0'],
        ]);

        $exists = LookupList::where('farm_id', 1)
            ->where('list_type', $request->list_type)
            ->where('value', $request->value)
            ->exists();

        if ($exists) {
            return back()->withErrors(['value' => 'This value already exists in the list.'])->withInput();
        }

        LookupList::create([
            'farm_id' => 1,
            'list_type' => $request->list_type,
            'value' => $request->value,
            'label' => $request->label,
            'sort_order' => $request->sort_order ?? 0,
            'is_active' => true,
        ]);

        return redirect(route('settings.index').'#'.$request->list_type)->with('success', 'List item added.');
    }

    public function updateLookup(Request $request, LookupList $lookup)
    {
        $request->validate([
            'label' => ['required', 'string', 'max:100'],
            'sort_order' => ['nullable', 'integer', 'min:0'],
        ]);

        $lookup->update([
            'label' => $request->label,
            'sort_order' => $request->sort_order ?? $lookup->sort_order,
        ]);

        return redirect(route('settings.index').'#'.$lookup->list_type)->with('success', 'List item updated.');
    }

    public function destroyLookup(LookupList $lookup)
    {
        $lookup->delete();

        return redirect(route('settings.index').'#'.$lookup->list_type)->with('success', 'List item removed.');
    }

    // ── App settings ──────────────────────────────────────────────────────────

    public function storeAppSetting(Request $request)
    {
        $request->validate([
            'key' => ['required', 'string', 'in:dimension_unit,feed_quantity_unit'],
            'value' => ['required', 'string', 'max:10'],
        ]);

        AppSetting::set($request->key, $request->value);

        return redirect(route('settings.index').'#app_settings')->with('success', 'Setting saved.');
    }

    // ── Roles ─────────────────────────────────────────────────────────────────

    public function storeRole(Request $request)
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:100'],
            'description' => ['nullable', 'string', 'max:255'],
            'parent_role' => ['required', 'string', 'in:admin,manager,farm_hand,viewer'],
            'permissions' => ['nullable', 'array'],
            'permissions.*' => ['string'],
        ]);

        $slug = \Str::slug($validated['name'], '_');

        if (Role::where('slug', $slug)->exists()) {
            return back()->withErrors(['name' => 'A role with this name already exists.'])->withInput();
        }

        Role::create([
            'farm_id' => 1,
            'slug' => $slug,
            'name' => $validated['name'],
            'description' => $validated['description'] ?? null,
            'parent_role' => $validated['parent_role'],
            'is_system' => false,
            'permissions' => $validated['permissions'] ?? [],
        ]);

        return redirect(route('settings.index').'#roles')->with('success', 'Role created.');
    }

    public function updateRole(Request $request, Role $role)
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:100'],
            'description' => ['nullable', 'string', 'max:255'],
            'parent_role' => ['nullable', 'string', 'in:admin,manager,farm_hand,viewer'],
            'permissions' => ['nullable', 'array'],
            'permissions.*' => ['string'],
        ]);

        $data = [
            'name' => $validated['name'],
            'description' => $validated['description'] ?? null,
            'permissions' => $validated['permissions'] ?? [],
        ];

        if (! $role->is_system) {
            $data['parent_role'] = $validated['parent_role'];
        }

        $role->update($data);

        return redirect(route('settings.index').'#roles')->with('success', 'Role updated.');
    }

    public function destroyRole(Role $role)
    {
        if ($role->is_system) {
            return back()->with('error', 'System roles cannot be deleted.');
        }

        $role->delete();

        return redirect(route('settings.index').'#roles')->with('success', 'Role deleted.');
    }
}
