<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\ImportSubscribersRequest;
use App\Http\Requests\Admin\SegmentSubscribersRequest;
use App\Http\Requests\Admin\StoreSubscriberRequest;
use App\Models\EmailMarketingList;
use App\Models\EmailMarketingSubscriber;
use App\Services\CsvSubscriberImportService;
use App\Services\EmailMarketingSegmentService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class EmailMarketingSubscriberApiController extends Controller
{
    public function records(Request $request, EmailMarketingList $list): JsonResponse
    {
        $draw = (int) $request->input('draw', 1);
        $start = (int) $request->input('start', 0);
        $length = (int) $request->input('length', 25);
        $search = $request->input('search.value', '');

        $base = $list->subscribers();

        if ($status = $request->input('filter.status')) {
            $base->where('email_marketing_subscribers.status', $status);
        }
        if ($source = $request->input('filter.source')) {
            $base->where('email_marketing_list_subscriber.source', $source);
        }

        $total = $base->count();

        if ($search !== '') {
            $base->where(function ($q) use ($search) {
                $q->where('email_marketing_subscribers.email', 'like', "%$search%")
                  ->orWhere('first_name', 'like', "%$search%")
                  ->orWhere('last_name', 'like', "%$search%");
            });
        }

        $filtered = $base->count();

        $rows = $base->orderByPivot('joined_at', 'desc')
            ->skip($start)->take($length)
            ->get();

        return response()->json([
            'draw' => $draw,
            'recordsTotal' => $total,
            'recordsFiltered' => $filtered,
            'data' => $rows->map(fn ($s) => [
                'id' => $s->id,
                'email' => $s->email,
                'name' => trim(($s->first_name ?? '').' '.($s->last_name ?? '')) ?: null,
                'status' => $s->status,
                'source' => $s->pivot->source,
                'joined_at' => $s->pivot->joined_at
                    ? \Carbon\Carbon::parse($s->pivot->joined_at)->format('Y-m-d H:i')
                    : null,
            ]),
        ]);
    }

    public function store(StoreSubscriberRequest $request, EmailMarketingList $list): JsonResponse
    {
        return DB::transaction(function () use ($request, $list) {
            $sub = EmailMarketingSubscriber::firstOrCreate(
                ['email' => $request->email],
                [
                    'first_name' => $request->first_name,
                    'last_name' => $request->last_name,
                    'status' => 'subscribed',
                    'source' => 'manual',
                ],
            );
            $list->subscribers()->syncWithoutDetaching([
                $sub->id => ['joined_at' => now(), 'source' => 'manual'],
            ]);
            $list->recountSubscribers();
            return response()->json(['success' => true, 'subscriber_id' => $sub->id]);
        });
    }

    public function destroy(Request $request, EmailMarketingList $list, EmailMarketingSubscriber $subscriber): JsonResponse
    {
        // Permission enforced via route middleware (permission:manage email marketing subscribers)
        $list->subscribers()->detach($subscriber->id);
        $list->recountSubscribers();
        return response()->json(['success' => true]);
    }

    public function segmentPreview(
        SegmentSubscribersRequest $request,
        EmailMarketingList $list,
        EmailMarketingSegmentService $svc
    ): JsonResponse {
        return response()->json([
            'success' => true,
            'count' => $svc->preview($request->criterion, $request->validated()),
        ]);
    }

    public function segmentAttach(
        SegmentSubscribersRequest $request,
        EmailMarketingList $list,
        EmailMarketingSegmentService $svc
    ): JsonResponse {
        $added = 0;
        $skipped = 0;
        DB::transaction(function () use ($request, $list, $svc, &$added, &$skipped) {
            foreach ($svc->emails($request->criterion, $request->validated()) as $row) {
                $sub = EmailMarketingSubscriber::firstOrCreate(
                    ['email' => $row['email']],
                    [
                        'first_name' => $row['first_name'],
                        'last_name' => $row['last_name'],
                        'client_id' => $row['client_id'],
                        'status' => 'subscribed',
                        'source' => 'segment',
                    ],
                );
                $alreadyAttached = $list->subscribers()
                    ->where('email_marketing_subscriber_id', $sub->id)
                    ->exists();
                if ($alreadyAttached) {
                    $skipped++;
                    continue;
                }
                $list->subscribers()->attach($sub->id, [
                    'joined_at' => now(),
                    'source' => 'segment',
                ]);
                $added++;
            }
            $list->recountSubscribers();
        });

        return response()->json([
            'success' => true,
            'added' => $added,
            'skipped' => $skipped,
        ]);
    }

    public function import(
        ImportSubscribersRequest $request,
        EmailMarketingList $list,
        CsvSubscriberImportService $svc
    ): JsonResponse {
        $result = $svc->import($list, $request->file('csv'));
        return response()->json(array_merge(['success' => true], $result));
    }
}
