<?php

namespace App\Master\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Master\Models\AutoTraderAdvertiser;
use App\Services\AutoTraderAdvertisersApi;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Tenant;

class AutoTraderAdvertiserController extends Controller
{
    public function __construct(
        protected AutoTraderAdvertisersApi $api
    ) {
    }

    /**
     * Verify API credentials are valid
     */
    public function verifyCredentials(): JsonResponse
    {
        $result = $this->api->verifyCredentials();

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

    /**
     * Get list of all accessible advertisers from DB cache.
     * Auto-fetches from API on first use (empty table).
     */
    public function index(): JsonResponse
    {
        $cached = AutoTraderAdvertiser::all();

        if ($cached->isEmpty()) {
            return $this->refreshAll();
        }

        $lastFetched = AutoTraderAdvertiser::max('last_fetched_at');

        return response()->json([
            'success' => true,
            'source' => 'database',
            'last_fetched_at' => $lastFetched,
            'count' => $cached->count(),
            'advertisers' => $cached->map->toApiFormat()->values(),
        ]);
    }

    /**
     * Get details for a specific advertiser from DB cache.
     * Falls back to live API if not found.
     */
    public function show(string $advertiserId): JsonResponse
    {
        $cached = AutoTraderAdvertiser::where('advertiser_id', $advertiserId)->first();

        if ($cached) {
            return response()->json([
                'success' => true,
                'source' => 'database',
                'advertiser' => $cached->toApiFormat(),
            ]);
        }

        return $this->refresh($advertiserId);
    }

    /**
     * Refresh all advertisers from the API and store in DB.
     */
    public function refreshAll(): JsonResponse
    {
        $result = $this->api->getAdvertisers();

        if (!$result['success']) {
            return response()->json($result);
        }

        $advertisers = collect($result['advertisers'])
            ->map(fn(array $data) => AutoTraderAdvertiser::upsertFromApiResponse($data));

        return response()->json([
            'success' => true,
            'source' => 'api',
            'last_fetched_at' => now()->toIso8601String(),
            'count' => $advertisers->count(),
            'advertisers' => $advertisers->map->toApiFormat()->values(),
        ]);
    }

    /**
     * Refresh a single advertiser from the API and store in DB.
     */
    public function refresh(string $advertiserId): JsonResponse
    {
        $result = $this->api->getAdvertiser($advertiserId);

        if (!$result['success']) {
            return response()->json($result);
        }

        $model = AutoTraderAdvertiser::upsertFromApiResponse($result['advertiser']);

        return response()->json([
            'success' => true,
            'source' => 'api',
            'advertiser' => $model->toApiFormat(),
        ]);
    }

    /**
     * Check access to a specific advertiser ID
     */
    public function checkAccess(Request $request): JsonResponse
    {
        $request->validate([
            'advertiser_id' => 'required|string',
        ]);

        $result = $this->api->checkAccess($request->input('advertiser_id'));

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

    /**
     * Get dealer IDs from a specific tenant's dealerships
     */
    public function getTenantDealerIds(string $tenantId): JsonResponse
    {
        $tenant = Tenant::find($tenantId);

        if (!$tenant) {
            return response()->json([
                'success' => false,
                'error' => 'Tenant not found',
            ], 404);
        }

        tenancy()->initialize($tenant);

        try {
            $dealerships = Dealership::all()
                ->map(function (Dealership $dealership) {
                    $autoTraderId = $dealership->data['auto-trader-location-id'] ?? null;
                    return [
                        'id' => $dealership->id,
                        'name' => $dealership->name,
                        'auto_trader_id' => $autoTraderId,
                        'is_master' => $dealership->is_master ?? false,
                    ];
                })
                ->filter(fn($d) => !empty($d['auto_trader_id']));

            // Get unique Autotrader IDs
            $uniqueIds = $dealerships->pluck('auto_trader_id')->unique()->values();

            return response()->json([
                'success' => true,
                'tenant' => [
                    'id' => $tenant->id,
                    'name' => $tenant->name,
                ],
                'dealerships' => $dealerships->values(),
                'unique_auto_trader_ids' => $uniqueIds,
            ]);
        } finally {
            tenancy()->end();
        }
    }

    /**
     * Check access to all dealer IDs for a tenant
     */
    public function checkTenantAccess(string $tenantId): JsonResponse
    {
        $tenant = Tenant::find($tenantId);

        if (!$tenant) {
            return response()->json([
                'success' => false,
                'error' => 'Tenant not found',
            ], 404);
        }

        tenancy()->initialize($tenant);

        try {
            $dealerships = Dealership::all()
                ->map(fn(Dealership $dealership) => [
                    'id' => $dealership->id,
                    'name' => $dealership->name,
                    'auto_trader_id' => $dealership->data['auto-trader-location-id'] ?? null,
                    'is_master' => $dealership->is_master ?? false,
                ])
                ->filter(fn($d) => !empty($d['auto_trader_id']));

            $uniqueIds = $dealerships->pluck('auto_trader_id')->unique()->values()->all();
            $apiResult = $this->api->getAdvertisersByIds($uniqueIds);

            $advertisersById = collect($apiResult['advertisers'] ?? [])
                ->keyBy('advertiserId');

            $results = $dealerships->map(function ($dealership) use ($advertisersById) {
                $advertiser = $advertisersById->get($dealership['auto_trader_id']);

                return [
                    'dealership_id' => $dealership['id'],
                    'dealership_name' => $dealership['name'],
                    'auto_trader_id' => $dealership['auto_trader_id'],
                    'is_master' => $dealership['is_master'],
                    'accessible' => $advertiser !== null,
                    'advertiser' => $advertiser,
                    'error' => $advertiser === null ? 'Advertiser not found in API response' : null,
                ];
            })->values()->all();

            $accessibleCount = collect($results)->where('accessible', true)->count();

            return response()->json([
                'success' => true,
                'tenant' => [
                    'id' => $tenant->id,
                    'name' => $tenant->name,
                ],
                'summary' => [
                    'total_dealer_ids' => count($results),
                    'accessible' => $accessibleCount,
                    'not_accessible' => count($results) - $accessibleCount,
                ],
                'results' => $results,
            ]);
        } finally {
            tenancy()->end();
        }
    }

    /**
     * List all tenants that have Autotrader dealer IDs configured
     */
    public function tenantsWithDealerIds(): JsonResponse
    {
        $tenants = Tenant::query()
            ->whereNull('suspended_at')
            ->orderBy('name')
            ->get(['id', 'name']);

        $tenantsWithIds = [];

        foreach ($tenants as $tenant) {

            try {
                tenancy()->initialize($tenant);
                $dealerIds = Dealership::all()
                    ->pluck('data')
                    ->map(fn($data) => $data['auto-trader-location-id'] ?? null)
                    ->filter()
                    ->unique()
                    ->values();

                if ($dealerIds->isNotEmpty()) {
                    $tenantsWithIds[] = [
                        'id' => $tenant->id,
                        'name' => $tenant->name,
                        'dealer_id_count' => $dealerIds->count(),
                        'dealer_ids' => $dealerIds,
                    ];
                }
            } finally {
                tenancy()->end();
            }
        }

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