<?php

namespace App\Http\Controllers\Reports\NewHire;

use Illuminate\Http\Request;

use App\Http\Controllers\Controller;
use App\Http\Responses\DataTableJsonResponse;
use App\Http\Traits\SavedSearchTrait;
use App\Models\Asset;
use App\Models\AssetHistory;
use App\Models\AssetStatus;
use Facades\App\Services\NewHire\NewHireEmployeesData;

use App\User;
use App\Models\SavedSearch;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Auth;

class NewHireEmployeesController extends Controller
{
    use SavedSearchTrait;

    /**
     * Display the index view for the new hire report.
     *
     * @return \Illuminate\View\View The view for the new hire report
     */
    public function index()
    {
        $userId = Auth::id();
        $user = User::with('userType')->find($userId);
        $assetStatusId = AssetStatus::where('slug', 'assigned')->first()->id;
        $savedFilters = SavedSearch::reportName('newhire')->userSavedSearch($userId)->get();
        $viewAllFilters = SavedSearch::reportName('newhire')->adminSavedSearch()->get();
        $savedSearch = [];
        $search = [];

        if (request('admin_saved_search') || request('user_saved_search')) {
            try {
                if (request('admin_saved_search')) {
                    $savedSearch = SavedSearch::reportName('newhire')->where('id', request('admin_saved_search'))->where('view_all', 1)->firstOrFail();
                }

                if (request('user_saved_search')) {
                    $savedSearch = SavedSearch::reportName('newhire')->where('id', request('user_saved_search'))->where('user_id', Auth::id())->whereNull('view_all')->firstOrFail();
                }

                $search = json_decode($savedSearch->parameters, true);
            } catch (Exception $e) {
                return redirect(route('new-hire'))->with('error', 'Search not found.');
            }
        }


        if (request('fte')) {
            $search['fte'] = request('fte');
        }

        if (request('from')) {
            $search['date_from'] = request('from');
        }

        if (request('to')) {
            $search['date_to'] = request('to');
        }


        return view('reports.new-hire.new-hire-employees', compact('savedFilters', 'viewAllFilters', 'savedSearch', 'search', 'user', 'assetStatusId'));
    }

    /**
     * View the assets for a specific user.
     *
     * @param int $id The ID of the user
     *
     * @return string The HTML table body with the asset details
     */
    public function viewAssets($id)
    {
        $assets = Asset::with('assetStatus')->with('makeAndModel')->with('user')->with('latestAssetHistory')->where('user_id', $id)
            ->whereIn('asset_status_id', AssetStatus::whereIn('slug', ['assigned', 'loaned', 'legal_hold', 'retain_hold', 'service_repair'])->pluck('id'))
            ->get();

        $assigned = AssetStatus::where('slug', 'assigned')->first();
        $tableBody = '';

        foreach ($assets as $asset) {
            if ($asset->assetStatus?->slug == 'stolen_lost') {
                $terminated = date(config('date.formats.read_date_format'), strtotime($asset->user->terminated_date . ' -10 day'));
                $updated = date(config('date.formats.read_date_format'), strtotime($asset->latestAssetHistory->updated_at));

                $date1 = Carbon::createFromFormat(config('date.formats.read_date_format'), $updated);
                $date2 = Carbon::createFromFormat(config('date.formats.read_date_format'), $terminated);

                if ($date1->lt($date2)) {
                    continue;
                }
            }

            $assetHistory = AssetHistory::where('new_user_id', $id)->where('action', 'status_updated')->where('asset_id', $asset->id)->where('new_asset_status_id', $assigned->id)->orderBy('created_at', 'desc')->first();
            $ticket_no = $assetHistory ? $assetHistory->ticket_no : '';
            $tableBody .= '<tr>
                            <td>' . $asset->serial_no . '</td>
                            <td>' . $asset->asset_tag . '</td>
                            <td>' . ($asset->makeAndModel ? $asset->makeAndModel->name : '') . '</td>
                            <td>' . ($asset->assetStatus ? $asset->assetStatus->name : '') . '</td>
                            <td>' . $ticket_no . '</td>
                            <td>' . date(config('date.formats.read_date_format'), ($asset->latestAssetHistory ? strtotime($asset->latestAssetHistory->updated_at) : strtotime($asset->updated_at->toDateString()))) . '</td>
                        </tr>';
        }

        return $tableBody;
    }

    /**
     * Retrieve and format the data for the new hire employees report.
     *
     * @param \Illuminate\Http\Request $request The incoming request instance
     *
     * @return \Illuminate\Http\JsonResponse The JSON response containing the formatted report data
     */
    public function data(Request $request)
    {
        $filteredData   = NewHireEmployeesData::filter();
        $users          = $filteredData['users'];
        $totalData      = $filteredData['count'];

        $start  = request('start');
        $data   = [];

        if (!empty($users)) {
            $data = NewHireEmployeesData::getUserData($users, $start, $data);
        }

        return new DataTableJsonResponse($request->input('draw'), $data, $totalData);
    }

    /**
     * Export the new hire employees report data to a CSV file.
     *
     * @return \Symfony\Component\HttpFoundation\StreamedResponse The response to export the data as CSV
     */
    public function export()
    {
        setUnlimitedExecutionTimeAndMemoryLimit();

        $data = [];
        $datas = collect();

        $filteredData = NewHireEmployeesData::filterData()->get();
        $datas->push(NewHireEmployeesData::getExportUserData($filteredData, 0, $data));

        return exportToCsv($datas->toArray());
    }

    /**
     * Synchronize JIRA users for new hires.
     *
     * @return \Illuminate\Http\JsonResponse The JSON response containing the status and message of the synchronization operation
     */
    public function syncJiraUsers()
    {
        try {
            Artisan::call('NewHireJiraSync:sync');

            return response()->json(array('status' => 'success', 'message' => Artisan::output()));
        } catch (Exception $e) {
            return response()->json(array('status' => 'error', 'message' => 'New hire sync failed.'));
        }
    }

    /**
     * Retrieve saved search parameters from the request.
     *
     * @return array The array containing the saved search parameters
     */
    public function getSavedSearchParameters()
    {
        return [
            'no_of_assets'     => request('no_of_assets') != '' ? request('no_of_assets') : '',
            'work_location'    => request('work_location') ? request('work_location') : '',
            'employee_type'    => request('employee_type') ? request('employee_type') : '',
            'employee_name'    => request('employee_name') ? request('employee_name') : '',
            'department'       => request('department') ? request('department') : '',
            'date_from'        => request('date_from') ? request('date_from') : '',
            'date_to'          => request('date_to') ? request('date_to') : '',
            'fte'              => request('fte') ? request('fte') : '',
        ];
    }

    /**
     * Retrieve the report name for saved searches.
     *
     * @return string The report name for saved searches
     */
    public function getSavedSearchReportName()
    {
        return 'newhire';
    }
}
