<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreCandidateRequest;
use App\Http\Requests\UpdateCandidateRequest;
use App\Models\Candidate;
use App\Models\Division;
use App\Models\Role;
use App\Models\Seat;
use App\Models\Team;
use App\Models\TeamMember;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class CandidateController extends Controller
{
    public function index(Request $request)
{
    $perPage = (int) $request->input('per_page', 20);

    $query = Candidate::query()
        ->with([
            'user',
            'seat.district.division',
            'seat.upazila', 
        ]);

    // Seat
    if ($request->filled('seat_id')) {
        $query->where('seat_id', $request->seat_id);
    }

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

    // Area type
    if ($request->filled('area_type')) {
        $query->where('area_type', $request->area_type);
    }

    // Division (via seat -> district -> division)
    if ($request->filled('division')) {
        $query->whereHas('seat.district.division', function ($q) use ($request) {
            $q->where('id', $request->division);
        });
    }

    // District (via seat -> district)
    if ($request->filled('district')) {
        $query->whereHas('seat.district', function ($q) use ($request) {
            $q->where('id', $request->district);
        });
    }

    // Upazila (via seat.upazila_id)
    if ($request->filled('upazila_id')) {
        $query->whereHas('seat', function ($q) use ($request) {
            $q->where('upazila_id', $request->upazila_id);
        });
    }

    $candidates = $query
        ->latest()
        ->paginate($perPage)
        ->withQueryString();

    $divisions = Division::with('districts.upazilas')
        ->orderBy('name_bn')
        ->get();

    $seatsForFilter = Seat::query()
        ->select(['id', 'name_bn', 'seat_code', 'district_id', 'upazila_id'])
        ->orderBy('name_bn')
        ->get();

    return view('candidates.index', [
        'candidates'     => $candidates,

        
        'seats'          => Seat::orderBy('name_bn')->get(),

        'divisions'      => $divisions,
        'seatsForFilter' => $seatsForFilter,
    ]);
}




    public function create()
    {
        $users = User::select('id', 'name')->whereDoesntHave('candidate')->orderBy('name')->get();

        $seats = Seat::select('id', 'name_bn', 'seat_code', 'district_id', 'upazila_id', 'city_id')
            ->with(['district.division:id,name_bn', 'district:id,division_id,name_bn', 'upazila:id,name_bn', 'city:id,name_bn'])
            ->orderBy('id')
            ->get();

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

    public function store(Request $request)
{
    $data = $request->validate([
        'candidate_id'     => ['required', 'exists:candidates,id'],
        'name'             => ['required', 'string', 'max:255'],
        'manager_user_id'  => ['required', 'exists:users,id'],
        'description'      => ['nullable', 'string'],
    ]);

    $data['status'] = 'active';

    DB::transaction(function () use ($data) {

        // 1️⃣ Create Team
        $team = Team::create([
            'candidate_id'     => $data['candidate_id'],
            'name'             => $data['name'],
            'description'      => $data['description'] ?? null,
            'manager_user_id'  => $data['manager_user_id'],
            'status'           => 'active',
        ]);

        // 2️⃣ Get Manager Role ID safely
        $managerRoleId = Role::where('slug', 'manager')->value('id');

        if (!$managerRoleId) {
            throw new \Exception('Manager role not found in roles table.');
        }

        // 3️⃣ Attach manager as team member
        TeamMember::firstOrCreate(
            [
                'team_id' => $team->id,
                'user_id' => $team->manager_user_id,
            ],
            [
                'role_id'    => $managerRoleId,
                'is_manager' => true,
                'joined_at'  => now(),
                'status'     => 'active',
            ]
        );
    });

    return redirect()
        ->route('teams.index')
        ->with('success', 'টিম সফলভাবে তৈরি করা হয়েছে');
}

    public function show(Candidate $candidate)
    {
        $candidate->load(['user:id,name,phone', 'seat:id,name_bn,name_en,seat_code,seat_type,district_id,upazila_id,city_id', 'seat.district:id,division_id,name_bn', 'seat.district.division:id,name_bn', 'seat.upazila:id,name_bn', 'seat.city:id,name_bn']);

        return view('candidates.show', compact('candidate'));
    }

    public function edit(Candidate $candidate)
    {
        $users = User::select('id', 'name')->where('id', $candidate->user_id)->orWhereDoesntHave('candidate')->orderBy('name')->get();

        $seats = Seat::select('id', 'name_bn', 'seat_code', 'seat_type', 'district_id', 'upazila_id', 'city_id')
            ->with(['district:id,division_id,name_bn', 'district.division:id,name_bn', 'upazila:id,name_bn', 'city:id,name_bn'])
            ->orderBy('id')
            ->get();

        return view('candidates.edit', compact('candidate', 'users', 'seats'));
    }

    public function update(UpdateCandidateRequest $request, Candidate $candidate)
    {
        $data = $request->validated();

        $raw = preg_replace('/\s+/', '', (string) ($data['nid_number'] ?? ''));
        $nidEn = preg_replace('/\D/', '', $this->bnToEnDigits($raw));
        $nidBn = $this->enToBnDigits($nidEn);

        if ($nidEn && Candidate::where('nid_number_en', $nidEn)->where('id', '!=', $candidate->id)->exists()) {
            return back()
                ->withErrors(['nid_number' => 'এই এনআইডি নম্বরটি ইতিমধ্যে ব্যবহৃত হয়েছে।'])
                ->withInput();
        }

        $data['nid_number_en'] = $nidEn ?: null;
        $data['nid_number_bn'] = $nidBn ?: null;
        unset($data['nid_number']);

        if (isset($data['previous_experience']) && is_string($data['previous_experience'])) {
            $data['previous_experience'] = [$data['previous_experience']];
        }

        if ($request->hasFile('photo')) {
            if ($candidate->photo) {
                Storage::disk('public')->delete($candidate->photo);
            }
            $data['photo'] = $request->file('photo')->store('candidate-photos', 'public');
        }

        if ($request->hasFile('symbol_photo')) {
            if ($candidate->symbol_photo) {
                Storage::disk('public')->delete($candidate->symbol_photo);
            }
            $data['symbol_photo'] = $request->file('symbol_photo')->store('candidate-symbols', 'public');
        }

        $candidate->update($data);

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

    public function destroy(Candidate $candidate)
    {
        if ($candidate->photo) {
            Storage::disk('public')->delete($candidate->photo);
        }
        if ($candidate->symbol_photo) {
            Storage::disk('public')->delete($candidate->symbol_photo);
        }

        $candidate->delete();

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

    private function bnToEnDigits(string $value): string
    {
        return strtr($value, [
            '০' => '0',
            '১' => '1',
            '২' => '2',
            '৩' => '3',
            '৪' => '4',
            '৫' => '5',
            '৬' => '6',
            '৭' => '7',
            '৮' => '8',
            '৯' => '9',
        ]);
    }

    private function enToBnDigits(string $value): string
    {
        return strtr($value, [
            '0' => '০',
            '1' => '১',
            '2' => '২',
            '3' => '৩',
            '4' => '৪',
            '5' => '৫',
            '6' => '৬',
            '7' => '৭',
            '8' => '৮',
            '9' => '৯',
        ]);
    }
}
