<?php

namespace Modules\Admin\app\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Services\JiraService;
use App\Traits\AnalyzeData;
use App\Traits\HasFilterRequest;
use App\Traits\HasOrderByRequest;
use App\Traits\HasSearchRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Modules\Admin\app\Models\Sprint;
use Modules\Admin\app\Models\UserCriteria;

class ProfileController extends Controller
{
    use HasOrderByRequest;
    use HasFilterRequest;
    use HasSearchRequest;
    use AnalyzeData;

    protected $jiraService;

    public function __construct(JiraService $jiraService)
    {
        $this->jiraService = $jiraService;
    }

    public function getProfilesData(Request $request)
    {
        $user = auth('admins')->user();

        $userEmail = $user->email;
        $projects = $this->jiraService->getAllProjects();

        $startDate = $request->input('fromDate');
        $endDate = $request->input('toDate');

        $userCriterias = UserCriteria::with([
            'sprint' => function ($query) use ($startDate, $endDate) {
                if ($startDate && $endDate) {
                    $query->whereBetween('complete_date', [$startDate, $endDate]);
                } elseif ($startDate) {
                    $query->where('complete_date', '>=', $startDate);
                } elseif ($endDate) {
                    $query->where('complete_date', '<=', $endDate);
                }
            },
            'criteria',
        ])->where('user_email', $userEmail)
            ->whereHas('sprint', function ($query) use ($startDate, $endDate) {
                if ($startDate && $endDate) {
                    $query->whereBetween('complete_date', [$startDate, $endDate]);
                } elseif ($startDate) {
                    $query->where('complete_date', '>=', $startDate);
                } elseif ($endDate) {
                    $query->where('complete_date', '<=', $endDate);
                }
            })
            ->get();
        // dd($userCriterias);
        // Xử lý dữ liệu thành cấu trúc mong muốn
        $projectsData = $userCriterias->groupBy('sprint.project_id')->map(function ($userCriteriasByProject, $projectId) use ($projects) {
            $result = self::getProjectById($projects, $projectId);
            return [
                'name' => $result['name'],
                'sprints' => $userCriteriasByProject->groupBy('sprint.id')->map(function ($userCriteriasBySprint) {
                    $sprint = $userCriteriasBySprint->first()->sprint;
                    return [
                        'name' => $sprint->name,
                        'complete_date' => $sprint->complete_date ?? '',
                        'criterias' => $userCriteriasBySprint->map(function ($userCriteria) {
                            $criteria = $userCriteria->criteria;
                            return [
                                'criteria' => $criteria->name,
                                'note' => $userCriteria->note ?? '',
                                'createdBy' => $userCriteria->created_by ?? '', // Lấy tên user từ auth
                                'point' => $userCriteria->point ?? '',
                            ];
                        })
                    ];
                })->values()
            ];
        })->values();

        // Trả về kết quả
        return AbstractController::ResultSuccess($projectsData);
    }

    public function getProjectById($projects, $inputId)
    {
        $filteredProjects = array_filter($projects, function ($project) use ($inputId) {
            return $project['id'] == $inputId;
        });
        return array_values($filteredProjects) ? array_values($filteredProjects)[0] : array_values($filteredProjects);
    }

    public function updateProfilesData(Request $request)
    {
        $userInfo = auth('admins')->user();
        $request->validate([
            'file' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048', // Chỉ chấp nhận file ảnh dưới 2MB
        ]);

        $user = User::findOrFail($userInfo->id);

        if ($user->avatar) {
            Storage::disk('public')->delete($user->avatar);
        }

        $path = $request->file('file')->store('avatars', 'public');
        $user->avatar = $path;
        $user->save();
        return AbstractController::ResultSuccess($path);
    }

    public function listFiles(Request $request)
    {
        // Get the root folder from the input URL
        $rootFolder = $request->input('root_folder');

        // Ensure the root folder is correctly formatted
        $rootFolder = rtrim($rootFolder, '/') . '/';

        // Get all files and directories in the specified root folder
        $fileList = $this->getDirectoryTree(public_path($rootFolder), env('APP_ENV') === 'local' ? $rootFolder: 'image'.$rootFolder);

        return response()->json(['data' => $fileList, 'status' => true]);
    }

    private function getDirectoryTree($dir, $urlRoot)
    {
        $results = [];

        // Scan the directory for files and folders
        $files = scandir($dir);

        foreach ($files as $file) {
            if ($file !== '.' && $file !== '..') {
                $filePath = $dir . DIRECTORY_SEPARATOR . $file;
                $fileUrl = url($urlRoot . $file);

                if (is_dir($filePath)) {
                    // If it's a directory, recurse into it
                    $results[] = [
                        'label' => $file,
                        'type' => 'directory',
                        'value' => $fileUrl,
                        'children' => $this->getDirectoryTree($filePath, $urlRoot . $file . '/')
                    ];
                } else {
                    // If it's a file, add it to the list
                    $results[] = [
                        'label' => $file,
                        'type' => 'file',
                        'value' => $fileUrl
                    ];
                }
            }
        }

        return $results;
    }

    public function updateProfile(Request $request)
    {
        $name = $request->input('name') ?? auth('admins')->user()->name;
        // Validate the incoming files
        $request->validate([
            'files.*' => 'required|file|mimes:jpg,png,jpeg,pdf,doc,docx|max:5120', // Adjust file types and size limit as needed
        ]);

        $uploadedFiles = [];
        $baseDirectory = 'profiles/' . $name;
        $othersDirectory = $baseDirectory . '/others';

        // Check if the base directory exists, if not create it
        if (!Storage::disk('public')->exists($baseDirectory)) {
            Storage::disk('public')->makeDirectory($baseDirectory);
        }

        // Check if the "others" directory exists, if not create it
        if (!Storage::disk('public')->exists($othersDirectory)) {
            Storage::disk('public')->makeDirectory($othersDirectory);
        }
        if ($request->hasFile('files')) {
            foreach ($request->file('files') as $file) {
                // Store the file and get its path
                $originalFilename = $file->getClientOriginalName();
                if (strpos($originalFilename, '__') === 0) {
                    // Store the file in the "others" directory
                    $path = $file->storeAs($othersDirectory, $originalFilename, 'public');
                } else {
                    // Store the file in the base directory
                    $path = $file->storeAs($baseDirectory, $originalFilename, 'public');
                }
                $uploadedFiles[] = $path;
            }
        }

        return response()->json([
            'status' => true,
            'message' => 'Files uploaded successfully',
            'files' => $uploadedFiles,
        ]);
    }

    public function removeFile(Request $request)
    {
        // Validate that the file URL is provided in the request
        $request->validate([
            'file_url' => 'required|string',
        ]);

        // Get the full file URL from the request
        $fileUrl = $request->input('file_url');

        // Parse the file path from the URL (remove the base URL part)
        $storagePath = parse_url($fileUrl, PHP_URL_PATH); // Extract the path part of the URL
        $filePath = str_replace(env('APP_ENV') === 'local' ? '/storage/' : '/image/storage/', '', $storagePath); // Remove "/storage/" to get the actual file path

        // Check if the file exists before attempting to delete it
        if (Storage::disk('public')->exists($filePath)) {
            // Delete the file
            Storage::disk('public')->delete($filePath);

            return response()->json([
                'status' => true,
                'message' => 'File deleted successfully',
            ]);
        }

        return response()->json([
            'status' => false,
            'message' => 'File not found',
        ], 404);
    }
}
