<?php

namespace Modules\Admin\app\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Services\JiraService;
use Carbon\Carbon;
use Modules\Admin\app\Models\TechnicalUser;
use Illuminate\Http\Request;
use Modules\Admin\app\Models\ProjectReview;
use Modules\Admin\app\Models\UserCriteria;
use PhpOffice\PhpWord\IOFactory;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\SimpleType\Jc;

class EvaluationController extends Controller
{
    protected $jiraService;

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

    public function sprintReview(Request $request)
    {
        $request->validate([
            'userID' => 'required|exists:users,id',
            'fromDate' => 'nullable|date',
            'toDate' => 'nullable|date',
        ]);

        $userEmail = User::findOrFail($request->input('userID'))->email;
        $startDate = $request->input('fromDate');
        $endDate = $request->input('toDate');

        $projectsData = self::getProjectReviewByParams($startDate, $endDate, $userEmail);
        // Trả về kết quả
        return AbstractController::ResultSuccess($projectsData);
    }

    public function getProjectReviewByParams($startDate, $endDate, $userEmail)
    {
        $projects = $this->jiraService->getAllProjects();
        $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();
        $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();
        return $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 technical(Request $request)
    {
        $request->validate([
            'user_id' => 'required|exists:users,id',
            'keyword' => 'nullable|string'
        ]);

        $user = User::find($request->input('user_id'));

        $query = TechnicalUser::query();
        $query = TechnicalUser::where('user_id', $user->id);

        if ($request->filled('keyword')) {
            $keyword = '%' . $request->input('keyword') . '%';
            $query->whereHas('technical', fn($q) => $q->where('name', 'like', $keyword))
                ->with('technical');
        } else {
            $query->with('technical');
        }

        $technical_users = $query->where('point', '>', 0)->get();

        return AbstractController::ResultSuccess(
            $technical_users
                ->map(function ($user) {
                    return [
                        'id' => $user->id,
                        'point' => $user->point,
                        'updated_at' => $user->updated_at,
                        'technical' => [
                            'id' => $user->technical->id,
                            'name' => $user->technical->name,
                            'level' => $user->technical->level,
                        ]
                    ];
                })
        );
    }

    public function report(Request $request)
    {
        $request->validate([
            'userID' => 'required|exists:users,id',
            'fromDate' => 'nullable|date',
            'toDate' => 'nullable|date',
        ]);

        // Query User
        $user = User::findOrFail($request->input('userID'));
        $userEmail = $user->email;
        $startDate = $request->input('fromDate');
        $endDate = $request->input('toDate');
        $projectsData = self::getProjectReviewByParams($startDate, $endDate, $userEmail);
        $technicalData = TechnicalController::getDataTechnicalsByUserId($request->input('userID'));
        // Generate Word document
        $phpWord = new PhpWord();
        $phpWord->setDefaultFontName('Times New Roman');
        $phpWord->setDefaultFontSize(12);
        $section = $phpWord->addSection();

        $section->addText('Staff Evaluation', [
            'bold' => true,
            'size' => 20,
            'color' => '000000',
        ], [
            'align' => 'center',
            'spaceAfter' => 600,
        ]);

        if ($request->filled('fromDate')) {
            $fromDate = Carbon::parse($request->input('fromDate'));
            $section->addText("From: " . $fromDate->format('d-m-Y'), ['name' => 'Times New Roman', 'size' => 12], ['align' => 'end']);
        }

        if ($request->filled('toDate')) {
            $toDate = Carbon::parse($request->input('toDate'));
            $section->addText("To: " . $toDate->format('d-m-Y'), ['name' => 'Times New Roman', 'size' => 12], ['align' => 'end']);
        }

        $section->addText("{$user->name}", [
            'bold' => true,
            'size' => 14,
            'color' => '000000',
        ], [
            'spaceAfter' => 400,
        ]);

        //ProjectsData
        foreach ($projectsData as $project) {
            $section->addText("Project: {$project['name']}", ['bold' => true, 'size' => 14, 'color' => '000080']);

            foreach ($project['sprints'] as $sprint) {
                $section->addText("Sprint: {$sprint['name']}", ['bold' => true, 'italic' => true, 'size' => 12, 'color' => '000000']);

                $table = $section->addTable([
                    'borderColor' => '000000',
                    'borderSize' => 6,
                    'cellMargin' => 80,
                ]);

                $table->addRow();

                $table->addCell(3000, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER])->addText('Criteria', ['bold' => true], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
                $table->addCell(3000, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER])->addText('Note', ['bold' => true], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
                $table->addCell(2500, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER])->addText('Created By', ['bold' => true], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
                $table->addCell(1500, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER])->addText('Point', ['bold' => true], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);

                foreach ($sprint['criterias'] as $criteria) {
                    $table->addRow();
                    $table->addCell(3000)->addText($criteria['criteria']);
                    $table->addCell(3000)->addText($criteria['note']);
                    $table->addCell(2500)->addText($criteria['createdBy']);
                    $table->addCell(1500, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER, 'valign' => 'center'])->addText($criteria['point'] > 0 ? $criteria['point'] : '', [], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
                }

                $section->addText(' ', [], [
                    'spaceAfter' => 600,
                ]);
            }

            $section->addText(' ', [], [
                'spaceAfter' => 600,
            ]);
        }

        // **ProjectReview Section**
        // Fetch Project Reviews
        $projectReviews = ProjectReview::where('user_id', $user->id);
        if ($startDate && $endDate) {
            $projectReviews->whereBetween('updated_at', [$startDate, $endDate . ' 23:59:59']);
        } elseif ($startDate) {
            $projectReviews->where('updated_at', '>=', $startDate);
        } elseif ($endDate) {
            $projectReviews->where('updated_at', '<=', $endDate . ' 23:59:59');
        }

        if ($projectReviews->get()->count() > 0) {
            $section->addText("Project Reviews", ['bold' => true, 'size' => 14, 'color' => '000080'], ['alignment' => Jc::CENTER]);

            $table = $section->addTable([
                'borderColor' => '000000',
                'borderSize' => 6,
                'cellMargin' => 80,
            ]);

            // Table Header
            $table->addRow();
            $table->addCell(3500)->addText('Project Name', ['bold' => true]);
            $table->addCell(2500)->addText('Role', ['bold' => true]);
            $table->addCell(5000)->addText('Note', ['bold' => true]);
            $table->addCell(2500)->addText('Created At', ['bold' => true]);
            $table->addCell(2500)->addText('Updated At', ['bold' => true]);



            foreach ($projectReviews->get() as $review) {
                $table->addRow();
                $table->addCell(3500)->addText($review->name);
                $table->addCell(2500)->addText($review->role);
                $table->addCell(5000)->addText($review->note);
                $table->addCell(2500)->addText(Carbon::parse($review->created_at)->format('d/m/Y H:i:s'));
                $table->addCell(2500)->addText(Carbon::parse($review->updated_at)->format('d/m/Y H:i:s'));
            }

            $section->addText(' ', [], [
                'spaceAfter' => 600,
            ]);
        }
        if ($technicalData)
            $section->addPageBreak();
        //Technical
        $section->addText("Technicals", ['bold' => true, 'size' => 14, 'color' => '000080'], [
            'alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER
        ]);
        $table = $section->addTable([
            'borderColor' => '000000',
            'borderSize' => 6,
            'cellMargin' => 80,
        ]);
        $table->addRow();

        $table->addCell(1500, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER])->addText('Level', ['bold' => true], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
        $table->addCell(3500, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER])->addText('Name', ['bold' => true], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
        $table->addCell(2500, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER])->addText('Point', ['bold' => true], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
        $table->addCell(2500, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER])->addText('Last Update', ['bold' => true], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);

        foreach ($technicalData as $technical) {
            $updated_at = $technical['updated_at'] ? Carbon::parse($technical['updated_at'])->format('d/m/Y H:i:s') : null;
            $table->addRow();
            $table->addCell(1500, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER, 'valign' => 'center'])->addText($technical['level'], [], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
            $table->addCell(3500)->addText($technical['name']);
            $table->addCell(2500, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER, 'valign' => 'center'])->addText($technical['point'], [], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
            $table->addCell(2500)->addText($updated_at);
        }

        $section->addText(' ', [], [
            'spaceAfter' => 600,
        ]);


        $tempFile = tempnam(sys_get_temp_dir(), 'word');
        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
        $objWriter->save($tempFile);

        return response()->download($tempFile, "$user->name.docx")->deleteFileAfterSend(true);
    }

    public function reportAllUsers(Request $request)
    {
        $request->validate([
            'fromDate' => 'nullable|date',
            'toDate' => 'nullable|date',
        ]);

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

        $users = User::all();

        $phpWord = new PhpWord();
        $phpWord->setDefaultFontName('Times New Roman');
        $phpWord->setDefaultFontSize(12);
        $section = $phpWord->addSection();

        foreach ($users as $index => $user) {
            $userEmail = $user->email;


            // Add user heading
            $section->addText("Staff Evaluation", ['bold' => true, 'size' => 20, 'color' => '000000'], ['align' => 'center']);

            if ($startDate) {
                $fromDate = Carbon::parse($startDate)->format('d-m-Y');
                $section->addText("From: " . $fromDate, ['size' => 12], ['align' => 'end']);
            }
            if ($endDate) {
                $toDate = Carbon::parse($endDate)->format('d-m-Y');
                $section->addText("To: " . $toDate, ['size' => 12], ['align' => 'end']);
            }

            $section->addText("{$user->name}", ['bold' => true, 'size' => 14, 'color' => '000000'], ['spaceAfter' => 400]);

            // **Projects Data**
            $projectsData = self::getProjectReviewByParams($startDate, $endDate, $userEmail);
            if (!empty($projectsData)) {
                foreach ($projectsData as $project) {
                    $section->addText("Project: {$project['name']}", ['bold' => true, 'size' => 14, 'color' => '000080']);

                    foreach ($project['sprints'] as $sprint) {
                        $section->addText("Sprint: {$sprint['name']}", ['bold' => true, 'italic' => true, 'size' => 12]);

                        $table = $section->addTable(['borderSize' => 6, 'cellMargin' => 80]);
                        $table->addRow();
                        $table->addCell(3000)->addText('Criteria', ['bold' => true]);
                        $table->addCell(3000)->addText('Note', ['bold' => true]);
                        $table->addCell(2500)->addText('Created By', ['bold' => true]);
                        $table->addCell(1500)->addText('Point', ['bold' => true]);

                        foreach ($sprint['criterias'] as $criteria) {
                            $table->addRow();
                            $table->addCell(3000)->addText($criteria['criteria']);
                            $table->addCell(3000)->addText($criteria['note']);
                            $table->addCell(2500)->addText($criteria['createdBy']);
                            $table->addCell(1500)->addText($criteria['point'] > 0 ? $criteria['point'] : '');
                        }
                    }
                    $section->addText(' ', [], [
                        'spaceAfter' => 600,
                    ]);
                }
            }



            // **ProjectReview Section**
            // Fetch Project Reviews
            $projectReviews = ProjectReview::where('user_id', $user->id);
            if ($startDate && $endDate) {
                $projectReviews->whereBetween('updated_at', [$startDate, $endDate . ' 23:59:59']);
            } elseif ($startDate) {
                $projectReviews->where('updated_at', '>=', $startDate);
            } elseif ($endDate) {
                $projectReviews->where('updated_at', '<=', $endDate . ' 23:59:59');
            }
            if ($projectReviews->get()->count() > 0) {
                $section->addText("Project Reviews", ['bold' => true, 'size' => 14, 'color' => '000080'], ['alignment' => Jc::CENTER]);

                $table = $section->addTable([
                    'borderColor' => '000000',
                    'borderSize' => 6,
                    'cellMargin' => 80,
                ]);

                // Table Header
                $table->addRow();
                $table->addCell(3500)->addText('Project Name', ['bold' => true]);
                $table->addCell(2500)->addText('Role', ['bold' => true]);
                $table->addCell(5000)->addText('Note', ['bold' => true]);
                $table->addCell(2500)->addText('Created At', ['bold' => true]);
                $table->addCell(2500)->addText('Updated At', ['bold' => true]);


                foreach ($projectReviews->get() as $review) {
                    $table->addRow();
                    $table->addCell(3500)->addText($review->name);
                    $table->addCell(2500)->addText($review->role);
                    $table->addCell(5000)->addText($review->note);
                    $table->addCell(2500)->addText(Carbon::parse($review->created_at)->format('d/m/Y H:i:s'));
                    $table->addCell(2500)->addText(Carbon::parse($review->updated_at)->format('d/m/Y H:i:s'));
                }

                $section->addText(' ', [], [
                    'spaceAfter' => 600,
                ]);
            }

            // **Technical Section**
            $section->addText("Technicals", ['bold' => true, 'size' => 14, 'color' => '000080'], ['alignment' => Jc::CENTER]);

            $table = $section->addTable([
                'borderColor' => '000000',
                'borderSize' => 6,
                'cellMargin' => 80,
            ]);

            $table->addRow();
            $table->addCell(1500)->addText('Level', ['bold' => true]);
            $table->addCell(3500)->addText('Name', ['bold' => true]);
            $table->addCell(2500)->addText('Point', ['bold' => true]);
            $table->addCell(2500)->addText('Last Update', ['bold' => true]);

            // Fetch Technical Data
            $technicalData = TechnicalController::getDataTechnicalsByUserId($user->id);

            foreach ($technicalData as $technical) {
                $updated_at = $technical['updated_at'] ? Carbon::parse($technical['updated_at'])->format('d/m/Y H:i:s') : null;
                $table->addRow();
                $table->addCell(1500)->addText($technical['level']);
                $table->addCell(3500)->addText($technical['name']);
                $table->addCell(2500)->addText($technical['point']);
                $table->addCell(2500)->addText($updated_at);
            }

            // Add page break between users (except last one)
            if ($index < count($users) - 1) {
                $section->addPageBreak();
            }
        }

        // Save & Download Word File
        $tempFile = tempnam(sys_get_temp_dir(), 'word');
        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
        $objWriter->save($tempFile);

        return response()->download($tempFile, "All_Users_Report.docx")->deleteFileAfterSend(true);
    }


}
