<?php

namespace App\Http\Controllers\Api;

use App\Services\DataRetrievalService;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Services\DashboardService;
use Carbon\Carbon;

class DashboardController extends Controller
{
    protected $service;
    protected $dataRetrievalService;

    public function __construct(DashboardService $service)
    {
        $this->service = $service;
        $this->dataRetrievalService = new DataRetrievalService();
    }

    /*
    |--------------------------------------------------------------------------
    | Helper: Resolve Epiweek Range
    |--------------------------------------------------------------------------
    */

    private function getEpiRange(Request $request)
    {
        $startYear = (int) $request->query('start_year');
        $startWeek = (int) $request->query('start_week');
        $endYear = (int) $request->query('end_year');
        $endWeek = (int) $request->query('end_week');

        if (!$startYear || !$startWeek || !$endYear || !$endWeek) {
            return null;
        }

        return [
            'startYear' => $startYear,
            'startWeek' => $startWeek,
            'endYear' => $endYear,
            'endWeek' => $endWeek
        ];
    }


    /*
    |--------------------------------------------------------------------------
    | Overview Summary Cards
    |--------------------------------------------------------------------------
    */

    public function summary()
    {
        return response()->json($this->service->summaryCards());
    }


    /*
    |--------------------------------------------------------------------------
    | Overview Trend Chart
    |--------------------------------------------------------------------------
    */

    public function trend(Request $request)
    {
        $range = $this->getEpiRange($request);

        if (!$range) {
            return response()->json(['error' => 'Missing epiweek range'], 400);
        }

        $data = $this->service->aggregateAllPrograms(

            $range['startYear'],
            $range['startWeek'],
            $range['endYear'],
            $range['endWeek']
        );

        return response()->json($data);
    }


    /*
    |--------------------------------------------------------------------------
    | Program Dashboard
    |--------------------------------------------------------------------------
    */

    public function program(Request $request)
    {
        $surveillanceId = (int) $request->query('surveillance_id');

        if (!$surveillanceId) {
            return response()->json(['error' => 'Missing surveillance_id'], 400);
        }

        $range = $this->getEpiRange($request);

        if (!$range) {
            return response()->json(['error' => 'Missing epiweek range'], 400);
        }

        $data = $this->service->programDashboardData(
            $surveillanceId,
            $range['startYear'],
            $range['startWeek'],
            $range['endYear'],
            $range['endWeek']
        );

        return response()->json($data);
    }


    /*
    |--------------------------------------------------------------------------
    | Province Map (Overview)
    |--------------------------------------------------------------------------
    */

    public function provinceCircles(Request $request)
    {
        $range = $this->getEpiRange($request);

        if (!$range) {
            return response()->json(['error' => 'Missing epiweek range'], 400);
        }

        $data = $this->service->provinceCircles(
            $range['startYear'],
            $range['startWeek'],
            $range['endYear'],
            $range['endWeek']
        );

        return response()->json($data);
    }

    /*
    |--------------------------------------------------------------------------
    | Influenza subtype distribution (Overview)
    |--------------------------------------------------------------------------
    */

    public function influenzaSubtypeDetected(Request $request)
    {
        $range = $this->getEpiRange($request);

        if (!$range) {
            return response()->json(['error' => 'Missing epiweek range'], 400);
        }

        $data = $this->service->influenzaSubtypeDetected(
            $range['startYear'],
            $range['startWeek'],
            $range['endYear'],
            $range['endWeek']
        );

        return response()->json($data);
    }

    public function covidDistributedByAgeGroup(Request $request)
    {
        $range = $this->getEpiRange($request);

        if (!$range) {
            return response()->json(['error' => 'Missing epiweek range'], 400);
        }

        $data = $this->service->covidDistributedByAgeGroup(
            $range['startYear'],
            $range['startWeek'],
            $range['endYear'],
            $range['endWeek']
        );

        return response()->json($data);
    }

    public function covidLineageRelativeOverTime(Request $request)
    {
        $range = $this->getEpiRange($request);
        if (!$range) {
            return response()->json(['error' => 'Missing epiweek range'], 400);
        }

        $data = $this->service->covidLineageRelativeOverTime(
            $range['startYear'],
            $range['startWeek'],
            $range['endYear'],
            $range['endWeek']
        );

        return response()->json($data);
    }

    public function influenzaRelativeOverTime(Request $request)
    {
        $range = $this->getEpiRange($request);
        if (!$range) {
            return response()->json(['error' => 'Missing epiweek range'], 400);
        }

        $data = $this->service->influenzaRelativeOverTime(
            $range['startYear'],
            $range['startWeek'],
            $range['endYear'],
            $range['endWeek']
        );

        return response()->json($data);
    }


    public function influenzaRelativeOverTimeSequencing(Request $request)
    {
        $range = $this->getEpiRange($request);
        if (!$range) {
            return response()->json(['error' => 'Missing epiweek range'], 400);
        }

        $data = $this->service->influenzaRelativeOverTimeSequencing(
            $range['startYear'],
            $range['startWeek'],
            $range['endYear'],
            $range['endWeek']
        );

        return response()->json($data);
    }


    public function fetchSourceData()
    {
        try {
            $this->dataRetrievalService->getSurveillanceData();
            return response()->json(['message' => 'Data loaded successfully!'], 200);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Data loaded unsuccessfully!'], 400);
        }
    }

    /*
    |--------------------------------------------------------------------------
    | Sequencing Dashboard
    |--------------------------------------------------------------------------
    */

    public function sequencing(Request $request)
    {
        $surveillanceId = (int) $request->query('surveillance_id');
        $range = $this->getEpiRange($request);

        if (!$surveillanceId || !$range) {
            return response()->json(['error' => 'Missing parameters'], 400);
        }

        return response()->json([
            'trend' => $this->service->sequencingTrend(
                $surveillanceId,
                $range['startYear'],
                $range['startWeek'],
                $range['endYear'],
                $range['endWeek']
            ),'distribution' => $this->service->subtypeDistribution(
                $surveillanceId,
                $range['startYear'],
                $range['startWeek'],
                $range['endYear'],
                $range['endWeek']
            )
        ]);
    }

}
