<?php

namespace App\Http\Controllers\Opportunity;

use App\Constants\ActivityTypes;
use App\Enums\ActivityStatus;
use App\Enums\PropertyStatus;
use App\Enums\SalesType;
use App\Enums\SeveritySystemLog;
use App\Enums\StagesOpportunity;
use App\Http\Controllers\Controller;
use App\Http\Messages\SuccessMessages;
use App\Http\Requests\Opportunity\ChangStatusRequest;
use App\Http\Resources\Opportunity\OpportunityResource;
use App\Http\Responses\ApiResponse;
use App\Services\BitacoraService;
use App\Services\Opportunity\ActivityService;
use App\Services\Opportunity\OpportunityService;
use App\Services\Opportunity\ProcedureOpportunityService;
use App\Services\Property\PropertyService;
use App\Services\Sale\PaymentPlanService;
use App\Services\Sale\SaleService;
use App\Services\SystemLogService;
use Illuminate\Support\Facades\DB;

class StageController extends Controller
{
    protected $activityService;
    protected $saleService;
    protected $procedureOpportunityService;
    protected $propertiesService;
    protected $opportunityService;
    protected $paymentPlansService;
    protected $bitacoraService;
    protected $systemLogService;

    public function __construct(
        ProcedureOpportunityService $procedureOpportunityService,
        OpportunityService $opportunityService,
        PropertyService $propertiesService,
        SaleService $saleService,
        ActivityService $activityService,
        PaymentPlanService $paymentPlansService,
        BitacoraService $bitacoraService,
        SystemLogService $systemLogService
    ) {
        $this->activityService = $activityService;
        $this->saleService = $saleService;
        $this->procedureOpportunityService = $procedureOpportunityService;
        $this->propertiesService = $propertiesService;
        $this->opportunityService = $opportunityService;
        $this->paymentPlansService = $paymentPlansService;
        $this->bitacoraService = $bitacoraService;
        $this->systemLogService = $systemLogService;
    }

    /**
     * @OA\PATCH(
     *     path="/api/opportunity/{opportunity_id}/stage/{stage_id}",
     *     summary="Cambiar de estado",
     *     tags={"change_status"},
     *     @OA\Parameter(
     *         name="opportunity_id",
     *         in="path",
     *         description="ID of the Oportunidad",
     *         required=true,
     *         @OA\Schema(
     *             type="integer",
     *             format="int64"
     *         )
     *     ),
     *     @OA\Parameter(
     *         name="stage_id",
     *         in="path",
     *         description="ID of the Estado",
     *         required=true,
     *         @OA\Schema(
     *             type="integer",
     *             format="int64"
     *         )
     *     ),
     *     @OA\RequestBody(
     *         required=true,
     *         @OA\JsonContent(
     *             @OA\Property(
     *                 property="property_id",
     *                 type="integer",
     *                 description="ID of the property related to the activity"
     *             ),
     *         )
     *     ),
     *     @OA\Response(response=200, description="Successful operation"),
     *     @OA\Response(response=422, description="Unprocessable Entity"),
     *     @OA\Response(response=400, description="Invalid request"),
     *     @OA\Response(response=500, description="Internal server error")
     * )
     */

    public function change_Stage(
        ChangStatusRequest $request,
        $opportunity_id,
        $stage_id
    ) {
        try {
            $oportunidad = DB::transaction(function () use ($request, $opportunity_id, $stage_id) {
                // $this->procedureOpportunityService->verifByOpportunityByStage($stage_id -1, $opportunity_id);
                $this->procedureOpportunityService->createbyStage($stage_id, $opportunity_id,);
                $opportunity = $this->opportunityService->changeStatus($opportunity_id, $stage_id);
                $opportunity = $this->opportunityService->getOpportunityById($opportunity_id);
                if ($request->input('property_id')) {
                    $opportunity->property_id = $request->input('property_id');
                    $opportunity->save();
                }
                if ($stage_id == StagesOpportunity::PRESALE->value()) {
                    $this->bitacoraService->logActivity(ActivityTypes::BECAME_PRESALE, $opportunity->customer, ['opportunity' => $opportunity]);
                    $this->systemLogService->logActivity('oportunidad','Oportunidad paso a PreVenta', SeveritySystemLog::info->name , $opportunity);
                }
                if ($stage_id == StagesOpportunity::SALE->value()) {
                    $this->bitacoraService->logActivity(ActivityTypes::BECAME_SALE, $opportunity->customer, ['opportunity' => $opportunity]);
                    $this->systemLogService->logActivity('oportunidad','Oportunidad paso a Venta', SeveritySystemLog::info->name , $opportunity);
                }
                if ($stage_id == StagesOpportunity::DELIVERY->value()) {
                    $this->bitacoraService->logActivity(ActivityTypes::BECAME_DELIVERY, $opportunity->customer, ['opportunity' => $opportunity]);
                    $this->systemLogService->logActivity('oportunidad','Oportunidad paso a Entrega', SeveritySystemLog::info->name , $opportunity);
                    foreach ($opportunity->sales as $sale) {
                        $sale->status = SalesType::DELIVERY->value;
                        $sale->save();
                        $this->systemLogService->logActivity('venta','Venta  ' . SalesType::DELIVERY->value , SeveritySystemLog::info->name,$sale);
                    }
                }
                if ($stage_id == StagesOpportunity::COMPLETED->value()) {
                    $this->bitacoraService->logActivity(ActivityTypes::BECAME_COMPLETED, $opportunity->customer, []);
                    $this->systemLogService->logActivity('oportunidad','Oportunidad Completada', SeveritySystemLog::info->name, $opportunity);

                    //Todo: cerrar todas las actividades de esa oportunidad, que tiene.
                    // $activity = $opportunity->activities->last();
                    // $activity->state_activity = ActivityStatus::COMPLETED->value;
                    // $activity->save();
                    foreach ($opportunity->activities as $activity) {
                        $activity->state_activity = ActivityStatus::COMPLETED->value;
                        $activity->save();
                        $this->systemLogService->logActivity('actividad','Actividad Completada', SeveritySystemLog::info->name, $activity);
                    }
                }

                if ($stage_id == StagesOpportunity::LOSS->value()) {
                    if (isset($opportunity->sale)) {
                        $this->saleService->changeStatus($opportunity->sale->id, SalesType::DISCARD->value);
                        $this->bitacoraService->logActivity(ActivityTypes::SALE_DISCARD,  $opportunity->customer, []);
                        $this->systemLogService->logActivity('venta','Venta descartada', SeveritySystemLog::info->name, $activity);
                        if (isset($opportunity->property)) {
                            $this->propertiesService->changestatus($opportunity->property->id, PropertyStatus::AVAILABLE->value);
                            $this->systemLogService->logActivity('propiedad','Propiedad Habilitada', SeveritySystemLog::info->name, $opportunity->property);
                        }
                    }
                    $oportunidad = $this->opportunityService->changeStatus($opportunity->id, StagesOpportunity::LOSS->value());
                    $this->bitacoraService->logActivity(ActivityTypes::OPPORTUNITY_LOSS, $oportunidad->customer , ['opportunity'=>$oportunidad]);
                    $this->systemLogService->logActivity('oportunidad','Oportunidad Perdida', SeveritySystemLog::info->name,);
                    foreach ($opportunity->activities as $activity) {
                        $activity->state_activity = ActivityStatus::DISCARD->value;
                        $activity->save();
                        $this->systemLogService->logActivity('actividad','Actividad Descartada', SeveritySystemLog::info->name, $activity);
                    }
                }
                if($stage_id != StagesOpportunity::LOSS->value()){
                    $this->systemLogService->logActivity('procedimiento','Procedimientos añadidos a la oportunidad', SeveritySystemLog::info->name);
                }
                return $opportunity;
            });
            return ApiResponse::success(SuccessMessages::UPDATE_SUCCESS,new OpportunityResource($oportunidad),[],200);
        } catch (\Exception $e) {
            $this->systemLogService->logActivity('oportunidad','Cambio de estado de oportunidad fallida' , SeveritySystemLog::error->name);
            return ApiResponse::error($e->getMessage(), $e, [], 500);
        }
    }
}
