<?php

namespace App\Console\Commands;

use App\Models\EmailRecipient;
use App\Notifications\HubSpotSyncReport;
use App\Services\HubSpotSyncService;
use App\Services\HubSpot\HubSpotSyncMetrics;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class HubSpotSyncCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'hubspot:sync
        {--dry-run : Show what would be synced without making changes}
        {--type= : Only sync specific type (committee|workgroup|member-regular|member-associate|all)}
        {--email-report= : Send email report to specified addresses (comma-separated)}
        {--test-connection : Test the HubSpot API connection only}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Synchronize committees, workgroups, and member users with HubSpot contact lists';

    /**
     * @var HubSpotSyncService
     */
    protected $hubSpotService;

    /**
     * Create a new command instance.
     *
     * @param HubSpotSyncService $hubSpotService
     */
    public function __construct(HubSpotSyncService $hubSpotService)
    {
        parent::__construct();
        $this->hubSpotService = $hubSpotService;
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle(): int
    {
        // Check if HubSpot sync is available
        if (!HubSpotSyncService::isAvailable()) {
            $this->error('❌ HubSpot sync is not available.');
            $this->line('');
            $this->line('Please ensure:');
            $this->line('  1. HUBSPOT_ACCESS_TOKEN is set in your .env file');
            $this->line('  2. HUBSPOT_SYNC_ENABLED=true in your .env file');
            return 1;
        }

        // Handle test connection
        if ($this->option('test-connection')) {
            return $this->handleTestConnection();
        }

        // Run sync
        return $this->handleSync();
    }

    /**
     * Test the HubSpot API connection.
     *
     * @return int
     */
    protected function handleTestConnection(): int
    {
        $this->info('🔌 Testing HubSpot API connection...');
        $this->line('');

        try {
            $result = $this->hubSpotService->testConnection();

            if ($result['success']) {
                $this->info('✅ ' . $result['message']);
                return 0;
            } else {
                $this->error('❌ ' . $result['message']);
                return 1;
            }
        } catch (\Exception $e) {
            $this->error('❌ Failed to test connection: ' . $e->getMessage());
            return 1;
        }
    }

    /**
     * Handle the synchronization.
     *
     * @return int
     */
    protected function handleSync(): int
    {
        $dryRun = $this->option('dry-run');
        $type = $this->option('type');
        if ($type === 'both' || $type === 'all') {
            $type = null;
        }

        $this->info('🚀 Starting HubSpot Synchronization...');
        if ($dryRun) {
            $this->warn('🧪 DRY RUN MODE - No changes will be made');
        }
        if ($type) {
            $this->info('🔎 Sync type: ' . $type);
        }
        $this->line('');

        Log::info('HubSpot sync command started' . ($dryRun ? ' (DRY-RUN)' : '') . ($type ? ", type: $type" : ''));

        try {
            // Run the sync
            $metrics = $this->hubSpotService->syncAll($dryRun, $type);

            // Output summary to console
            $this->outputMetrics($metrics);

            // Send email report if requested
            $this->sendEmailReport($metrics);

            // Return appropriate exit code
            $exitCode = $metrics->hasErrors() ? 1 : 0;

            if ($metrics->hasErrors()) {
                Log::warning('HubSpot sync completed with errors');
            } else {
                Log::info('HubSpot sync completed successfully');
            }

            return $exitCode;

        } catch (\Exception $e) {
            $this->error('❌ Sync failed: ' . $e->getMessage());
            Log::error('HubSpot sync command failed: ' . $e->getMessage());
            return 1;
        }
    }

    /**
     * Output metrics to console.
     *
     * @param HubSpotSyncMetrics $metrics
     * @return void
     */
    protected function outputMetrics(HubSpotSyncMetrics $metrics): void
    {
        $this->line($metrics->toSummary());
    }

    /**
     * Send email report if configured.
     *
     * @param HubSpotSyncMetrics $metrics
     * @return void
     */
    protected function sendEmailReport(HubSpotSyncMetrics $metrics): void
    {
        $emailOption = $this->option('email-report');

        // Get recipients from option or config
        $recipients = [];

        if (!empty($emailOption)) {
            $recipients = array_filter(array_map('trim', explode(',', $emailOption)));
        } else {
            // Check config for default recipients
            $configRecipients = config('hubspot.email_report.recipients', '');
            if (!empty($configRecipients)) {
                $recipients = array_filter(array_map('trim', explode(',', $configRecipients)));
            }
        }

        if (empty($recipients)) {
            return;
        }

        // Check if we should only send on errors
        $onlyOnError = config('hubspot.email_report.only_on_error', false);
        if ($onlyOnError && !$metrics->hasErrors()) {
            $this->info('📧 No email sent (only_on_error is enabled and no errors occurred)');
            return;
        }

        $this->info('📧 Sending email report to: ' . implode(', ', $recipients));

        try {
            foreach ($recipients as $email) {
                $recipient = new EmailRecipient($email, 'HubSpot Sync Admin');
                $recipient->notify(new HubSpotSyncReport($metrics));
            }
            $this->info('✅ Email report sent successfully');
        } catch (\Exception $e) {
            $this->error('❌ Failed to send email report: ' . $e->getMessage());
            Log::error('Failed to send HubSpot sync email report: ' . $e->getMessage());
        }
    }
}
