<?php

namespace App\Http\Controllers;

use App\Models\Seat;
use App\Http\Requests\StoreSeatRequest;
use App\Http\Requests\UpdateSeatRequest;
use App\Models\Candidate;
use App\Models\District;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;

class SeatController extends Controller
{
    public function index(Request $request)
    {
        $query = Seat::query();

        if ($request->filled('search')) {
            $s = trim($request->string('search')->toString());
            $query->where(function ($q) use ($s) {
                $q->where('name_bn', 'like', "%{$s}%")
                    ->orWhere('name_en', 'like', "%{$s}%")
                    ->orWhere('seat_code', 'like', "%{$s}%");
            });
        }

        if ($request->filled('seat_type')) {
            $query->where('seat_type', $request->string('seat_type')->toString());
        }

        if ($request->filled('status')) {
            $query->where('status', $request->string('status')->toString());
        }

        $perPage = (int) $request->input('per_page', 20);
        $perPage = in_array($perPage, [20, 50, 100], true) ? $perPage : 20;

        $seats = $query
            ->withCount('candidates')

            ->latest('id')
            ->paginate($perPage)
            ->withQueryString();

        return view('seats.index', compact('seats'));
    }

    public function create()
    {
        $districts = District::orderBy('name_bn')->get(['id', 'name_bn']);

        return view('seats.create', compact('districts'));
    }

    public function store(StoreSeatRequest $request)
    {
        $data = $request->validated();

        $data['total_voters'] = (int) ($data['male_voters'] ?? 0) + (int) ($data['female_voters'] ?? 0) + (int) ($data['other_voters'] ?? 0);

        Seat::create($data);

        return redirect()->route('seats.index')->with('success', 'সীট সফলভাবে তৈরি করা হয়েছে।');
    }

    public function show(Seat $seat)
    {
        $seat->load(['district:id,division_id,name_bn', 'district.division:id,name_bn', 'upazila:id,name_bn', 'city:id,name_bn', 'candidates.user:id,name']);

        return view('seats.show', compact('seat'));
    }

    public function edit(Seat $seat)
    {
        $districts = District::orderBy('name_bn')->get();

        return view('seats.edit', compact('seat', 'districts'));
    }
    public function update(UpdateSeatRequest $request, Seat $seat)
    {
        $data = $request->validated();

        $data['total_voters'] = (int) ($data['male_voters'] ?? 0) + (int) ($data['female_voters'] ?? 0) + (int) ($data['other_voters'] ?? 0);

        $seat->update($data);

        return redirect()->route('seats.index')->with('success', 'সীট তথ্য সফলভাবে আপডেট করা হয়েছে।');
    }

    public function destroy(Seat $seat)
    {
        if ($seat->candidates()->exists()) {
            return redirect()->route('seats.index')->with('error', 'এই সীটে প্রার্থী আছে। আগে প্রার্থী সরান।');
        }

        $seat->delete();

        return redirect()->route('seats.index')->with('success', 'সীট সফলভাবে মুছে ফেলা হয়েছে।');
    }

    public function statistics()
    {
        $seatTable = (new Seat)->getTable();


        $hasIsActive = Schema::hasColumn($seatTable, 'is_active');
        $hasStatus = Schema::hasColumn($seatTable, 'status');

        $votersCol = null;
        foreach (['total_voters', 'voters', 'voter_count'] as $col) {
            if (Schema::hasColumn($seatTable, $col)) {
                $votersCol = $col;
                break;
            }
        }

        $totalSeats = Seat::count();

        if ($hasIsActive) {
            $activeSeats = Seat::where('is_active', 1)->count();
        } elseif ($hasStatus) {
            $activeSeats = Seat::where('status', 'active')->count();
        } else {
            $activeSeats = $totalSeats;
        }

        $totalVoters = 0;
        if ($votersCol) {
            $totalVoters = (int) Seat::sum($votersCol);
        }

        $totalCandidates = Candidate::count();

        $divisions = \App\Models\Division::query()
            ->select(['divisions.id', 'divisions.name_bn'])
            ->selectRaw('COUNT(seats.id) as seat_count')
            ->when(
                $votersCol,
                function ($q) use ($votersCol) {
                    $q->selectRaw('COALESCE(SUM(seats.' . $votersCol . '),0) as voters');
                },
                function ($q) {
                    $q->selectRaw('0 as voters');
                },
            )
            ->leftJoin('districts', 'districts.division_id', '=', 'divisions.id')
            ->leftJoin('seats', 'seats.district_id', '=', 'districts.id')
            ->groupBy('divisions.id', 'divisions.name_bn')
            ->orderBy('divisions.name_bn')
            ->get();

        $seatTypes = Seat::query()
            ->select('seat_type')
            ->selectRaw('COUNT(*) as count')
            ->groupBy('seat_type')
            ->orderByRaw(
                "CASE
                WHEN seat_type='parliament' THEN 1
                WHEN seat_type='city_corp' THEN 2
                WHEN seat_type='pouroshova' THEN 3
                WHEN seat_type='union' THEN 4
                WHEN seat_type='local' THEN 5
                ELSE 99 END",
            )
            ->get();

        $areaTypes = collect([
            (object) [
                'area_type' => 'city',
                'count' => Seat::whereNotNull('city_id')->count(),
            ],
            (object) [
                'area_type' => 'upazila',
                'count' => Seat::whereNotNull('upazila_id')->count(),
            ],
        ])
            ->filter(fn($x) => (int) $x->count > 0)
            ->values();

        return view('seats.statistics', compact('totalSeats', 'activeSeats', 'totalVoters', 'totalCandidates', 'divisions', 'seatTypes', 'areaTypes'));
    }
}
