<?php

namespace App\Models\Test;

use App\Models\BaseModel;

class TestDefCalModel extends BaseModel {
  protected $table      = 'testdefcal';
  protected $primaryKey = 'TestCalID';
  protected $allowedFields = [
    'TestSiteID',
    'DisciplineID', 
    'DepartmentID',
    'FormulaCode', 
    'RefType',
    'Unit1', 
    'Factor', 
    'Unit2', 
    'Decimal',
    'Method',
    'CreateDate', 
    'EndDate'
  ];  
  
  protected $useTimestamps = true;
  protected $createdField = 'CreateDate';
  protected $updatedField = '';
  protected $useSoftDeletes = true;
  protected $deletedField = "EndDate";

  /**
   * Get calculation details for a test with relations
   */
  public function getByTestSiteID($testSiteID) {
    return $this->db->table('testdefcal')
      ->select('testdefcal.*, d.DisciplineName, dept.DepartmentName')
      ->join('discipline d', 'd.DisciplineID=testdefcal.DisciplineID', 'left')
      ->join('department dept', 'dept.DepartmentID=testdefcal.DepartmentID', 'left')
      ->where('testdefcal.TestSiteID', $testSiteID)
      ->where('testdefcal.EndDate IS NULL')
      ->get()->getResultArray();
  }

  /**
   * Check if calculation exists for a test
   */
  public function existsByTestSiteID($testSiteID) {
    return $this->db->table('testdefcal')
      ->where('TestSiteID', $testSiteID)
      ->where('EndDate IS NULL')
      ->get()->getRowArray();
  }

  /**
   * Find an active calculation by TestSiteCode or TestSiteName (case-insensitive).
   */
  public function findActiveByCodeOrName(string $codeOrName): ?array
  {
    $identifier = mb_strtolower(trim($codeOrName));

    if ($identifier === '') {
      return null;
    }

    $builder = $this->db->table('testdefcal cal')
      ->select('cal.*, site.TestSiteCode, site.TestSiteName')
      ->join('testdefsite site', 'site.TestSiteID=cal.TestSiteID', 'left')
      ->where('cal.EndDate IS NULL')
      ->where('site.EndDate IS NULL')
      ->groupStart()
        ->where('LOWER(site.TestSiteCode)', $identifier)
        ->orWhere('LOWER(site.TestSiteName)', $identifier)
      ->groupEnd()
      ->orderBy('cal.CreateDate', 'DESC')
      ->limit(1);

    $row = $builder->get()->getRowArray();

    return $row ?: null;
  }

  /**
   * Disable calculation by TestSiteID
   */
  public function disableByTestSiteID($testSiteID) {
    $this->db->table('testdefcal')
      ->where('TestSiteID', $testSiteID)
      ->update(['EndDate' => date('Y-m-d H:i:s')]);
  }

  /**
   * Get calculated tests by discipline
   */
  public function getCalcsByDiscipline($disciplineID, $siteID = null) {
    $builder = $this->select('testdefcal.*, testdefsite.TestSiteCode, testdefsite.TestSiteName')
        ->join('testdefsite', 'testdefsite.TestSiteID=testdefcal.TestSiteID', 'left')
        ->where('testdefcal.DisciplineID', $disciplineID)
        ->where('testdefcal.EndDate IS NULL');
    
    if ($siteID) {
        $builder->where('testdefsite.SiteID', $siteID);
    }
    
    return $builder->findAll();
  }

  /**
   * Get calculated tests by department
   */
  public function getCalcsByDepartment($departmentID, $siteID = null) {
    $builder = $this->select('testdefcal.*, testdefsite.TestSiteCode, testdefsite.TestSiteName')
        ->join('testdefsite', 'testdefsite.TestSiteID=testdefcal.TestSiteID', 'left')
        ->where('testdefcal.DepartmentID', $departmentID)
        ->where('testdefcal.EndDate IS NULL');
    
    if ($siteID) {
        $builder->where('testdefsite.SiteID', $siteID);
    }
    
    return $builder->findAll();
  }
}
