<?php

namespace App\Controllers\Api;

use App\Controllers\BaseController;
use CodeIgniter\API\ResponseTrait;
use App\Models\Master\MasterControlsModel;
use App\Models\Master\MasterTestsModel;
use App\Models\Qc\ControlTestsModel;
use App\Models\Qc\ResultsModel;
use App\Models\Qc\ResultCommentsModel;

class ReportApiController extends BaseController
{
    use ResponseTrait;

    protected $dictControlModel;
    protected $dictTestModel;
    protected $controlTestModel;
    protected $resultModel;
    protected $commentModel;

    public function __construct()
    {
        $this->dictControlModel = new MasterControlsModel();
        $this->dictTestModel = new MasterTestsModel();
        $this->controlTestModel = new ControlTestsModel();
        $this->resultModel = new ResultsModel();
        $this->commentModel = new ResultCommentsModel();
    }

    public function getReport()
    {
        try {
            $control1 = $this->request->getGet('control1') ?? 0;
            $control2 = $this->request->getGet('control2') ?? 0;
            $control3 = $this->request->getGet('control3') ?? 0;
            $dates = $this->request->getGet('dates') ?? date('Y-m');
            $test = $this->request->getGet('test') ?? 0;

            $controlIds = array_filter([$control1, $control2, $control3]);

            $reportData = [];
            foreach ($controlIds as $controlId) {
                $control = $this->dictControlModel->find($controlId);
                if (!$control) continue;

                $controlTest = $this->controlTestModel->getByControlAndTest($control['controlId'], $test);
                $results = $this->resultModel->getByControlAndMonth($control['controlId'], $test, $dates);
                $comment = $this->commentModel->getByControlTestMonth($control['controlId'], $test, $dates);
                $testInfo = $this->dictTestModel->find($test);

                $outOfRangeCount = 0;
                $processedResults = [];
                if ($controlTest && $controlTest['sd'] > 0) {
                    foreach ($results as $res) {
                        $zScore = ($res['resValue'] - $controlTest['mean']) / $controlTest['sd'];
                        $outOfRange = abs($zScore) > 2;
                        if ($outOfRange) $outOfRangeCount++;

                        $processedResults[] = [
                            'resdate' => $res['resDate'],
                            'resvalue' => $res['resValue'],
                            'zScore' => round($zScore, 2),
                            'outOfRange' => $outOfRange,
                            'status' => $zScore === null ? '-' : (abs($zScore) > 2 ? 'Out' : (abs($zScore) > 1 ? 'Warn' : 'OK'))
                        ];
                    }
                } else {
                    foreach ($results as $res) {
                        $processedResults[] = [
                            'resdate' => $res['resDate'],
                            'resvalue' => $res['resValue'],
                            'zScore' => null,
                            'outOfRange' => false,
                            'status' => '-'
                        ];
                    }
                }

                $daysInMonth = date('t', strtotime($dates . '-01'));
                $values = [];
                for ($day = 1; $day <= $daysInMonth; $day++) {
                    $value = null;
                    foreach ($processedResults as $res) {
                        if (date('j', strtotime($res['resdate'])) == $day) {
                            $value = $res['resvalue'];
                            break;
                        }
                    }
                    $values[] = $value;
                }

                $reportData[] = [
                    'control' => $control,
                    'controlTest' => $controlTest,
                    'results' => $processedResults,
                    'values' => $values,
                    'test' => $testInfo,
                    'comment' => $comment,
                    'outOfRange' => $outOfRangeCount
                ];
            }

            return $this->respond([
                'status' => 'success',
                'message' => 'fetch success',
                'data' => [
                    'reportData' => $reportData,
                    'dates' => $dates,
                    'test' => $test,
                    'daysInMonth' => $daysInMonth
                ]
            ], 200);
        } catch (\Exception $e) {
            return $this->failServerError('Something went wrong: ' . $e->getMessage());
        }
    }
}
