<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Interview;
use App\Models\JobApplication;
use App\Models\SiteSetting;
use App\Models\User;
use App\Notifications\InterviewStatusChangedNotification;
use App\Services\GoogleCalendarService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rules\Password;

class InterviewController extends Controller
{
    public function index(Request $request)
    {
        $tab = $request->input('tab', 'active'); // active | completed | cancelled | rescheduled
        $interviewerFilter = $request->input('interviewer_id');
        $dateFrom = $request->input('date_from');
        $dateTo   = $request->input('date_to');

        // ─── Aktif görüşmeler (Planlandı + Yeniden Planlandı) ───────────────
        $activeQuery = Interview::with(['application', 'jobPosting', 'interviewer'])
            ->whereIn('status', ['scheduled', 'rescheduled'])
            ->orderBy('scheduled_at');
        if ($interviewerFilter) $activeQuery->where('interviewer_id', $interviewerFilter);
        if ($dateFrom) $activeQuery->whereDate('scheduled_at', '>=', $dateFrom);
        if ($dateTo)   $activeQuery->whereDate('scheduled_at', '<=', $dateTo);
        $activeInterviews = $activeQuery->paginate(25, ['*'], 'active_page');

        // ─── Tamamlanmış görüşmeler ──────────────────────────────────────────
        $completedQuery = Interview::with(['application', 'jobPosting', 'interviewer'])
            ->where('status', 'completed')
            ->orderByDesc('scheduled_at');
        if ($interviewerFilter) $completedQuery->where('interviewer_id', $interviewerFilter);
        if ($dateFrom) $completedQuery->whereDate('scheduled_at', '>=', $dateFrom);
        if ($dateTo)   $completedQuery->whereDate('scheduled_at', '<=', $dateTo);
        $completedInterviews = $completedQuery->paginate(15, ['*'], 'completed_page');

        // ─── Yeniden planlanmış görüşmeler ──────────────────────────────────
        $rescheduledQuery = Interview::with(['application', 'jobPosting', 'interviewer'])
            ->where('status', 'rescheduled')
            ->orderBy('scheduled_at');
        if ($interviewerFilter) $rescheduledQuery->where('interviewer_id', $interviewerFilter);
        if ($dateFrom) $rescheduledQuery->whereDate('scheduled_at', '>=', $dateFrom);
        if ($dateTo)   $rescheduledQuery->whereDate('scheduled_at', '<=', $dateTo);
        $rescheduledInterviews = $rescheduledQuery->paginate(15, ['*'], 'rescheduled_page');

        // ─── İptal edilmiş görüşmeler ────────────────────────────────────────
        $cancelledQuery = Interview::with(['application', 'jobPosting', 'interviewer'])
            ->where('status', 'cancelled')
            ->orderByDesc('scheduled_at');
        if ($interviewerFilter) $cancelledQuery->where('interviewer_id', $interviewerFilter);
        if ($dateFrom) $cancelledQuery->whereDate('scheduled_at', '>=', $dateFrom);
        if ($dateTo)   $cancelledQuery->whereDate('scheduled_at', '<=', $dateTo);
        $cancelledInterviews = $cancelledQuery->paginate(15, ['*'], 'cancelled_page');

        // ─── İstatistikler ───────────────────────────────────────────────────
        $stats = [
            'scheduled'   => Interview::where('status', 'scheduled')->count(),
            'rescheduled' => Interview::where('status', 'rescheduled')->count(),
            'completed'   => Interview::where('status', 'completed')->count(),
            'cancelled'   => Interview::where('status', 'cancelled')->count(),
        ];

        $interviewers = User::permission('manage interviews')->get();
        $allUsers     = User::orderBy('name')->get();

        return view('admin.gorusmeler.index', compact(
            'activeInterviews', 'completedInterviews', 'rescheduledInterviews', 'cancelledInterviews',
            'stats', 'tab', 'interviewers', 'allUsers'
        ));
    }

    public function create(Request $request)
    {
        $application  = null;
        $interviewers = User::permission('manage interviews')->get();
        $prefilledDate = $request->input('date'); // ?date=2026-07-15T09:00

        if ($request->filled('application_id')) {
            $application = JobApplication::with('jobPosting')->findOrFail($request->application_id);
        }

        return view('admin.gorusmeler.create', compact('application', 'interviewers', 'prefilledDate'));
    }

    public function getInterviewsByDate(Request $request)
    {
        $request->validate(['date' => 'required|date_format:Y-m-d']);

        $date = $request->input('date');

        $interviews = Interview::with(['application', 'interviewer'])
            ->whereDate('scheduled_at', $date)
            ->whereNotIn('status', ['cancelled'])
            ->orderBy('scheduled_at')
            ->get()
            ->map(function ($interview) {
                return [
                    'id'             => $interview->id,
                    'title'          => $interview->title,
                    'scheduled_at'   => $interview->scheduled_at->format('H:i'),
                    'duration'       => $interview->duration_minutes,
                    'status'         => $interview->status,
                    'status_label'   => $interview->status_label ?? $interview->status,
                    'applicant_name' => $interview->application->full_name ?? '—',
                    'interviewer'    => $interview->interviewer->name ?? '—',
                    'url'            => route('admin.gorusmeler.show', $interview->id),
                ];
            });

        return response()->json($interviews);
    }

    public function store(Request $request)
    {
        $request->validate([
            'job_application_id' => 'nullable|exists:job_applications,id',
            'candidate_name'     => 'nullable|string|max:255',
            'candidate_email'    => 'nullable|email|max:255',
            'title'              => 'required|string|max:200',
            'scheduled_at'       => 'required|date|after:now',
            'duration_minutes'   => 'integer|min:15|max:480',
            'location'           => 'nullable|string|max:200',
            'meeting_link'       => 'nullable|url|max:500',
            'notes'              => 'nullable|string|max:2000',
            'interviewer_id'     => 'nullable|exists:users,id',
        ]);

        $application = $request->job_application_id
            ? JobApplication::find($request->job_application_id)
            : null;

        $interview = Interview::create([
            'job_application_id' => $application?->id,
            'job_posting_id'     => $application?->job_posting_id,
            'interviewer_id'     => $request->interviewer_id ?? auth()->id(),
            // Başvuru varsa başvurudan al, yoksa manuel girilen bilgileri kullan
            'candidate_name'     => $application?->full_name ?? $request->candidate_name,
            'candidate_email'    => $application?->email ?? $request->candidate_email,
            'title'              => $request->title,
            'scheduled_at'       => $request->scheduled_at,
            'duration_minutes'   => $request->duration_minutes ?? 60,
            'location'           => $request->location,
            'meeting_link'       => $request->meeting_link,
            'notes'              => $request->notes,
            'status'             => 'scheduled',
        ]);

        // Google Calendar entegrasyonu
        $this->syncToGoogleCalendar($interview, 'create');

        // Başvuru varsa durumunu güncelle
        if ($interview->application) {
            $interview->application->update(['status' => 'görüşmeye_çağrıldı']);
        }

        return redirect()->route('admin.gorusmeler.show', $interview)
            ->with('success', 'Görüşme planlandı.');
    }

    public function show(Interview $gorusme)
    {
        $gorusme->load(['application.jobPosting', 'interviewer']);
        return view('admin.gorusmeler.show', compact('gorusme'));
    }

    public function edit(Interview $gorusme)
    {
        $interviewers = User::permission('manage interviews')->get();
        return view('admin.gorusmeler.edit', compact('gorusme', 'interviewers'));
    }

    public function update(Request $request, Interview $gorusme)
    {
        $request->validate([
            'title'            => 'required|string|max:200',
            'scheduled_at'     => 'required|date',
            'duration_minutes' => 'integer|min:15|max:480',
            'location'         => 'nullable|string|max:200',
            'meeting_link'     => 'nullable|url|max:500',
            'notes'            => 'nullable|string|max:2000',
            'interviewer_id'   => 'nullable|exists:users,id',
            'status'           => 'required|in:scheduled,completed,cancelled,rescheduled',
        ]);

        $oldStatus = $gorusme->status;
        $newStatus = $request->status;

        $gorusme->update($request->only([
            'title', 'scheduled_at', 'duration_minutes',
            'location', 'meeting_link', 'notes', 'interviewer_id', 'status',
        ]));

        $this->syncToGoogleCalendar($gorusme, 'update');

        // Durum değiştiyse ve e-posta bildirimi açıksa başvurana bildir
        if ($oldStatus !== $newStatus) {
            $emailEnabled = SiteSetting::where('key', 'interview_email_notifications')->value('value');
            if ($emailEnabled === '1' || $emailEnabled === 'true') {
                try {
                    $gorusme->load('application');
                    $applicantEmail = $gorusme->application->email ?? null;
                    if ($applicantEmail) {
                        \Illuminate\Support\Facades\Notification::route('mail', $applicantEmail)
                            ->notify(new InterviewStatusChangedNotification($gorusme, $oldStatus, $newStatus));
                    }
                } catch (\Exception $e) {
                    Log::warning('Interview status notification failed: ' . $e->getMessage());
                }
            }
        }

        $statusLabels = [
            'scheduled'   => 'Görüşme planlandı olarak işaretlendi.',
            'completed'   => 'Görüşme tamamlandı olarak işaretlendi.',
            'cancelled'   => 'Görüşme iptal edildi.',
            'rescheduled' => 'Görüşme yeniden planlandı.',
        ];
        $msg = $oldStatus !== $newStatus
            ? ($statusLabels[$newStatus] ?? 'Görüşme güncellendi.')
            : 'Görüşme güncellendi.';

        return back()->with('success', $msg);
    }

    public function destroy(Interview $gorusme)
    {
        $this->syncToGoogleCalendar($gorusme, 'delete');
        $gorusme->delete();

        return redirect()->route('admin.gorusmeler.index')
            ->with('success', 'Görüşme silindi.');
    }

    public function calendar()
    {
        // Veritabanındaki görüşmeler (mavi/yeşil/sarı)
        $dbEvents = Interview::with(['application', 'interviewer'])
            ->whereNotNull('status')
            ->where('status', '!=', 'cancelled')
            ->get()
            ->map(function ($interview) {
                return [
                    'id'    => 'db_' . $interview->id,
                    'title' => $interview->title . ' — ' . ($interview->application->full_name ?? ''),
                    'start' => $interview->scheduled_at->toIso8601String(),
                    'end'   => $interview->scheduled_at->copy()->addMinutes($interview->duration_minutes)->toIso8601String(),
                    'url'   => route('admin.gorusmeler.show', $interview),
                    'color' => match ($interview->status) {
                        'scheduled'   => '#3b82f6',
                        'completed'   => '#22c55e',
                        'rescheduled' => '#f59e0b',
                        default       => '#6b7280',
                    },
                    'extendedProps' => [
                        'source'        => 'db',
                        'status'        => $interview->status,
                        'applicantName' => $interview->application->full_name ?? null,
                        'duration'      => $interview->duration_minutes,
                        'location'      => $interview->location,
                        'meetingLink'   => $interview->meeting_link,
                        'notes'         => $interview->notes,
                        'interviewerId' => $interview->interviewer_id,
                    ],
                ];
            })->toArray();

        // Google Calendar etkinlikleri (gri — sadece entegrasyon aktifse)
        $googleEvents = [];
        $googleConnected = false;

        try {
            $calendarService = app(GoogleCalendarService::class);
            if ($calendarService->isEnabled()) {
                $googleConnected = true;
                $timeMin = now()->startOfMonth()->subMonth()->toRfc3339String();
                $timeMax = now()->endOfMonth()->addMonths(3)->toRfc3339String();

                $rawEvents = $calendarService->listEvents($timeMin, $timeMax);

                // Veritabanındaki google_event_id'leri topla (çakışmayı önlemek için)
                $dbGoogleIds = Interview::whereNotNull('google_event_id')
                    ->pluck('google_event_id')
                    ->toArray();

                foreach ($rawEvents as $gEvent) {
                    // Zaten DB'de olan etkinlikleri atla (zaten mavi gösteriliyor)
                    if (in_array($gEvent['id'] ?? '', $dbGoogleIds)) {
                        continue;
                    }

                    $start = $gEvent['start']['dateTime'] ?? $gEvent['start']['date'] ?? null;
                    $end   = $gEvent['end']['dateTime']   ?? $gEvent['end']['date']   ?? null;

                    if (!$start) continue;

                    $googleEvents[] = [
                        'id'            => 'gcal_' . ($gEvent['id'] ?? uniqid()),
                        'title'         => '📅 ' . ($gEvent['summary'] ?? 'Google Etkinliği'),
                        'start'         => $start,
                        'end'           => $end,
                        'color'         => '#9ca3af',
                        'url'           => $gEvent['htmlLink'] ?? null,
                        'extendedProps' => ['source' => 'google'],
                    ];
                }
            }
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::warning('Calendar: Google events fetch failed: ' . $e->getMessage());
        }

        $interviews = array_merge($dbEvents, $googleEvents);
        $allUsers   = User::orderBy('name')->get();

        return view('admin.gorusmeler.calendar', compact('interviews', 'googleConnected', 'allUsers'));
    }

    public function storeGorusmeci(Request $request)
    {
        $mode = $request->input('mode', 'existing'); // 'existing' veya 'new'

        if ($mode === 'existing') {
            // Mevcut kullanıcıya görüşmeci yetkisi ver
            $request->validate([
                'existing_user_id' => 'required|exists:users,id',
            ], [
                'existing_user_id.required' => 'Lütfen bir kullanıcı seçin.',
                'existing_user_id.exists'   => 'Seçilen kullanıcı bulunamadı.',
            ]);

            $user = User::findOrFail($request->existing_user_id);

            // Zaten yetkisi varsa bildir
            if ($user->hasPermissionTo('manage interviews')) {
                return redirect()->route('admin.gorusmeler.index')
                    ->with('success', $user->name . ' zaten görüşmeci yetkisine sahip.');
            }

            if (\Spatie\Permission\Models\Role::where('name', 'interviewer')->exists()) {
                $user->assignRole('interviewer');
            } else {
                $user->givePermissionTo('manage interviews');
            }

            return redirect()->route('admin.gorusmeler.index')
                ->with('success', $user->name . ' görüşmeci olarak atandı.');

        } else {
            // Yeni kullanıcı oluştur
            $request->validate([
                'name'     => 'required|string|max:255',
                'email'    => 'required|email|unique:users,email',
                'password' => ['required', 'confirmed', Password::min(8)],
            ], [
                'name.required'      => 'Ad Soyad zorunludur.',
                'email.required'     => 'E-posta zorunludur.',
                'email.unique'       => 'Bu e-posta adresi zaten kayıtlı.',
                'password.required'  => 'Şifre zorunludur.',
                'password.confirmed' => 'Şifreler eşleşmiyor.',
            ]);

            $user = User::create([
                'name'     => $request->name,
                'email'    => $request->email,
                'password' => Hash::make($request->password),
            ]);

            if (\Spatie\Permission\Models\Role::where('name', 'interviewer')->exists()) {
                $user->assignRole('interviewer');
            } else {
                $user->givePermissionTo('manage interviews');
            }

            return redirect()->route('admin.gorusmeler.index')
                ->with('success', $request->name . ' görüşmeci olarak oluşturuldu ve eklendi.');
        }
    }

    protected function syncToGoogleCalendar(Interview $interview, string $action): void
    {
        try {
            $calendarService = app(GoogleCalendarService::class);

            if (!$calendarService->isEnabled()) {
                return;
            }

            if ($action === 'delete') {
                if ($interview->google_event_id) {
                    $user = $interview->interviewer ?? auth()->user();
                    $calendarService->deleteEvent(
                        $interview->google_event_id,
                        $user,
                        $interview->google_calendar_id
                    );
                }
                return;
            }

            match ($action) {
                'create' => $calendarService->createEvent($interview),
                'update' => $calendarService->updateEvent($interview),
                default  => null,
            };
        } catch (\Exception $e) {
            Log::warning('Google Calendar sync failed: ' . $e->getMessage());
        }
    }

    public function searchApplications(Request $request)
    {
        $q = $request->input('q', '');

        $applications = JobApplication::with('jobPosting')
            ->when($q, function ($query) use ($q) {
                $query->where(function ($sub) use ($q) {
                    $sub->where('full_name', 'like', "%{$q}%")
                        ->orWhere('email', 'like', "%{$q}%")
                        ->orWhereHas('jobPosting', function ($jp) use ($q) {
                            $jp->where('title', 'like', "%{$q}%");
                        });
                });
            })
            ->whereNotIn('status', ['reddedildi', 'işe_alındı'])
            ->orderByDesc('created_at')
            ->limit(50)
            ->get()
            ->map(function ($app) {
                return [
                    'id'          => $app->id,
                    'full_name'   => $app->full_name,
                    'email'       => $app->email,
                    'position'    => $app->jobPosting->title ?? 'Genel Başvuru',
                    'status'      => $app->status,
                    'created_at'  => $app->created_at->format('d.m.Y'),
                ];
            });

        return response()->json($applications);
    }
}
