<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Business;
use App\Models\Document;
use App\Models\DocumentException;
use App\Models\ExportError;
use App\Models\UserActivity;
use App\Support\ApiResponse;
use Illuminate\Http\Request;

/**
 * Admin / back-office ("Service Portal") list endpoints. These power the
 * Internal pages that previously rendered hardcoded mock data.
 */
class InternalController extends Controller
{
    /**
     * Platform-wide user activity log (all users), shaped for the
     * Internal → User Activity table.
     */
    public function userActivity(Request $request)
    {
        $page = max(1, (int) $request->query('page', 1));
        $pageSize = max(1, (int) $request->query('pageSize', 10));

        $paginator = UserActivity::with(['user', 'business'])
            ->orderByDesc('id')
            ->paginate($pageSize, ['*'], 'page', $page);

        $rows = collect($paginator->items())->map(function (UserActivity $a) {
            return [
                'country'           => null,
                'orgName'           => $a->business?->business_name,
                'orgId'             => $a->business_id,
                'entityName'        => $a->business?->business_name,
                'entityId'          => $a->business_id,
                'userName'          => $a->user?->full_name,
                'userid'            => $a->user_id,
                'loginIP'           => $a->ip_address,
                'logInTime'         => optional($a->created_at)->toIso8601String(),
                'logInTimeElapsed'  => optional($a->created_at)->diffForHumans(),
                'logOutTime'        => null,
                'logOutTimeElapsed' => null,
                'duration'          => null,
                'device'            => null,
                'browser'           => null,
                'version'           => null,
                'action'            => $a->action,
                'description'       => $a->description,
            ];
        })->values();

        return ApiResponse::success('User activity', [
            'documents' => $rows,
            'items' => $rows,
            'pagination' => [
                'currentPage' => $paginator->currentPage(),
                'totalPages' => $paginator->lastPage(),
                'totalRecords' => $paginator->total(),
                'pageSize' => $paginator->perPage(),
            ],
        ]);
    }

    /**
     * Exception log for the Internal → Exception Management table.
     */
    public function exceptions(Request $request)
    {
        $page = max(1, (int) $request->query('page', 1));
        $pageSize = max(1, (int) $request->query('pageSize', 10));
        $status = $request->query('status');

        $q = DocumentException::with(['reporter', 'document.business'])->orderByDesc('id');
        if ($status) $q->where('status', $status);
        $paginator = $q->paginate($pageSize, ['*'], 'page', $page);

        $rows = collect($paginator->items())->map(function (DocumentException $e) {
            $business = $e->document?->business;
            return [
                'logId'           => $e->id,
                'date'            => optional($e->created_at)->toDateString(),
                'time'            => optional($e->created_at)->format('H:i:s'),
                'elapsedTime'     => optional($e->created_at)->diffForHumans(),
                'userid'          => $e->reported_by,
                'userEmail'       => $e->reporter?->email,
                'orgId'           => $business?->id,
                'orgName'         => $business?->business_name,
                'entityId'        => $business?->id,
                'entityName'      => $business?->business_name,
                'storedProcedure' => null,
                'machine'         => null,
                'uniqueCheck'     => $e->status,
                'cause'           => $e->reason ?? $e->notes,
                'status'          => $e->status,
            ];
        })->values();

        return $this->paginatedPayload('Exceptions', $rows, $paginator);
    }

    /**
     * Export error log for the Internal → Export Errors table.
     */
    public function exportErrors(Request $request)
    {
        $page = max(1, (int) $request->query('page', 1));
        $pageSize = max(1, (int) $request->query('pageSize', 10));

        $paginator = ExportError::with(['business.user', 'document'])
            ->orderByDesc('id')
            ->paginate($pageSize, ['*'], 'page', $page);

        $rows = collect($paginator->items())->map(function (ExportError $e) {
            return [
                'orgName'       => $e->business?->business_name,
                'orgOwnerEmail' => $e->business?->user?->email,
                'entityName'    => $e->business?->business_name,
                'software'      => $e->software,
                'docStatus'     => $e->document?->status ?? $e->status,
                'externalError' => $e->external_error,
                'ebError'       => $e->internal_error,
                'createdOn'     => optional($e->created_at)->toIso8601String(),
                'isExported'    => $e->status === 'Exported',
            ];
        })->values();

        return $this->paginatedPayload('Export errors', $rows, $paginator);
    }

    /**
     * Per-entity deleted-document summary for Internal → Deleted Documents.
     */
    public function deletedSummary(Request $request)
    {
        $businesses = Business::whereHas('documents', function ($q) {
            $q->where('is_deleted', true)->orWhere('status', 'Deleted');
        })->get();

        $rows = $businesses->map(function (Business $b) {
            $deleted = Document::where('business_id', $b->id)
                ->where(function ($q) { $q->where('is_deleted', true)->orWhere('status', 'Deleted'); })
                ->get(['uploaded_date', 'updated_at']);
            $last = $deleted->max('updated_at');
            return [
                'businessId'            => $b->id,
                'orgName'               => $b->business_name,
                'entityName'            => $b->business_name,
                'lastDeletedDate'       => optional($last)->toIso8601String(),
                'elapsedTime'           => optional($last)->diffForHumans(),
                'deletedDocumentsCount' => $deleted->count(),
            ];
        })->values();

        return ApiResponse::success('Deleted documents', [
            'documents' => $rows, 'items' => $rows,
            'pagination' => ['currentPage' => 1, 'totalPages' => 1, 'totalRecords' => $rows->count(), 'pageSize' => $rows->count()],
        ]);
    }

    /**
     * Per-entity processing summary for Internal → Documents Processing Summary.
     */
    public function processingSummary(Request $request)
    {
        $businesses = Business::whereHas('documents')->with('user')->get();

        $rows = $businesses->map(function (Business $b) {
            $docs = Document::where('business_id', $b->id)->where('is_deleted', false)->get();
            $processedStatuses = ['Data Entered', 'Processed', 'Exported'];
            $inProcessStatuses = ['Uploaded', 'Processing', 'Review'];
            return [
                'businessId'          => $b->id,
                'uploadedBy'          => $b->user?->full_name ?? $b->user?->email,
                'orgName'             => $b->business_name,
                'invoiceProcessed'    => $docs->whereIn('document_type', ['SalesInvoice', 'PurchaseInvoice'])->whereIn('status', $processedStatuses)->count(),
                'statementsProcessed' => $docs->where('document_type', 'BankStatement')->whereIn('status', $processedStatuses)->count(),
                'inProcess'           => $docs->whereIn('status', $inProcessStatuses)->count(),
                'firstUploadDate'     => optional($docs->min('uploaded_date'))->toIso8601String(),
                'lastUploadDate'      => optional($docs->max('uploaded_date'))->toIso8601String(),
                'lastSent'            => optional($docs->max('processed_date'))->toIso8601String(),
                'lastSentElapsedTime' => optional($docs->max('processed_date'))->diffForHumans(),
            ];
        })->values();

        return ApiResponse::success('Processing summary', [
            'documents' => $rows, 'items' => $rows,
            'pagination' => ['currentPage' => 1, 'totalPages' => 1, 'totalRecords' => $rows->count(), 'pageSize' => $rows->count()],
        ]);
    }

    /**
     * Flat upload history for Internal → Upload History.
     */
    public function uploadHistory(Request $request)
    {
        $page = max(1, (int) $request->query('page', 1));
        $pageSize = max(1, (int) $request->query('pageSize', 10));

        $paginator = Document::with('uploader')
            ->orderByDesc('id')
            ->paginate($pageSize, ['*'], 'page', $page);

        $rows = collect($paginator->items())->map(function (Document $d) {
            return [
                'id'             => $d->id,
                'filename'       => $d->file_name,
                'uploadedBy'     => $d->uploader?->full_name ?? $d->uploader?->email,
                'docType'        => $d->document_type,
                'uploadDateTime' => optional($d->uploaded_date)->toIso8601String() ?? optional($d->created_at)->toIso8601String(),
                'status'         => $d->status,
                'source'         => 'web',
                'fileSize'       => $d->file_size,
                'documentsPages' => 1,
            ];
        })->values();

        return $this->paginatedPayload('Upload history', $rows, $paginator);
    }

    private function paginatedPayload(string $message, $rows, $paginator)
    {
        return ApiResponse::success($message, [
            'documents' => $rows,
            'items' => $rows,
            'pagination' => [
                'currentPage' => $paginator->currentPage(),
                'totalPages' => $paginator->lastPage(),
                'totalRecords' => $paginator->total(),
                'pageSize' => $paginator->perPage(),
            ],
        ]);
    }
}
