<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Backup;
use App\Models\BackupActivityLog;
use App\Models\User;
use App\Models\Setting;
use App\Notifications\BackupDeleted;
use App\Services\BackupService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Notification;

class BackupController extends Controller
{
    protected $backupService;

    public function __construct(BackupService $backupService)
    {
        $this->backupService = $backupService;
    }

    /**
     * Lista backup-uri
     */
    public function index()
    {
        $backups = Backup::with('creator')
            ->latest()
            ->paginate(20);

        $stats = [
            'total' => Backup::count(),
            'total_size' => Backup::sum('file_size'),
            'last_backup' => Backup::latest()->first(),
        ];

        return view('admin.backups.index', compact('backups', 'stats'));
    }

    /**
     * Jurnal activitate backup-uri
     */
    public function activityLog()
    {
        $activities = BackupActivityLog::with(['backup', 'user'])
            ->latest()
            ->paginate(50);

        return view('admin.backups.activity-log', compact('activities'));
    }

    /**
     * Creează backup nou
     */
    public function store(Request $request)
    {
        $request->validate([
            'type' => 'required|in:full,incremental',
            'include_database' => 'boolean',
            'include_files' => 'boolean',
        ]);

        try {
            $backup = $this->backupService->createBackup([
                'type' => $request->type,
                'include_database' => $request->boolean('include_database', true),
                'include_files' => $request->boolean('include_files', true),
                'created_by' => auth()->id(),
            ]);

            return redirect()->route('admin.backups.index')
                ->with('success', 'Backup creat cu succes!');

        } catch (\Exception $e) {
            return back()->with('error', 'Eroare: ' . $e->getMessage());
        }
    }

    /**
     * Descarcă backup
     */
    public function download(Backup $backup)
    {
        if (!$backup->exists()) {
            return back()->with('error', 'Fișierul de backup nu există');
        }

        // Log activitate download
        BackupActivityLog::logActivity(
            backupId: $backup->id,
            action: 'downloaded',
            userId: auth()->id(),
            userName: auth()->user()->name,
            ipAddress: request()->ip(),
            details: [
                'filename' => $backup->filename,
                'size' => $backup->file_size_human,
            ]
        );

        // Folosim calea completă pentru download
        return response()->download($backup->getFullPath(), $backup->filename);
    }

    /**
     * Șterge backup
     */
    public function destroy(Backup $backup)
    {
        try {
            // Salvează datele backup-ului înainte de ștergere
            $backupData = [
                'id' => $backup->id,
                'filename' => $backup->filename,
                'size' => $backup->file_size_human,
                'type' => $backup->type,
                'created_at' => $backup->created_at->format('d.m.Y H:i:s'),
            ];

            // Log activitate delete înainte de ștergere (cu toate detaliile)
            BackupActivityLog::logActivity(
                backupId: $backup->id,
                action: 'deleted',
                userId: auth()->id(),
                userName: auth()->user()->name,
                ipAddress: request()->ip(),
                details: $backupData
            );

            // Trimite notificare către adresele configurate sau către admini
            $emailsString = Setting::get('backup_notification_emails', '');

            if (!empty($emailsString)) {
                // Trimite către adresele configurate
                $emails = array_map('trim', explode(',', $emailsString));
                $emails = array_filter($emails);

                foreach ($emails as $email) {
                    if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
                        Notification::route('mail', $email)->notify(new BackupDeleted($backupData, request()->ip()));
                    }
                }
            } else {
                // Fallback: trimite către toți adminii
                $admins = User::where('role', 'admin')->get();
                foreach ($admins as $admin) {
                    $admin->notify(new BackupDeleted($backupData, request()->ip()));
                }
            }

            $backup->delete();
            return redirect()->route('admin.backups.index')
                ->with('success', 'Backup șters cu succes');
        } catch (\Exception $e) {
            return back()->with('error', 'Eroare: ' . $e->getMessage());
        }
    }

    /**
     * Restore backup
     */
    public function restore(Backup $backup)
    {
        if ($backup->status !== 'completed') {
            return back()->with('error', 'Doar backup-urile completate pot fi restaurate');
        }

        try {
            $this->backupService->restoreBackup($backup, auth()->id());

            return redirect()->route('admin.backups.index')
                ->with('success', 'Backup restaurat cu succes!');

        } catch (\Exception $e) {
            return back()->with('error', 'Eroare la restore: ' . $e->getMessage());
        }
    }

    /**
     * Bulk delete backups
     */
    public function bulkDelete(Request $request)
    {
        $request->validate([
            'backup_ids' => 'required|array|max:50',
            'backup_ids.*' => 'required|integer|exists:backups,id',
        ]);

        $backupIds = $request->input('backup_ids');
        $deletedCount = 0;
        $errors = [];

        try {
            $backups = Backup::whereIn('id', $backupIds)->get();

            foreach ($backups as $backup) {
                try {
                    // Șterge fișierul fizic
                    if ($backup->destination === 'local' && Storage::disk('local')->exists($backup->path)) {
                        Storage::disk('local')->delete($backup->path);
                    } elseif ($backup->destination === 's3' && Storage::disk('s3')->exists($backup->path)) {
                        Storage::disk('s3')->delete($backup->path);
                    }

                    // Salvează datele pentru log
                    $backupData = [
                        'id' => $backup->id,
                        'filename' => $backup->filename,
                        'size' => $backup->file_size,
                        'type' => $backup->type,
                    ];

                    // Înregistrează în log (FĂRĂ email notification)
                    BackupActivityLog::create([
                        'backup_id' => null, // null pentru că backup-ul va fi șters
                        'user_id' => auth()->id(),
                        'action' => 'deleted',
                        'user_name' => auth()->user()->name,
                        'ip_address' => $request->ip(),
                        'details' => $backupData,
                    ]);

                    // Șterge backup-ul din baza de date
                    $backup->delete();
                    $deletedCount++;
                } catch (\Exception $e) {
                    $errors[] = "Eroare la ștergerea backup-ului #{$backup->id}: " . $e->getMessage();
                }
            }

            if ($deletedCount > 0) {
                $message = $deletedCount === 1
                    ? '1 backup șters cu succes'
                    : "{$deletedCount} backup-uri șterse cu succes";

                if (!empty($errors)) {
                    $message .= ', dar au apărut ' . count($errors) . ' erori.';
                }

                return redirect()->route('admin.backups.index')
                    ->with('success', $message)
                    ->with('errors', $errors);
            } else {
                return back()->with('error', 'Nu s-a putut șterge niciun backup. ' . implode(' ', $errors));
            }
        } catch (\Exception $e) {
            return back()->with('error', 'Eroare la ștergerea în masă: ' . $e->getMessage());
        }
    }

    /**
     * Afișează detaliile unui backup
     */
    public function show(Backup $backup)
    {
        $backup->load(['creator', 'restorations.user']);
        return view('admin.backups.show', compact('backup'));
    }

    /**
     * Lista programări backup
     */
    public function schedules()
    {
        $schedules = \App\Models\BackupSchedule::latest()->get();
        return view('admin.backups.schedules', compact('schedules'));
    }

    /**
     * Creează programare backup
     */
    public function storeSchedule(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'type' => 'required|in:full,zones,database',
            'frequency' => 'required|in:daily,weekly,monthly',
            'time' => 'required|date_format:H:i',
            'day_of_week' => 'nullable|integer|between:0,6',
            'day_of_month' => 'nullable|integer|between:1,28',
            'retention_days' => 'required|integer|min:1|max:365',
            'enabled' => 'boolean',
        ]);

        $schedule = \App\Models\BackupSchedule::create($validated);
        $schedule->calculateNextRun();

        return response()->json([
            'success' => true,
            'message' => 'Programare creată cu succes',
            'schedule' => $schedule
        ]);
    }

    /**
     * Actualizează programare backup
     */
    public function updateSchedule(Request $request, \App\Models\BackupSchedule $schedule)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'type' => 'required|in:full,zones,database',
            'frequency' => 'required|in:daily,weekly,monthly',
            'time' => 'required|date_format:H:i',
            'day_of_week' => 'nullable|integer|between:0,6',
            'day_of_month' => 'nullable|integer|between:1,28',
            'retention_days' => 'required|integer|min:1|max:365',
            'enabled' => 'boolean',
        ]);

        $schedule->update($validated);
        $schedule->calculateNextRun();

        return response()->json([
            'success' => true,
            'message' => 'Programare actualizată cu succes'
        ]);
    }

    /**
     * Toggle status programare
     */
    public function toggleSchedule(Request $request, \App\Models\BackupSchedule $schedule)
    {
        $schedule->update([
            'enabled' => $request->boolean('enabled')
        ]);

        if ($schedule->enabled) {
            $schedule->calculateNextRun();
        }

        return response()->json([
            'success' => true,
            'message' => $schedule->enabled ? 'Programare activată' : 'Programare dezactivată'
        ]);
    }

    /**
     * Șterge programare backup
     */
    public function destroySchedule(\App\Models\BackupSchedule $schedule)
    {
        $schedule->delete();

        return response()->json([
            'success' => true,
            'message' => 'Programare ștearsă cu succes'
        ]);
    }
}
