<?php

namespace App\Services;

use App\Mail\RanchCalvingReportMail;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Throwable;

class RanchCalvingReportNotificationService
{
    public function __construct(
        private readonly RanchCalvingReportService $calvingReportService,
        private readonly RanchWeightAlertNotificationService $recipientService,
    ) {}

    /**
     * @param  array<string, mixed>  $filters
     * @return array{sent: bool, calvings_count: int, recipients: list<string>, message: string, from: ?string, to: ?string}
     */
    public function send(array $filters = [], bool $usePreviousMonth = false): array
    {
        $from = isset($filters['from']) ? Carbon::parse($filters['from']) : null;
        $to = isset($filters['to']) ? Carbon::parse($filters['to']) : null;

        if ($usePreviousMonth) {
            $previous = Carbon::today()->subMonth();
            $from = $previous->copy()->startOfMonth();
            $to = $previous->copy()->endOfMonth();
            $filters['from'] = $from->toDateString();
            $filters['to'] = $to->toDateString();
        } elseif ($from === null && $to === null) {
            $from = Carbon::today()->startOfMonth();
            $to = Carbon::today();
            $filters['from'] = $from->toDateString();
            $filters['to'] = $to->toDateString();
        } elseif ($from !== null && $to === null) {
            $to = Carbon::today();
            $filters['to'] = $to->toDateString();
        } elseif ($from === null && $to !== null) {
            $from = $to->copy()->startOfMonth();
            $filters['from'] = $from->toDateString();
        }

        $report = $this->calvingReportService->generate($filters);
        $count = (int) ($report['totals']['calvings_count'] ?? 0);

        $recipients = $this->recipientService->resolveRecipients();
        if ($recipients === []) {
            return [
                'sent' => false,
                'calvings_count' => $count,
                'recipients' => [],
                'message' => 'No hay destinatarios configurados (RANCH_ALERT_EMAILS o administradores).',
                'from' => $report['from'] ?? null,
                'to' => $report['to'] ?? null,
            ];
        }

        $errors = [];
        foreach ($recipients as $email) {
            try {
                Mail::to($email)->send(new RanchCalvingReportMail($report));
            } catch (Throwable $e) {
                $errors[] = $email.': '.$e->getMessage();
                Log::warning('Ranch calving report email failed', [
                    'destinatario' => $email,
                    'error' => $e->getMessage(),
                ]);
            }
        }

        if ($errors !== [] && count($errors) === count($recipients)) {
            return [
                'sent' => false,
                'calvings_count' => $count,
                'recipients' => $recipients,
                'message' => 'Falló el envío a todos los destinatarios.',
                'from' => $report['from'] ?? null,
                'to' => $report['to'] ?? null,
            ];
        }

        return [
            'sent' => true,
            'calvings_count' => $count,
            'recipients' => $recipients,
            'message' => "Resumen de partos enviado: {$count} parto(s) en el periodo.",
            'from' => $report['from'] ?? null,
            'to' => $report['to'] ?? null,
        ];
    }
}
