<?php

namespace App\Http\Controllers\Reports;

use App\Http\Controllers\Controller;
use App\Http\Responses\ReportJsonResponse;
use Illuminate\Http\Request;
use App\Services\Reports\DuplicateAssetsService;
use Facades\App\Services\ExportManagement\ExportManagementService;
use Illuminate\Validation\Rule;

/**
 * Controller class that handles the functionality and operations related to the AssetsDuplication.
 */
class DuplicateAssetsController extends Controller
{

    /**
     * Initialize the controller with the DuplicateAssetsService.
     *
     * @param \App\Services\DuplicateAssetsService $service The service to manage duplicate assets
     */
    public function __construct(protected DuplicateAssetsService $service)
    {
    }

    /**
     * Display the index view for duplicate assets report.
     *
     * @return \Illuminate\View\View The view for the duplicate assets report index
     */
    public function index()
    {
        return view('reports.duplicate-assets.index');
    }

    /**
     * Retrieve and format the data for the duplicate assets report.
     *
     * @return \App\Http\Responses\ReportJsonResponse The JSON response containing the formatted duplicate assets data
     */
    public function data()
    {
        $reportData = $this->service->getDuplicatedAssetsData();
        $duplicatedAssets = $reportData['duplicatedAssets'];
        $start = request('start');
        $data = [];

        if (!empty($duplicatedAssets)) {
            $matchedAssets = $duplicatedAssets->flatMap(function ($item) {
                return explode(',', $item->matching_assets);
            })->toArray();

            $data = $this->service->formatAssetDuplicationData($duplicatedAssets, $start, $data, $matchedAssets, request('length'));
        }

        return new ReportJsonResponse(intval(request('draw')), $data, $reportData['count']);
    }

    /**
     * Remove a duplicated asset based on the provided asset ID.
     *
     * @return \Illuminate\Http\RedirectResponse The redirect response with a success or error message
     */
    public function removeDuplicatedAsset()
    {
        $response = $this->service->removeDuplicatedAsset(request('delete-asset-id'));

        if ($response) {
            return redirect('/duplicate-assets')->with('message', 'Asset deleted successfully.');
        }

        return redirect('/duplicate-assets')->with('error', 'Opertaion failed');
    }

    /**
     * Export the duplicated assets data.
     *
     * @return \Symfony\Component\HttpFoundation\StreamedResponse|string The response to export the data as CSV or a string indicating a background download
     */
    public function exportDuplicatedAsset()
    {
        setUnlimitedExecutionTimeAndMemoryLimit();

        $datas = collect();
        $exportData = $this->service->getDuplicatedAssetsExportData();

        if (ExportManagementService::duplicatedAssetsLargeExport($exportData)) {
            return 'background_download';
        }

        if (!empty($exportData)) {
            $matchedAssets = $exportData->flatMap(function ($item) {
                return explode(',', $item->matching_assets);
            })->toArray();

            $dataToExport = $this->service->formatExportAssetDuplicationData($exportData, $matchedAssets);
        }

        $datas->push($dataToExport);

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

    /**
     * Retrieve duplicated assets data for merging.
     *
     * @return \Illuminate\Support\Collection The collection of duplicated assets data for merging
     */
    public function getAssetDataForMerge()
    {
        return $this->service->getDuplicatedAssetsDataForMerge();
    }

    /**
     * Merge duplicate assets.
     *
     * @return \Illuminate\Http\RedirectResponse The redirect response with a success or error message
     */
    public function mergeDuplicateAssets()
    {
        $mergeResponse = $this->service->mergeDuplicatedAssets(request('primary_asset_id'), request('asset_id_to_delete'));

        if ($mergeResponse['status'] == 'error') {
            return redirect('/duplicate-assets')->with('error', $mergeResponse['message']);
        }

        return redirect('/duplicate-assets')->with('message', $mergeResponse['message']);
    }

    /**
     * Update duplicate assets.
     *
     * @return \Illuminate\Http\RedirectResponse The redirect response with a success or error message
     */
    public function updateDuplicateAssets()
    {
        request()->validate([
            'asset_id' => ['required'],
            'edit_duplicate_asset_serial_no' => ['required', Rule::unique('assets', 'serial_no')->ignore(request('asset_id'))],
            'edit_duplicate_asset_asset_tag' => ['required', Rule::unique('assets', 'asset_tag')->ignore(request('asset_id'))]
        ], [
            'asset_id.required' => 'The asset ID field is required.',
            'edit_duplicate_asset_serial_no.required' => 'The serial # field is required.',
            'edit_duplicate_asset_serial_no.unique' => 'The serial # is already in use.',
            'edit_duplicate_asset_asset_tag.required' => 'The asset tag field is required.',
            'edit_duplicate_asset_asset_tag.unique' => 'The asset tag is already in use.'
        ]);

        if ($this->service->updateDuplicatedAssets(request()->all())) {
            return redirect('/duplicate-assets')->with('message', 'Updated successfully.');
        }

        return redirect('/duplicate-assets')->with('error', 'Operation failed');
    }
}
