<?php

namespace App\Http\Controllers\Frontend;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use App\Helpers\SeoHelper;
use App\Models\Upload;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Contracts\Encryption\DecryptException;
use App\Helpers\AnalyticsHelper;
use App\Models\FileReports;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

class FileController extends Controller
{
    public function file(
        Request $request,
        string $fileName
    ): View {
        $fileData = Upload::where("filename", $fileName)
            ->first();

        if (!$fileData) {
            abort(404);
        }

        $check = isset($fileData->password) && $fileData->password
            ? (
                (Auth::check() && $fileData->created_by_id == Auth::id()) 
                    ? true 
                    : $this->checkPermission($fileName)) 
            : true;
        $rand = rand();
        $fileUrl = url("/get/{$fileData->filename}?v={$rand}");

        if ($check) {
            AnalyticsHelper::make($fileData->id, $request->ip());
            $analyticsGet = AnalyticsHelper::get($fileData->id);
        }

        $seo = SeoHelper::pageSeo('file',$fileData);

        return view('frontend.file.index', [
            'functions' => 'frontend.file.function',
            'pageKey' => 'file',
            'seoData' => $seo,
            'permission' => $check,
            'file' => $fileData,
            'fileUrl' => $fileUrl,
            'downloadUrl' => $fileUrl,
            'analytics' => $analyticsGet ?? false,
        ]);
    }

    public function file_password(
        Request $request, 
        string $fileName
    ): RedirectResponse {
        $request->validate([
            'file-password' => 'required|min:3|max:15',
        ]);

        $file = Upload::where("filename", $fileName)->first();

        if (!$file) {
            return back()->withErrors([
                'error' => __('lang.file_not_found'),
            ]);
        }

        if ($file->password != $request->input('file-password')) {
            return back()->withErrors([
                'error' => __('lang.password_incorrect'),
            ]);
        }

        $fileKey = Crypt::encryptString($fileName);
        $request->session()->push('files', $fileKey);

        return back();
    }

    public function clear(
        Request $request
    ): void {
        $request->session()->forget('files');
    }

    public function report(
        Request $request,
        string $fileName
    ): JsonResponse {
        $validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'reason' => 'required|string|max:10000',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'result' => false,
                'errors' => $validator->errors(),
            ]);
        }

        $file = Upload::where('filename', $fileName)->first();

        if (!$file) {
            return response()->json([
                'result' => false,
                'data' => __('lang.file_not_found'), 
            ]);
        }

        $userId = Auth::id();
        $userIp = $request->ip();
        $create = FileReports::create([
            'created_by_id' => $userId,
            'created_by_ip' => $userIp,
            'updated_by_id' => $userId,
            'updated_by_ip' => $userIp,
            'file_id' => $file->id,
            'file_uploader' => $file->created_by_id,
            'reporter' => $request->input('email'),
            'reason' => $request->input('reason'),
        ]);

        if ($create) {
            return response()->json([
                'result' => true,
                'data' => __('lang.report_send'), 
            ]);
        }

        return response()->json([
            'result' => false,
            'data' => __('lang.report_send_error'), 
        ]);
    }

    private function checkPermission(
        string $filename
    ): bool {
        if (Auth::check() && Auth::user()->type == 2) {
            $permission = true;
        } else {
            $filesArr = request()->session()->get('files');

            if (isset($filesArr) && $filesArr) {
                $decryptedArr = [];
                foreach ($filesArr as $file) {
                    try {
                        $decrypted = Crypt::decryptString($file);
                        array_push($decryptedArr, $decrypted);
                    } catch (DecryptException $e) {
                        // Ignore errors
                    }
                }
    
                $permission = in_array($filename, $decryptedArr)
                    ? true
                    : false;
            } else {
                $permission = false;
            }
        }

        return $permission;
    }

}
