<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Http\Controllers\Helpers\ResponseHelper;
use App\Http\Controllers\Helpers\Permissions\UserPermissions;
use App\Enums\UserActions;
use App\Models\Chapter;
use App\Models\ChapterMember;
use App\Models\User;
use App\Models\SystemSetting;
use App\Support\IslandGroupHelper;
use Hypervel\Http\Request;
use Hypervel\Support\Facades\Auth;
use Hypervel\Support\Facades\Validator;
use Hypervel\Support\Str;

class ChapterController
{
    private const CHILD_LEVELS = [
        'national'  => ['region'],
        'region'    => ['province'],
        'province'  => ['city', 'municipal'],
        'city'      => ['barangay'],
        'municipal' => ['barangay'],
        'barangay'  => ['purok'],
        'purok'     => [],
    ];

    private function isAdmin(): bool
    {
        return UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::ManageChapterMembers);
    }

    public function hierarchy(Request $request)
    {
        $chapterId = $request->input('chapter_id');

        if (!$chapterId) {
            $national = Chapter::where('level', 'national')->where('location_key', 'philippines')->first();
            if (!$national) {
                return response()->json(['chapters' => [], 'current' => null, 'breadcrumb' => []]);
            }
            $chapters = $national->children()
                ->where('is_active', true)
                ->withCount('activeMembers')
                ->with('leaders.user')
                ->get()
                ->map(fn ($c) => $this->formatChapter($c))
                ->values();

            return response()->json(['chapters' => $chapters, 'current' => null, 'breadcrumb' => []]);
        }

        $current = Chapter::withCount('activeMembers')->with('leaders.user')->find($chapterId);
        if (!$current) return ResponseHelper::returnError('Chapter not found', 404);

        $chapters = $current->children()
            ->where('is_active', true)
            ->withCount('activeMembers')
            ->with('leaders.user')
            ->get()
            ->map(fn ($c) => $this->formatChapter($c))
            ->values();

        return response()->json([
            'chapters'   => $chapters,
            'current'    => $this->formatChapter($current),
            'breadcrumb' => $this->buildBreadcrumb($current),
        ]);
    }

    public function mapData(Request $request)
    {
        $level    = $request->input('level', 'region');
        $parentId = $request->input('parent_id');

        $query = Chapter::where('level', $level)->where('is_active', true)->withCount('activeMembers');
        if ($parentId) $query->where('parent_id', $parentId);

        $chapters = $query->get()
            ->filter(fn ($c) => $c->lat && $c->lng)
            ->map(fn ($c) => [
                'id'    => $c->id,
                'name'  => $c->name,
                'level' => $c->level,
                'lat'   => $c->lat,
                'lng'   => $c->lng,
                'count' => $c->active_members_count,
            ])
            ->values();

        return response()->json(['chapters' => $chapters]);
    }

    public function members(Request $request)
    {
        $chapterId = $request->input('chapter_id');
        if (!$chapterId) return ResponseHelper::returnError('chapter_id required', 400);

        $members = ChapterMember::with('user')
            ->where('chapter_id', $chapterId)
            ->where('is_active', true)
            ->get()
            ->map(fn ($cm) => [
                'hashkey'   => $cm->hashkey,
                'name'      => $cm->user?->fullname ?? $cm->user?->name,
                'position'  => $cm->position,
                'photo'     => $cm->user?->photourl ?? null,
                'is_manual' => (bool) $cm->is_manual_override,
            ]);

        return response()->json(['members' => $members]);
    }

    public function assignMember(Request $request)
    {
        if (!$this->isAdmin()) return ResponseHelper::returnUnauthorized();

        $validator = Validator::make($request->all(), [
            'user_hashkey' => 'required|string',
            'chapter_id'   => 'required|integer',
            'position'     => 'nullable|string|max:100',
        ]);

        if ($validator->fails()) return ResponseHelper::returnError('Validation failed', 422, $validator->errors());

        $user = User::where('hashkey', $request->input('user_hashkey'))->first();
        if (!$user) return ResponseHelper::returnError('User not found', 404);

        $chapter = Chapter::find($request->input('chapter_id'));
        if (!$chapter) return ResponseHelper::returnError('Chapter not found', 404);

        $existing = ChapterMember::where('user_id', $user->id)->where('chapter_id', $chapter->id)->first();

        if ($existing) {
            $existing->update([
                'position'           => $request->input('position'),
                'is_manual_override' => true,
                'assigned_by'        => Auth::id(),
                'assigned_at'        => now(),
                'updated_by'         => Auth::id(),
            ]);
        } else {
            ChapterMember::create([
                'hashkey'            => (string) Str::uuid(),
                'user_id'            => $user->id,
                'chapter_id'         => $chapter->id,
                'position'           => $request->input('position'),
                'is_manual_override' => true,
                'is_active'          => true,
                'assigned_by'        => Auth::id(),
                'assigned_at'        => now(),
                'created_by'         => Auth::id(),
            ]);
        }

        return response()->json(['success' => true]);
    }

    public function removeMember(Request $request)
    {
        if (!$this->isAdmin()) return ResponseHelper::returnUnauthorized();

        $member = ChapterMember::where('hashkey', $request->input('hashkey'))->first();
        if (!$member) return ResponseHelper::returnError('Member assignment not found', 404);

        $member->update(['is_active' => false, 'updated_by' => Auth::id()]);

        return response()->json(['success' => true]);
    }

    public function positions()
    {
        $raw = SystemSetting::getValue('chapter_positions');
        $positions = is_string($raw) ? (json_decode($raw, true) ?? []) : [];
        if (empty($positions)) {
            $positions = ['Punong Barangay', 'Kagawad', 'Secretary', 'Treasurer', 'SK Chairperson', 'SK Councilor', 'Tanod', 'BHW', 'Daycare Worker', 'Staff', 'Member'];
        }
        return response()->json(['positions' => $positions]);
    }

    public function createChapter(Request $request)
    {
        if (!$this->isAdmin()) return ResponseHelper::returnUnauthorized();

        $validator = Validator::make($request->all(), [
            'name'         => 'required|string|max:255',
            'level'        => 'required|in:national,region,province,city,municipal,barangay,purok',
            'parent_id'    => 'nullable|integer|exists:chapters,id',
            'location_key' => 'nullable|string|max:255',
            'lat'          => 'nullable|numeric',
            'lng'          => 'nullable|numeric',
        ]);

        if ($validator->fails()) {
            return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
        }

        $data = $validator->validated();
        $data['hashkey']    = hash('sha256', uniqid((string) now(), true));
        $data['is_active']  = true;
        $data['created_by'] = Auth::id();
        $data['updated_by'] = Auth::id();
        $data['location_key'] = strtolower(trim($data['location_key'] ?? $data['name']));

        $chapter = Chapter::create($data);

        return response()->json(['success' => true, 'data' => $this->formatChapter($chapter), 'message' => 'Chapter created']);
    }

    private function formatChapter(Chapter $c): array
    {
        return [
            'id'            => $c->id,
            'hashkey'       => $c->hashkey,
            'name'          => $c->name,
            'level'         => $c->level,
            'parent_id'     => $c->parent_id,
            'location_key'  => $c->location_key,
            'lat'           => $c->lat,
            'lng'           => $c->lng,
            'is_active'     => $c->is_active,
            'member_count'  => $c->active_members_count ?? 0,
            'child_levels'  => self::CHILD_LEVELS[$c->level] ?? [],
        ];
    }

    private function buildBreadcrumb(Chapter $chapter): array
    {
        $crumbs = [];
        $current = $chapter;
        while ($current) {
            array_unshift($crumbs, ['id' => $current->id, 'name' => $current->name, 'level' => $current->level]);
            $current = $current->parent;
        }
        return $crumbs;
    }
}
