<?php

namespace App\Http\Controllers\Admin;

use App\DataTables\ChampionshipDataTable;
use App\Enums\ChampionshipMatchStageEnum;
use App\Enums\ChampionshipStatusEnum;
use App\Enums\TeamMemberInvitationStatusEnum;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\Championship\StoreBulkMatchesRequest;
use App\Http\Requests\Admin\Championship\StoreChampionshipMatchRequest;
use App\Http\Requests\Admin\Championship\StoreChampionshipRequest;
use App\Http\Requests\Admin\Championship\SubmitChampionshipMatchResultRequest;
use App\Http\Requests\Admin\Championship\UpdateChampionshipMatchRequest;
use App\Http\Requests\Admin\Championship\UpdateChampionshipRequest;
use App\Models\Championship;
use App\Models\ChampionshipMatch;
use App\Models\Court;
use App\Models\Game;
use App\Repositories\ChampionshipRepository;
use App\Services\ChampionshipScoringService;
use App\Services\ChampionshipService;
use Illuminate\Http\Request;

class ChampionshipController extends Controller
{
    public function __construct(
        protected ChampionshipRepository $repository,
        protected ChampionshipService $championshipService,
        protected ChampionshipScoringService $scoringService,
    ) {}

    public function index(ChampionshipDataTable $dataTable)
    {
        return view('admin.championships.index', [
            'dataTable' => $dataTable->html(),
        ]);
    }

    public function datatable(ChampionshipDataTable $dataTable)
    {
        return $dataTable->ajax();
    }

    public function create()
    {
        $games = Game::query()->where('status', 1)->get(['id', 'name']);

        return view('admin.championships.create', compact('games'));
    }

    public function store(StoreChampionshipRequest $request)
    {
        $this->repository->create($request->validated());

        return response()->json([
            'message' => __('Championship created successfully'),
            'redirect_url' => route('admin.championships.index'),
        ]);
    }

    public function show(Championship $championship)
    {
        $championship->load([
            'game',
            'teams' => fn ($q) => $q
                ->where('is_confirmed', true)
                ->orderBy('name')
                ->withCount([
                    'members as players_count' => fn ($mq) => $mq->where(
                        'championship_team_members.status',
                        TeamMemberInvitationStatusEnum::ACCEPTED->value
                    ),
                ]),
            'matches.teamA',
            'matches.teamB',
            'matches.score',
            'matches.winnerTeam',
            'matches.parentMatch',
        ]);

        $bracketData = $this->championshipService->getBracketData($championship);
        $courts = Court::query()->where('game_id', $championship->game_id)->get(['id', 'name']);

        return view('admin.championships.show', compact('championship', 'bracketData', 'courts'));
    }

    public function edit(Championship $championship)
    {
        $games = Game::query()->where('status', 1)->get(['id', 'name']);

        return view('admin.championships.edit', compact('championship', 'games'));
    }

    public function update(UpdateChampionshipRequest $request, Championship $championship)
    {
        $this->repository->update($championship, $request->validated());

        return response()->json([
            'message' => __('Championship updated successfully'),
            'redirect_url' => route('admin.championships.index'),
        ]);
    }

    public function destroy(Championship $championship)
    {
        $result = $this->repository->delete($championship);

        return response()->json([
            'message' => $result['success'] ? __('Championship deleted successfully') : __('dashboard.cannot_delete_has_relations'),
            'success' => $result['success'],
            'relations' => $result['relations'],
        ]);
    }

    public function updateStatus(Championship $championship)
    {
        $result = $this->repository->statusToggle($championship);

        return response()->json([
            'message' => $result['message'],
            'success' => $result['success'],
        ]);
    }

    public function bulkDelete(Request $request)
    {
        $request->validate(['ids' => 'required|array']);
        $result = $this->repository->bulkDelete($request->ids);

        return response()->json([
            'message' => __('dashboard.deleted_success'),
            'success' => true,
            'data' => $result,
        ]);
    }

    public function bulkStatus(Request $request)
    {
        $request->validate(['ids' => 'required|array', 'status' => 'required|boolean']);
        $value = $request->status
            ? ChampionshipStatusEnum::ONGOING->value
            : ChampionshipStatusEnum::CANCELLED->value;
        Championship::whereIn('id', $request->ids)->update(['status' => $value]);

        return response()->json([
            'message' => __('dashboard.status_updated'),
            'success' => true,
        ]);
    }

    // ==================== Match Management ====================

    public function storeMatch(StoreChampionshipMatchRequest $request, Championship $championship)
    {
        $match = $this->championshipService->createMatch($championship, $request->validated());

        return response()->json([
            'message' => __('Match created successfully'),
            'success' => true,
            'data' => $match->load(['teamA', 'teamB']),
        ]);
    }

    public function updateMatch(UpdateChampionshipMatchRequest $request, ChampionshipMatch $match)
    {
        $match = $this->championshipService->updateMatch($match, $request->validated());

        return response()->json([
            'message' => __('Match updated successfully'),
            'success' => true,
            'data' => $match,
        ]);
    }

    public function submitMatchResult(SubmitChampionshipMatchResultRequest $request, ChampionshipMatch $match)
    {
        $match = $this->scoringService->submitScore(
            $match,
            (int) $request->validated('winner_team_id'),
            (int) $request->validated('team_a_score'),
            (int) $request->validated('team_b_score')
        );

        return response()->json([
            'message' => __('Result submitted successfully'),
            'success' => true,
            'data' => $match,
        ]);
    }

    public function destroyMatch(ChampionshipMatch $match)
    {
        $this->championshipService->deleteMatch($match);

        return response()->json([
            'message' => __('Match deleted successfully'),
            'success' => true,
        ]);
    }

    /**
     * Matches Builder page (wizard + drag & drop UI)
     */
    public function matchesBuilder(Championship $championship)
    {
        $championship->load([
            'game',
            'teams' => fn ($q) => $q->where('is_confirmed', true),
        ]);
        $courts = Court::query()->where('game_id', $championship->game_id)->get(['id', 'name']);
        $stages = ChampionshipMatchStageEnum::options();
        $teamsPayload = $championship->teams
            ->map(function ($team) {
                $name = $team->name;
                if (is_array($name)) {
                    $name = $name[app()->getLocale()] ?? $name['en'] ?? (string) reset($name);
                }

                return [
                    'id' => $team->id,
                    'name' => (string) $name,
                    'logo' => $team->logo ? asset('storage/'.$team->logo) : null,
                ];
            })
            ->values()
            ->all();
        $courtsPayload = $courts
            ->map(function ($court) {
                return [
                    'id' => $court->id,
                    'name' => $court->name,
                ];
            })
            ->values()
            ->all();

        return view('admin.championships.matches-builder', compact('championship', 'courts', 'stages', 'teamsPayload', 'courtsPayload'));
    }

    /**
     * Bulk-create matches from the builder (AJAX)
     */
    public function storeBulkMatches(StoreBulkMatchesRequest $request, Championship $championship)
    {
        $this->championshipService->createBulkMatches($championship, $request->validated());

        return response()->json([
            'success' => true,
            'message' => __('Matches created successfully'),
            'redirect_url' => route('admin.championships.show', $championship->id),
        ]);
    }

    /**
     * Get teams for select (AJAX)
     */
    public function getTeams(Championship $championship)
    {
        $teams = $championship->teams()
            ->where('is_confirmed', true)
            ->with('members')
            ->get(['id', 'championship_id', 'name', 'logo']);

        return response()->json([
            'success' => true,
            'data' => $teams,
        ]);
    }
}
