<?php

namespace App\Http\Controllers;

use App\Models\Campaign;
use App\Models\Contact;
use App\Models\Tag;
use App\Services\BusinessSettings;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Inertia\Inertia;
use Inertia\Response;

class DashboardController extends Controller
{
    public function index(): Response
    {
        $stats = [
            'active_contacts'    => Contact::where('status', 'subscribed')->count(),
            'total_contacts'     => Contact::count(),
            'campaigns'          => Campaign::whereIn('type', ['campaign', 'recurring_occurrence'])->count(),
            'emails_sent'        => (int) Campaign::sum('emails_sent'),
            'tags'               => Tag::count(),
            'email_templates'    => 0,
            'active_automations' => Campaign::where('type', 'automation')->where('status', 'active')->count(),
        ];

        $latestSent = Campaign::whereIn('type', ['campaign', 'recurring_occurrence'])
            ->where('status', 'sent')
            ->orderByDesc('updated_at')
            ->first();

        $latestCampaign = $latestSent ? [
            'title'    => $latestSent->title,
            'openRate' => $latestSent->emails_sent > 0
                ? round($latestSent->unique_opens / $latestSent->emails_sent * 100, 1)
                : 0,
            'sentAt'   => optional($latestSent->updated_at)->toIso8601String(),
        ] : null;

        $initialOperations = $this->buildOperationsData('all', false);

        return Inertia::render('Dashboard', [
            'stats'             => $stats,
            'latestCampaign'    => $latestCampaign,
            'initialOperations' => $initialOperations,
        ]);
    }

    public function operations(Request $request): JsonResponse
    {
        $scope = $request->input('scope', 'all');
        $runningOnly = filter_var($request->input('running_only', false), FILTER_VALIDATE_BOOLEAN);

        $data = $this->buildOperationsData($scope, $runningOnly);

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

    private function buildOperationsData(string $scope = 'all', bool $runningOnly = false): array
    {
        $userId = auth()->id();

        $query = Campaign::with(['user:id,name', 'creator:id,name']);

        if ($scope === 'my') {
            $query->where(function ($q) use ($userId) {
                $q->where('user_id', $userId)
                  ->orWhere('created_by', $userId);
            });
        }

        if ($runningOnly) {
            $query->whereIn('status', ['sending', 'processing', 'scheduled', 'active']);
        }

        $allMatching = (clone $query)->get();

        $totalOps = $allMatching->count();
        $runningOps = $allMatching->whereIn('status', ['sending', 'processing', 'scheduled', 'active'])->count();
        $sentOps = $allMatching->whereIn('status', ['sent', 'completed'])->count();
        $draftOps = $allMatching->where('status', 'draft')->count();
        $pausedOps = $allMatching->where('status', 'paused')->count();

        $totalSent = (int) $allMatching->sum('emails_sent');
        $totalFailed = (int) $allMatching->sum('emails_failed');
        $totalBounced = (int) $allMatching->sum('emails_bounced');
        $uniqueOpens = (int) $allMatching->sum('unique_opens');
        $uniqueClicks = (int) $allMatching->sum('unique_clicks');

        $deliveryRate = $totalSent > 0
            ? round(max(0, $totalSent - $totalBounced - $totalFailed) / $totalSent * 100, 1)
            : 100.0;

        $openRate = $totalSent > 0
            ? round($uniqueOpens / $totalSent * 100, 1)
            : 0.0;

        $clickRate = $totalSent > 0
            ? round($uniqueClicks / $totalSent * 100, 1)
            : 0.0;

        $statusCounts = [
            'sent'       => $allMatching->whereIn('status', ['sent', 'completed'])->count(),
            'sending'    => $allMatching->whereIn('status', ['sending', 'processing'])->count(),
            'scheduled'  => $allMatching->where('status', 'scheduled')->count(),
            'active'     => $allMatching->where('status', 'active')->count(),
            'draft'      => $allMatching->where('status', 'draft')->count(),
            'paused'     => $allMatching->where('status', 'paused')->count(),
            'failed'     => $allMatching->where('status', 'failed')->count(),
        ];

        $typeCounts = [
            'campaign'         => $allMatching->where('type', 'campaign')->count(),
            'automation'       => $allMatching->where('type', 'automation')->count(),
            'recurring_master' => $allMatching->where('type', 'recurring_master')->count(),
            'sequence'         => $allMatching->where('type', 'sequence')->count(),
        ];

        $opsList = (clone $query)
            ->orderByDesc('updated_at')
            ->limit(15)
            ->get()
            ->map(function ($op) use ($userId, $scope) {
                $isOwner = ($op->user_id == $userId || $op->created_by == $userId);
                // Privacy protection: When in 'my' (own operations) scope or when owned by user, show 'You'
                $creatorName = $isOwner ? 'You' : ($op->creator?->name ?? $op->user?->name ?? 'Team Member');

                $viewUrl = match($op->type) {
                    'automation'       => route('automation.edit', $op->id),
                    'sequence'         => route('sequences.edit', $op->id),
                    'recurring_master' => route('recurring.edit', $op->id),
                    default            => route('campaigns.show', $op->id),
                };

                return [
                    'id'               => $op->id,
                    'title'            => $op->title,
                    'type'             => $op->type,
                    'status'           => $op->status,
                    'email_subject'    => $op->email_subject,
                    'recipients_count' => (int) $op->recipients_count,
                    'emails_sent'      => (int) $op->emails_sent,
                    'emails_failed'    => (int) $op->emails_failed,
                    'emails_bounced'   => (int) $op->emails_bounced,
                    'unique_opens'     => (int) $op->unique_opens,
                    'unique_clicks'    => (int) $op->unique_clicks,
                    'creator_name'     => $creatorName,
                    'is_owner'         => $isOwner,
                    'scheduled_at'     => $op->scheduled_at?->toIso8601String(),
                    'updated_at'       => $op->updated_at->toIso8601String(),
                    'view_url'         => $viewUrl,
                ];
            });

        return [
            'scope'        => $scope,
            'running_only' => $runningOnly,
            'kpis' => [
                'total_operations'   => $totalOps,
                'running_operations' => $runningOps,
                'sent_operations'    => $sentOps,
                'draft_operations'   => $draftOps,
                'paused_operations'  => $pausedOps,
                'total_sent'         => $totalSent,
                'total_bounced'      => $totalBounced,
                'delivery_rate'      => $deliveryRate,
                'open_rate'          => $openRate,
                'click_rate'         => $clickRate,
            ],
            'status_breakdown' => $statusCounts,
            'type_breakdown'   => $typeCounts,
            'operations_list'  => $opsList,
        ];
    }

    public function growth(Request $request)
    {
        $tz = BusinessSettings::timezone();

        $to   = $request->filled('to')
            ? Carbon::parse($request->input('to'), $tz)->endOfDay()
            : now($tz)->endOfDay();

        $from = $request->filled('from')
            ? Carbon::parse($request->input('from'), $tz)->startOfDay()
            : $to->copy()->subDays(29)->startOfDay();

        $fromUtc = $from->copy()->setTimezone(config('app.timezone'));
        $toUtc   = $to->copy()->setTimezone(config('app.timezone'));

        $baseline = Contact::where('created_at', '<', $fromUtc)->count();

        $offset = $from->format('P');
        $daily = Contact::selectRaw("DATE(CONVERT_TZ(created_at, '+00:00', ?)) as date, COUNT(*) as count", [$offset])
            ->whereBetween('created_at', [$fromUtc, $toUtc])
            ->groupBy('date')
            ->pluck('count', 'date');

        $labels     = [];
        $newAdds    = [];
        $cumulative = [];
        $running    = $baseline;

        for ($date = $from->copy(); $date->lte($to); $date->addDay()) {
            $key   = $date->format('Y-m-d');
            $count = (int) ($daily[$key] ?? 0);
            $running += $count;

            $labels[]     = $date->format('M j');
            $newAdds[]    = $count;
            $cumulative[] = $running;
        }

        return response()->json(compact('labels', 'newAdds', 'cumulative'));
    }
}
