<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class OctoparseImportReport extends Notification
{
    use Queueable;

    /** @var array<int,array<string,mixed>> */
    protected $summary;

    /** @var array<string,array<int,string>> */
    protected $sampleNewEntriesByTask;

    /** @var bool */
    protected $dryRun;

    /** @var bool */
    protected $hadFailure;

    /** @var int|null */
    protected $latestLogId;

    /**
     * @param  array<int,array<string,mixed>>  $summary
     * @param  array<string,array<int,string>>  $sampleNewEntriesByTask
     */
    public function __construct(
        array $summary,
        array $sampleNewEntriesByTask,
        bool $dryRun,
        bool $hadFailure,
        ?int $latestLogId
    ) {
        $this->summary = $summary;
        $this->sampleNewEntriesByTask = $sampleNewEntriesByTask;
        $this->dryRun = $dryRun;
        $this->hadFailure = $hadFailure;
        $this->latestLogId = $latestLogId;
    }

    public function via(object $notifiable): array
    {
        return ['mail'];
    }

    public function toMail(object $notifiable): MailMessage
    {
        $modePrefix = $this->dryRun ? '[DRY-RUN] ' : '';
        $statusEmoji = $this->hadFailure ? '❌' : '✅';
        $statusText = $this->hadFailure ? 'With Errors' : 'Success';

        $subject = "{$statusEmoji} {$modePrefix}Octoparse Import Report - {$statusText}";

        $greeting = $this->dryRun
            ? 'Octoparse Import Dry-Run Completed'
            : ($this->hadFailure ? 'Octoparse Import Completed with Errors' : 'Octoparse Import Completed Successfully');

        $mail = (new MailMessage)
            ->subject($subject)
            ->greeting($greeting)
            ->line('**Date:** ' . now()->format('Y-m-d H:i:s T'));

        if ($this->dryRun) {
            $mail->line('')
                 ->line('⚠️ **This was a dry-run. No actual changes were made.**');
        }

        // Per-task summary
        $mail->line('')
             ->line('---')
             ->line('### 📊 Tasks Summary');

        $totalInserted = 0;
        $totalUpdated = 0;
        $totalFetched = 0;
        $totalFailed = 0;

        foreach ($this->summary as $row) {
            $label = $row['label'] ?? $row['task_id'] ?? 'unknown';
            $taskId = $row['task_id'] ?? '';
            $status = $row['status'] ?? 'unknown';
            $emoji = $this->statusEmoji($status);

            $mail->line('')
                 ->line("**{$emoji} {$label}**")
                 ->line("Task ID: `{$taskId}` &middot; Status: **{$status}**");

            if (isset($row['error'])) {
                $mail->line("Error: {$row['error']}");
                continue;
            }

            $fetched = (int) ($row['rows_fetched'] ?? 0);
            $inserted = (int) ($row['rows_inserted'] ?? 0);
            $updated = (int) ($row['rows_updated'] ?? 0);
            $failed = (int) ($row['rows_failed'] ?? 0);

            $totalFetched += $fetched;
            $totalInserted += $inserted;
            $totalUpdated += $updated;
            $totalFailed += $failed;

            $mail->line("- Fetched: **{$fetched}**")
                 ->line("- 🆕 Inserted: **{$inserted}**")
                 ->line("- Updated: **{$updated}**")
                 ->line("- Failed: **{$failed}**");

            if (!empty($row['duration_seconds'])) {
                $duration = round((float) $row['duration_seconds'], 2);
                $mail->line("- Duration: {$duration}s");
            }
        }

        $mail->line('')
             ->line('---')
             ->line('### 📈 Totals')
             ->line("- Fetched: **{$totalFetched}**")
             ->line("- 🆕 New entries inserted: **{$totalInserted}**")
             ->line("- Updated: **{$totalUpdated}**")
             ->line("- Failed: **{$totalFailed}**");

        // New entries detail per task (with sample of up to 10)
        $tasksWithNewEntries = array_filter(
            $this->summary,
            fn ($row) => (int) ($row['rows_inserted'] ?? 0) > 0
        );

        if (!empty($tasksWithNewEntries)) {
            $mail->line('')
                 ->line('---')
                 ->line('### 🆕 New Entries Detail');

            foreach ($tasksWithNewEntries as $row) {
                $taskId = $row['task_id'] ?? '';
                $label = $row['label'] ?? $taskId;
                $inserted = (int) ($row['rows_inserted'] ?? 0);

                $mail->line('')
                     ->line("**{$label}** — {$inserted} new " . ($inserted === 1 ? 'row' : 'rows'));

                $samples = $this->sampleNewEntriesByTask[$taskId] ?? [];
                if (!empty($samples)) {
                    foreach ($samples as $sample) {
                        $mail->line("- {$sample}");
                    }
                    $remaining = $inserted - count($samples);
                    if ($remaining > 0) {
                        $mail->line("- … and {$remaining} more");
                    }
                }
            }

            if ($this->latestLogId !== null) {
                $mail->action(
                    'View all new entries',
                    url('/admin/octoparse/logs/' . $this->latestLogId . '/new-entries')
                );
            }
        } else {
            $mail->line('')
                 ->line('---')
                 ->line('ℹ️ No new entries were imported in this run.');
        }

        // Errors block
        $errors = array_filter(
            $this->summary,
            fn ($row) => isset($row['error']) || ($row['status'] ?? '') === 'failed'
        );

        if (!empty($errors)) {
            $mail->line('')
                 ->line('---')
                 ->line('### ❌ Errors');
            foreach ($errors as $row) {
                $label = $row['label'] ?? $row['task_id'] ?? 'unknown';
                $message = $row['error'] ?? 'See application logs for details.';
                $mail->line("- **{$label}**: {$message}");
            }
        }

        return $mail->line('')
                    ->line('---')
                    ->line('This is an automated notification from the Octoparse integration.');
    }

    public function toArray(object $notifiable): array
    {
        return [
            'summary' => $this->summary,
            'dry_run' => $this->dryRun,
            'had_failure' => $this->hadFailure,
            'latest_log_id' => $this->latestLogId,
        ];
    }

    private function statusEmoji(string $status): string
    {
        switch ($status) {
            case 'success':
                return '✅';
            case 'failed':
                return '❌';
            case 'partial':
                return '⚠️';
            case 'running':
                return '⏳';
            default:
                return '•';
        }
    }
}
