<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Http\Concerns\AuthorizesCompanyAccess;
use App\Services\DataverseService;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Throwable;

class PLReportController extends Controller
{
    use AuthorizesCompanyAccess;

    public function __construct(private DataverseService $dv) {}

    /**
     * POST /api/v1/reports/pl
     *
     * Fetches P&L data from AutoCount via Azure Function and streams the raw
     * JSON body directly to the client — avoids decode + re-encode of large payloads.
     */
    public function query(Request $request): Response
    {
        // Raise memory limit for this request only — large JSON payloads
        ini_set('memory_limit', '512M');

        $validated = $request->validate([
            'company_id'      => 'required|string',
            'start_date'      => 'required|date_format:Y-m-d',
            'end_date'        => 'required|date_format:Y-m-d',
            'department_code' => 'nullable|string',
            'return_full'     => 'nullable|boolean',
        ]);

        // Multi-tenant guard: caller must be PIC of (or admin over) this company.
        if ($deny = $this->authorizeCompany($validated['company_id'])) {
            return $deny;
        }

        // ── Fetch company credentials from Dataverse ─────────────────────────
        try {
            $company = $this->dv->find('cr6f2_companies', $validated['company_id'], [
                'select' => [
                    'cr6f2_companyid',
                    'cr6f2_name',
                    'cr6f2_acsynctype',
                    'cr6f2_acapiendpoint',
                    'cr6f2_ackeyid',
                    'cr6f2_acapikey',
                ],
            ]);
        } catch (Throwable $e) {
            return $this->jsonError('Company not found.', 404);
        }

        if (($company['cr6f2_acsynctype'] ?? null) !== 'Cloud') {
            return $this->jsonError('AutoCount Cloud sync is not enabled for this company.', 422);
        }

        $apiEndpoint = $company['cr6f2_acapiendpoint'] ?? null;
        $apiKey      = $company['cr6f2_acapikey']      ?? null;
        $keyId       = $company['cr6f2_ackeyid']       ?? null;
        $companyName = $company['cr6f2_name']          ?? '';

        if (empty($apiEndpoint) || empty($apiKey) || empty($keyId)) {
            return $this->jsonError('AutoCount API credentials are incomplete. Please configure the API tab for this company.', 422);
        }

        // ── Call Azure Function ───────────────────────────────────────────────
        $payload = [
            'varAPIEndpoint' => $apiEndpoint,
            'varAPIKey'      => $apiKey,
            'varKeyID'       => $keyId,
            'varStartDate'   => $validated['start_date'],
            'varEndDate'     => $validated['end_date'],
            'companyName'    => $companyName,
            'returnFullData' => $validated['return_full'] ?? true,
        ];

        if (!empty($validated['department_code'])) {
            $payload['departmentCode'] = $validated['department_code'];
        }

        try {
            $functionUrl = rtrim((string) config('services.function_app.base_url'), '/') . '/get_pl_data_json';
            $azureResponse = Http::timeout(120)
                ->withHeaders([
                    'Content-Type'    => 'application/json',
                    'x-functions-key' => (string) config('services.function_app.key'),
                ])
                ->post($functionUrl, $payload);

            if (!$azureResponse->successful()) {
                Log::warning('P&L Azure Function failed', [
                    'status'     => $azureResponse->status(),
                    'company_id' => $validated['company_id'],
                ]);
                return $this->jsonError('P&L data fetch failed [' . $azureResponse->status() . '].', 502);
            }

            // Stream raw body directly — no decode/re-encode, avoids memory exhaustion
            // The frontend reads res.data directly (not res.data.data)
            return response($azureResponse->body(), 200, [
                'Content-Type' => 'application/json',
            ]);

        } catch (Throwable $e) {
            Log::error('P&L Azure Function exception', [
                'error'      => $e->getMessage(),
                'company_id' => $validated['company_id'],
            ]);
            return $this->jsonError($e->getMessage(), 500);
        }
    }

    private function jsonError(string $message, int $status): Response
    {
        return response(
            json_encode(['success' => false, 'message' => $message]),
            $status,
            ['Content-Type' => 'application/json']
        );
    }
}
