<?php

namespace App\Http\Controllers;

use App\Models\Incident;
use App\Models\AgeGroup;
use App\Models\Gender;
use App\Models\Religion;
use App\Models\Relation;
use App\Models\TimeofDay;
use App\Models\MaritalStatus;
use App\Models\NationalStatus;
use App\Models\Disability;
use Illuminate\Http\Request;

class IndicatorController extends Controller
{
    function incidents(){ return view('indicator.incidents'); }
    function list(){ return view('indicator.list'); }
    function agegroup(){ return view('indicator.agegroups'); }
    function gender(){ return view('indicator.gender'); }
    function religion(){ return view('indicator.religion'); }
    function relations(){ return view('indicator.relations'); }
    function timeofday(){ return view('indicator.timeofday'); }
    function maritalstatus(){ return view('indicator.maritalstatus'); }
    function nationalstatus(){ return view('indicator.nationalstatus'); }
    function disability(){ return view('indicator.disability'); }

    function processincident(Request $request){
        $data = $this->validateIncident($request);
        $indicator = new Incident();
        $indicator->name = $data['name'];
        $indicator->code = $data['code'] ?? null;
        $indicator->notes = $data['notes'] ?? null;
        return $this->saveAndRedirect($indicator, 'indicator/list', 'indicator/incidents', 'Incident Category');
    }

    function updateincident(Request $request){
        $data = $this->validateIncident($request, true);
        $indicator = Incident::findOrFail($data['id']);
        $indicator->name = $data['name'];
        $indicator->code = $data['code'] ?? null;
        $indicator->notes = $data['notes'] ?? null;
        return $this->saveAndRedirect($indicator, 'indicator/list', 'indicator/incidents', 'Incident Category');
    }

    function processage(Request $request){
        $data = $this->validateAgeGroup($request);
        $agegroup = new AgeGroup();
        $agegroup->name = $data['name'];
        $agegroup->min = $data['min'];
        $agegroup->max = $data['max'];
        return $this->saveAndRedirect($agegroup, 'indicator/agegroups', 'dashboard/index', 'Age Group');
    }

    function updateagegroups(Request $request){
        $data = $this->validateAgeGroup($request, true);
        $agegroup = AgeGroup::findOrFail($data['id']);
        $agegroup->name = $data['name'];
        $agegroup->min = $data['min'];
        $agegroup->max = $data['max'];
        return $this->saveAndRedirect($agegroup, 'indicator/list?tab=age', 'indicator/list?tab=age', 'Age Group');
    }

    function disableage(Request $request){ return $this->disableRecord($request, AgeGroup::class, 'indicator/list?tab=age', 'Age Group'); }
    function disablereligion(Request $request){ return $this->disableRecord($request, Religion::class, 'indicator/list?tab=religion', 'Religion'); }
    function disablerelations(Request $request){ return $this->disableRecord($request, Relation::class, 'indicator/list?tab=relations', 'Relation'); }
    function disabletime(Request $request){ return $this->disableRecord($request, TimeofDay::class, 'indicator/list?tab=time', 'Time of day'); }
    function disablemariage(Request $request){ return $this->disableRecord($request, MaritalStatus::class, 'indicator/list?tab=marital', 'Marital status'); }
    function disablenationalstatus(Request $request){ return $this->disableRecord($request, NationalStatus::class, 'indicator/list?tab=national', 'National status'); }
    function disabledisabiliy(Request $request){ return $this->disableRecord($request, Disability::class, 'indicator/list?tab=disability', 'Disability status'); }

    function processgender(Request $request){
        $data = $this->validateNameOnly($request);
        $record = new Gender();
        $record->name = $data['name'];
        return $this->saveAndRedirect($record, 'indicator/list?tab=gender', 'dashboard/index', 'Gender');
    }

    function updategender(Request $request){
        $data = $this->validateNameOnly($request, true);
        $record = Gender::findOrFail($data['id']);
        $record->name = $data['name'];
        return $this->saveAndRedirect($record, 'indicator/list?tab=gender', 'dashboard/index', 'Gender');
    }

    function processreligion(Request $request){
        $data = $this->validateNameNotes($request);
        $record = new Religion();
        $record->name = $data['name'];
        $record->notes = $data['notes'] ?? null;
        return $this->saveAndRedirect($record, 'indicator/religion', 'dashboard/index', 'Religion');
    }

    function updatereligion(Request $request){
        $data = $this->validateNameNotes($request, true);
        $record = Religion::findOrFail($data['id']);
        $record->name = $data['name'];
        $record->notes = $data['notes'] ?? null;
        return $this->saveAndRedirect($record, 'indicator/list?tab=religion', 'dashboard/index', 'Religion');
    }

    function processrelations(Request $request){
        $data = $this->validateNameNotes($request);
        $record = new Relation();
        $record->name = $data['name'];
        $record->notes = $data['notes'] ?? null;
        return $this->saveAndRedirect($record, 'indicator/relation', 'dashboard/index', 'Relation');
    }

    function updaterelations(Request $request){
        $data = $this->validateNameNotes($request, true);
        $record = Relation::findOrFail($data['id']);
        $record->name = $data['name'];
        $record->notes = $data['notes'] ?? null;
        return $this->saveAndRedirect($record, 'indicator/list?tab=relations', 'dashboard/index', 'Relation');
    }

    function processtimeofday(Request $request){
        $data = $this->validateNameNotes($request);
        $record = new TimeofDay();
        $record->name = $data['name'];
        $record->notes = $data['notes'] ?? null;
        return $this->saveAndRedirect($record, 'indicator/relation', 'dashboard/index', 'Time of Day');
    }

    function updatetimeofday(Request $request){
        $data = $this->validateNameNotes($request, true);
        $record = TimeofDay::findOrFail($data['id']);
        $record->name = $data['name'];
        $record->notes = $data['notes'] ?? null;
        return $this->saveAndRedirect($record, 'indicator/list?tab=time', 'dashboard/index', 'Time of Day');
    }

    function processmaritalstatus(Request $request){
        $data = $this->validateNameOnly($request);
        $record = new MaritalStatus();
        $record->name = $data['name'];
        return $this->saveAndRedirect($record, 'indicator/maritalstatus', 'dashboard/index', 'Marital Status');
    }

    function updatemaritalstatus(Request $request){
        $data = $this->validateNameOnly($request, true);
        $record = MaritalStatus::findOrFail($data['id']);
        $record->name = $data['name'];
        return $this->saveAndRedirect($record, 'indicator/list?tab=marital', 'dashboard/index', 'Marital Status');
    }

    function processnationalstatus(Request $request){
        $data = $this->validateNameOnly($request);
        $record = new NationalStatus();
        $record->name = $data['name'];
        return $this->saveAndRedirect($record, 'indicator/nationalstatus', 'dashboard/index', 'National Status');
    }

    function updatenationalstatus(Request $request){
        $data = $this->validateNameOnly($request, true);
        $record = NationalStatus::findOrFail($data['id']);
        $record->name = $data['name'];
        return $this->saveAndRedirect($record, 'indicator/list?tab=national', 'dashboard/index', 'National Status');
    }

    function processdisability(Request $request){
        $data = $this->validateNameOnly($request);
        $record = new Disability();
        $record->name = $data['name'];
        return $this->saveAndRedirect($record, 'indicator/disability', 'dashboard/index', 'Disability');
    }

    function updatedisability(Request $request){
        $data = $this->validateNameOnly($request, true);
        $record = Disability::findOrFail($data['id']);
        $record->name = $data['name'];
        return $this->saveAndRedirect($record, 'indicator/list?tab=disability', 'dashboard/index', 'Disability');
    }

    private function validateIncident(Request $request, bool $withId = false): array
    {
        $rules = [
            'name' => ['required', 'string', 'max:180'],
            'code' => ['nullable', 'string', 'max:60', 'regex:/^[A-Za-z0-9\-_\.\/ ]+$/'],
            'notes' => ['nullable', 'string', 'max:3000'],
        ];

        if ($withId) {
            $rules['id'] = ['required', 'integer', 'exists:incidents,id'];
        }

        return $request->validate($rules);
    }

    private function validateAgeGroup(Request $request, bool $withId = false): array
    {
        $rules = [
            'name' => ['required', 'string', 'max:120'],
            'min' => ['required', 'integer', 'min:0', 'max:150'],
            'max' => ['required', 'integer', 'min:0', 'max:150', 'gte:min'],
        ];

        if ($withId) {
            $rules['id'] = ['required', 'integer', 'exists:agegroup,id'];
        }

        return $request->validate($rules);
    }

    private function validateNameOnly(Request $request, bool $withId = false): array
    {
        $rules = [
            'name' => ['required', 'string', 'max:180'],
        ];

        if ($withId) {
            $rules['id'] = ['required', 'integer', 'min:1'];
        }

        return $request->validate($rules);
    }

    private function validateNameNotes(Request $request, bool $withId = false): array
    {
        $rules = [
            'name' => ['required', 'string', 'max:180'],
            'notes' => ['nullable', 'string', 'max:3000'],
        ];

        if ($withId) {
            $rules['id'] = ['required', 'integer', 'min:1'];
        }

        return $request->validate($rules);
    }

    private function disableRecord(Request $request, string $modelClass, string $redirect, string $label)
    {
        $data = $request->validate([
            'id' => ['required', 'integer', 'min:1'],
        ]);

        $record = $modelClass::findOrFail($data['id']);
        if (property_exists($record, 'status') || array_key_exists('status', $record->getAttributes())) {
            $record->status = 0;
        } else {
            $record->setAttribute('status', 0);
        }

        if ($record->save()) {
            return redirect(url($redirect))->with('message', $label.' successfully disabled');
        }

        return redirect(url($redirect))->with('message', 'Failed to save');
    }

    private function saveAndRedirect($model, string $successUrl, string $failUrl, string $label)
    {
        if ($model->save()) {
            return redirect(url($successUrl))->with('message', $label.' successfully saved');
        }

        return redirect(url($failUrl))->with('message', $label.' failed to save');
    }
}
