<?php
/**
 * @author: Uldis Zvirbulis <uldis.zvirbulis@mtcmedia.co.uk>
 * @version: 10.10.2024
 */

namespace Mtc\Plugins\Clinic\Http\Controllers\Admin;

use Carbon\Carbon;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Mtc\Modules\Members\Models\Member;
use Mtc\Plugins\Clinic\Src\Clinic;
use Mtc\Plugins\Clinic\Src\Logger;
use Mtc\Plugins\Clinic\Src\Models\PatientFile;
use Mtc\Plugins\Clinic\Src\Uploader;
use Mtc\Plugins\Wisebee\Classes\Models\WisebeeDocument;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class FileController extends ClinicController
{
    /**
     * File download
     *
     * @param $id
     * @param Request $request
     * @return Application|ResponseFactory|Response|BinaryFileResponse
     */
    public function getFile($id, Request $request)
    {
        /** @var PatientFile $file */
        if (!$file = PatientFile::query()->find($id)) {
            return response('Not Found', 404);
        }

        return PatientFile::downloadFile($file);
    }

    /**
     * Load entries
     *
     * @param $id
     * @return JsonResponse
     */
    public function load($id): JsonResponse
    {
        $patientFiles = PatientFile::query()
            ->where('member_id', $id)
            ->orderByDesc('date_provided')
            ->get()
            ->map(function (PatientFile $record) {
                $record->fileURL = route('admin-file-get', [
                    $record->id,
                ]);
                return $record;
            });

        if (config('wisebee.enabled')) {
            $patientFiles = PatientFile::injectWisebeeDocuments($patientFiles, $id);
        }

        $patientFiles->map(function (PatientFile|WisebeeDocument $record) {
            $record->date_provided = Carbon::parse($record->date_provided)
                ->format('d/m/Y');
            return $record;
        });

        return response()
            ->json([
                'files' => $patientFiles,
                'todayDate' => Carbon::now()
                    ->format('d/m/Y'),
                'types' => PatientFile::$types,
                'imageExtensions' => PatientFile::IMAGE_EXTENSIONS,
            ]);
    }

    /**
     * Creates / updates entry in database
     *
     * @param $id
     * @param Request $request
     * @return JsonResponse
     */
    public function store($id, Request $request): JsonResponse
    {
        /** @var Member $member */
        $member = Member::query()
            ->with('addressBilling')
            ->find($id);
        $data = $request->all();
        $data['member_id'] = $id;
        if ($errors = PatientFile::validate($data)) {
            return response()
                ->json([
                    'errors' => $errors,
                ]);
        }

        /** @var PatientFile $patientFile */
        $patientFile = PatientFile::query()
            ->where('member_id', $id)
            ->where('id', $request->input('id'))
            ->first();

        $dateProvided = !empty($data['date_provided']) ?
            Carbon::createFromFormat('d/m/Y', $data['date_provided']) :
            Carbon::now();
        $data['date_provided'] = $dateProvided->format('Y-m-d');

        if (!empty($patientFile)) {
            if (empty($request->file('file'))) {
                // Updating
                $patientFile->fill($data);
                $patientFile->save();

                (new Logger($patientFile, Clinic::getActor(), $id))
                    ->log(Logger::FILE, Logger::ACTION_UPDATED, $patientFile->toArray());

                return response()
                    ->json([
                        'success' => 'Data saved successfully!',
                    ]);
            } else {
                // If the file exists, but is re-uploaded, we re-create it
                $patientFile->deleteFile();
            }
        } elseif (empty($request->file('file'))) {
            return response()
                ->json([
                    'errors' => [
                        'file' => 'Please select a file for upload!',
                    ],
                ]);
        }

        $fileToStore = $request->file('file');
        $uploadParams = [
            'public' => false,
            'type' => $request->input('type'),
            'title' => $request->input('title'),
        ];
        $uploader = new Uploader($uploadParams);
        if (!$file = $uploader->uploadFile($fileToStore)) {
            return response()->json([
                'errors' => [
                    'file' => implode(', ', $uploader->errors),
                ],
            ]);
        }
        $file->update([
            'member_id' => $member->id,
            'date_provided' => $data['date_provided'],
        ]);

        (new Logger($file, Clinic::getActor(), $id))
            ->log(Logger::FILE, Logger::ACTION_CREATED, $file->toArray());

        return response()
            ->json([
                'success' => 'Data saved successfully!',
            ]);
    }

    /**
     * Deletes entry in database
     *
     * @param $id
     * @param Request $request
     * @return JsonResponse
     */
    public function delete($id, Request $request): JsonResponse
    {
        /** @var PatientFile $patientFile */
        $patientFile = PatientFile::query()
            ->where('id', $request->input('id'))
            ->where('member_id', $id)
            ->firstOrFail();

        (new Logger($patientFile, Clinic::getActor(), $patientFile->member_id))
            ->log(Logger::FILE, Logger::ACTION_DELETED, $patientFile->toArray());

        $patientFile->deleteFile();

        return response()
            ->json([
                'success' => 'File deleted successfully!',
            ]);
    }
}
