<?php

namespace App\Database\Seeds;

use CodeIgniter\Database\Seeder;

class OrderSeeder extends Seeder
{
  public function run()
  {
    $now = date('Y-m-d H:i:s');
    $yesterday = date('Y-m-d H:i:s', strtotime('-1 day'));
    $twoDaysAgo = date('Y-m-d H:i:s', strtotime('-2 days'));

    echo "Creating dummy orders with specimens and results...\n";

    // Get existing test IDs from testdefsite
    $testIDs = $this->getTestIDs();
    if (empty($testIDs)) {
      echo "Error: No test definitions found. Please run TestSeeder first.\n";
      return;
    }

    // Get container definitions
    $containers = $this->db->table('containerdef')->get()->getResultArray();
    if (empty($containers)) {
      echo "Error: No container definitions found. Please run SpecimenSeeder first.\n";
      return;
    }

    // ========================================
    // ORDER 1: Patient 1 - Complete Blood Count (CBC)
    // ========================================
    $orderID1 = '001' . date('ymd', strtotime('-2 days')) . '00001';
    $internalOID1 = $this->createOrder([
      'OrderID' => $orderID1,
      'PlacerID' => 'PLC001',
      'InternalPID' => 1,
      'SiteID' => '1',
      'PVADTID' => 2,
      'ReqApp' => 'HIS',
      'Priority' => 'R',
      'TrnDate' => $twoDaysAgo,
      'EffDate' => $twoDaysAgo,
      'CreateDate' => $twoDaysAgo
    ]);

    echo "Created Order 1: {$orderID1} (InternalOID: {$internalOID1})\n";

    // Create specimen for CBC (EDTA tube - ConDefID = 9)
    $specimenID1 = $orderID1 . '-S01';
    $internalSID1 = $this->createSpecimen([
      'SID' => $specimenID1,
      'SiteID' => '1',
      'OrderID' => $internalOID1,
      'ConDefID' => 9,
      'Qty' => 1,
      'Unit' => 'tube',
      'GenerateBy' => 'ORDER',
      'CreateDate' => $twoDaysAgo
    ]);

    // Create specimen status progression
    $this->createSpecimenStatus($specimenID1, $internalOID1, 'PENDING', $twoDaysAgo);
    $this->createSpecimenStatus($specimenID1, $internalOID1, 'COLLECTED', date('Y-m-d H:i:s', strtotime('-2 days +30 minutes')));
    $this->createSpecimenStatus($specimenID1, $internalOID1, 'RECEIVED', date('Y-m-d H:i:s', strtotime('-2 days +1 hour')));
    $this->createSpecimenStatus($specimenID1, $internalOID1, 'PROCESSING', date('Y-m-d H:i:s', strtotime('-2 days +2 hours')));
    $this->createSpecimenStatus($specimenID1, $internalOID1, 'COMPLETED', date('Y-m-d H:i:s', strtotime('-1 day +8 hours')));

    echo "  Created Specimen: {$specimenID1} (EDTA)\n";

    // Create CBC test results
    $cbcTests = [
      ['code' => 'HB', 'result' => '14.2'],
      ['code' => 'HCT', 'result' => '42.5'],
      ['code' => 'RBC', 'result' => '4.85'],
      ['code' => 'WBC', 'result' => '7.2'],
      ['code' => 'PLT', 'result' => '285'],
      ['code' => 'MCV', 'result' => '87.6'],
      ['code' => 'MCH', 'result' => '29.3'],
      ['code' => 'MCHC', 'result' => '33.4'],
    ];

    foreach ($cbcTests as $test) {
      if (isset($testIDs[$test['code']])) {
        $this->createPatRes([
          'OrderID' => $internalOID1,
          'InternalSID' => $internalSID1,
          'SID' => $specimenID1,
          'TestSiteID' => $testIDs[$test['code']],
          'TestSiteCode' => $test['code'],
          'Result' => $test['result'],
          'SampleType' => 'Whole Blood',
          'ResultDateTime' => date('Y-m-d H:i:s', strtotime('-1 day +8 hours')),
          'CreateDate' => date('Y-m-d H:i:s', strtotime('-1 day +8 hours'))
        ]);
      }
    }

    echo "  Created " . count($cbcTests) . " CBC results\n";

    // Create order status
    $this->createOrderStatus($internalOID1, 'ORDERED', $twoDaysAgo);
    $this->createOrderStatus($internalOID1, 'SPECIMEN_COLLECTED', date('Y-m-d H:i:s', strtotime('-2 days +30 minutes')));
    $this->createOrderStatus($internalOID1, 'IN_LAB', date('Y-m-d H:i:s', strtotime('-2 days +2 hours')));
    $this->createOrderStatus($internalOID1, 'COMPLETED', date('Y-m-d H:i:s', strtotime('-1 day +8 hours')));
    $this->createOrderStatus($internalOID1, 'REPORTED', date('Y-m-d H:i:s', strtotime('-1 day +9 hours')));

    // Create order comment
    $this->createOrderComment($internalOID1, 'Routine CBC ordered for annual checkup', $twoDaysAgo);

    // ========================================
    // ORDER 2: Patient 2 - Lipid Profile + Liver Function
    // ========================================
    $orderID2 = '001' . date('ymd', strtotime('-1 day')) . '00002';
    $internalOID2 = $this->createOrder([
      'OrderID' => $orderID2,
      'PlacerID' => 'PLC002',
      'InternalPID' => 2,
      'SiteID' => '1',
      'PVADTID' => 3,
      'ReqApp' => 'HIS',
      'Priority' => 'R',
      'TrnDate' => $yesterday,
      'EffDate' => $yesterday,
      'CreateDate' => $yesterday
    ]);

    echo "\nCreated Order 2: {$orderID2} (InternalOID: {$internalOID2})\n";

    // Create specimen for Lipid/Liver (SST tube - ConDefID = 1)
    $specimenID2 = $orderID2 . '-S01';
    $internalSID2 = $this->createSpecimen([
      'SID' => $specimenID2,
      'SiteID' => '1',
      'OrderID' => $internalOID2,
      'ConDefID' => 1,
      'Qty' => 1,
      'Unit' => 'tube',
      'GenerateBy' => 'ORDER',
      'CreateDate' => $yesterday
    ]);

    $this->createSpecimenStatus($specimenID2, $internalOID2, 'PENDING', $yesterday);
    $this->createSpecimenStatus($specimenID2, $internalOID2, 'COLLECTED', date('Y-m-d H:i:s', strtotime('-1 day +30 minutes')));
    $this->createSpecimenStatus($specimenID2, $internalOID2, 'RECEIVED', date('Y-m-d H:i:s', strtotime('-1 day +2 hours')));
    $this->createSpecimenStatus($specimenID2, $internalOID2, 'COMPLETED', date('Y-m-d H:i:s', strtotime('-1 day +6 hours')));

    echo "  Created Specimen: {$specimenID2} (SST)\n";

    // Create Lipid Profile results
    $lipidTests = [
      ['code' => 'CHOL', 'result' => '195'],
      ['code' => 'TG', 'result' => '145'],
      ['code' => 'HDL', 'result' => '55'],
      ['code' => 'LDL', 'result' => '115'],
    ];

    foreach ($lipidTests as $test) {
      if (isset($testIDs[$test['code']])) {
        $this->createPatRes([
          'OrderID' => $internalOID2,
          'InternalSID' => $internalSID2,
          'SID' => $specimenID2,
          'TestSiteID' => $testIDs[$test['code']],
          'TestSiteCode' => $test['code'],
          'Result' => $test['result'],
          'SampleType' => 'Serum',
          'ResultDateTime' => date('Y-m-d H:i:s', strtotime('-1 day +6 hours')),
          'CreateDate' => date('Y-m-d H:i:s', strtotime('-1 day +6 hours'))
        ]);
      }
    }

    // Create Liver Function results
    $liverTests = [
      ['code' => 'SGOT', 'result' => '28'],
      ['code' => 'SGPT', 'result' => '32'],
    ];

    foreach ($liverTests as $test) {
      if (isset($testIDs[$test['code']])) {
        $this->createPatRes([
          'OrderID' => $internalOID2,
          'InternalSID' => $internalSID2,
          'SID' => $specimenID2,
          'TestSiteID' => $testIDs[$test['code']],
          'TestSiteCode' => $test['code'],
          'Result' => $test['result'],
          'SampleType' => 'Serum',
          'ResultDateTime' => date('Y-m-d H:i:s', strtotime('-1 day +6 hours')),
          'CreateDate' => date('Y-m-d H:i:s', strtotime('-1 day +6 hours'))
        ]);
      }
    }

    echo "  Created " . (count($lipidTests) + count($liverTests)) . " chemistry results\n";

    // Create order status
    $this->createOrderStatus($internalOID2, 'ORDERED', $yesterday);
    $this->createOrderStatus($internalOID2, 'SPECIMEN_COLLECTED', date('Y-m-d H:i:s', strtotime('-1 day +30 minutes')));
    $this->createOrderStatus($internalOID2, 'IN_LAB', date('Y-m-d H:i:s', strtotime('-1 day +2 hours')));
    $this->createOrderStatus($internalOID2, 'COMPLETED', date('Y-m-d H:i:s', strtotime('-1 day +6 hours')));

    // ========================================
    // ORDER 3: Patient 3 - Renal Function + Glucose (URGENT)
    // ========================================
    $orderID3 = '001' . date('ymd', strtotime('-1 day')) . '00003';
    $internalOID3 = $this->createOrder([
      'OrderID' => $orderID3,
      'PlacerID' => 'PLC003',
      'InternalPID' => 3,
      'SiteID' => '1',
      'PVADTID' => 4,
      'ReqApp' => 'EMR',
      'Priority' => 'U',
      'TrnDate' => $yesterday,
      'EffDate' => $yesterday,
      'CreateDate' => $yesterday
    ]);

    echo "\nCreated Order 3: {$orderID3} (InternalOID: {$internalOID3}) [URGENT]\n";

    // Create specimen for Renal/Glucose (SST tube)
    $specimenID3 = $orderID3 . '-S01';
    $internalSID3 = $this->createSpecimen([
      'SID' => $specimenID3,
      'SiteID' => '1',
      'OrderID' => $internalOID3,
      'ConDefID' => 1,
      'Qty' => 1,
      'Unit' => 'tube',
      'GenerateBy' => 'ORDER',
      'CreateDate' => $yesterday
    ]);

    $this->createSpecimenStatus($specimenID3, $internalOID3, 'PENDING', $yesterday);
    $this->createSpecimenStatus($specimenID3, $internalOID3, 'COLLECTED', date('Y-m-d H:i:s', strtotime('-1 day +20 minutes')));
    $this->createSpecimenStatus($specimenID3, $internalOID3, 'RECEIVED', date('Y-m-d H:i:s', strtotime('-1 day +30 minutes')));
    $this->createSpecimenStatus($specimenID3, $internalOID3, 'PROCESSING', date('Y-m-d H:i:s', strtotime('-1 day +45 minutes')));
    $this->createSpecimenStatus($specimenID3, $internalOID3, 'COMPLETED', date('Y-m-d H:i:s', strtotime('-1 day +2 hours')));

    echo "  Created Specimen: {$specimenID3} (SST)\n";

    // Create Renal Function results
    $renalTests = [
      ['code' => 'CREA', 'result' => '1.1'],
      ['code' => 'UREA', 'result' => '18'],
    ];

    foreach ($renalTests as $test) {
      if (isset($testIDs[$test['code']])) {
        $this->createPatRes([
          'OrderID' => $internalOID3,
          'InternalSID' => $internalSID3,
          'SID' => $specimenID3,
          'TestSiteID' => $testIDs[$test['code']],
          'TestSiteCode' => $test['code'],
          'Result' => $test['result'],
          'SampleType' => 'Serum',
          'ResultDateTime' => date('Y-m-d H:i:s', strtotime('-1 day +2 hours')),
          'CreateDate' => date('Y-m-d H:i:s', strtotime('-1 day +2 hours'))
        ]);
      }
    }

    // Create Glucose result
    if (isset($testIDs['GLU'])) {
      $this->createPatRes([
        'OrderID' => $internalOID3,
        'InternalSID' => $internalSID3,
        'SID' => $specimenID3,
        'TestSiteID' => $testIDs['GLU'],
        'TestSiteCode' => 'GLU',
        'Result' => '95',
        'SampleType' => 'Serum',
        'ResultDateTime' => date('Y-m-d H:i:s', strtotime('-1 day +2 hours')),
        'CreateDate' => date('Y-m-d H:i:s', strtotime('-1 day +2 hours'))
      ]);
    }

    echo "  Created " . (count($renalTests) + 1) . " urgent chemistry results\n";

    // Create order status (fast-tracked for urgent)
    $this->createOrderStatus($internalOID3, 'ORDERED', $yesterday);
    $this->createOrderStatus($internalOID3, 'SPECIMEN_COLLECTED', date('Y-m-d H:i:s', strtotime('-1 day +20 minutes')));
    $this->createOrderStatus($internalOID3, 'IN_LAB', date('Y-m-d H:i:s', strtotime('-1 day +30 minutes')));
    $this->createOrderStatus($internalOID3, 'COMPLETED', date('Y-m-d H:i:s', strtotime('-1 day +2 hours')));
    $this->createOrderStatus($internalOID3, 'REPORTED', date('Y-m-d H:i:s', strtotime('-1 day +2 hours +15 minutes')));

    // Create order comment
    $this->createOrderComment($internalOID3, 'STAT order for suspected kidney dysfunction. Patient has diabetes history.', $yesterday);

    // ========================================
    // ORDER 4: Patient 1 - Urinalysis (PENDING)
    // ========================================
    $orderID4 = '001' . date('ymd') . '00004';
    $internalOID4 = $this->createOrder([
      'OrderID' => $orderID4,
      'PlacerID' => 'PLC004',
      'InternalPID' => 1,
      'SiteID' => '1',
      'PVADTID' => 2,
      'ReqApp' => 'HIS',
      'Priority' => 'R',
      'TrnDate' => $now,
      'EffDate' => $now,
      'CreateDate' => $now
    ]);

    echo "\nCreated Order 4: {$orderID4} (InternalOID: {$internalOID4})\n";

    // Create urine specimen (Pot Urin - ConDefID = 12)
    $specimenID4 = $orderID4 . '-S01';
    $internalSID4 = $this->createSpecimen([
      'SID' => $specimenID4,
      'SiteID' => '1',
      'OrderID' => $internalOID4,
      'ConDefID' => 12,
      'Qty' => 1,
      'Unit' => 'container',
      'GenerateBy' => 'ORDER',
      'CreateDate' => $now
    ]);

    $this->createSpecimenStatus($specimenID4, $internalOID4, 'PENDING', $now);

    echo "  Created Specimen: {$specimenID4} (Urine)\n";

    // Create Urinalysis results (pending - use current time for ResultDateTime)
    $urineTests = [
      ['code' => 'UCOLOR'],
      ['code' => 'UGLUC'],
      ['code' => 'UPROT'],
      ['code' => 'PH'],
    ];

    foreach ($urineTests as $test) {
      if (isset($testIDs[$test['code']])) {
        $this->createPatRes([
          'OrderID' => $internalOID4,
          'InternalSID' => $internalSID4,
          'SID' => $specimenID4,
          'TestSiteID' => $testIDs[$test['code']],
          'TestSiteCode' => $test['code'],
          'Result' => null,
          'SampleType' => 'Urine',
          'ResultDateTime' => $now,
          'CreateDate' => $now
        ]);
      }
    }

    echo "  Created " . count($urineTests) . " pending urinalysis results\n";

    // Create order status
    $this->createOrderStatus($internalOID4, 'ORDERED', $now);

    // ========================================
    // ORDER 5: Patient 3 - Multiple tubes (CBC + Chemistry)
    // ========================================
    $orderID5 = '001' . date('ymd') . '00005';
    $internalOID5 = $this->createOrder([
      'OrderID' => $orderID5,
      'PlacerID' => 'PLC005',
      'InternalPID' => 3,
      'SiteID' => '1',
      'PVADTID' => 4,
      'ReqApp' => 'HIS',
      'Priority' => 'R',
      'TrnDate' => $now,
      'EffDate' => $now,
      'CreateDate' => $now
    ]);

    echo "\nCreated Order 5: {$orderID5} (InternalOID: {$internalOID5}) [Multi-container]\n";

    // Create EDTA specimen for CBC
    $specimenID5a = $orderID5 . '-S01';
    $internalSID5a = $this->createSpecimen([
      'SID' => $specimenID5a,
      'SiteID' => '1',
      'OrderID' => $internalOID5,
      'ConDefID' => 9,
      'Qty' => 1,
      'Unit' => 'tube',
      'GenerateBy' => 'ORDER',
      'CreateDate' => $now
    ]);

    $this->createSpecimenStatus($specimenID5a, $internalOID5, 'PENDING', $now);

    echo "  Created Specimen: {$specimenID5a} (EDTA)\n";

    // Create SST specimen for Chemistry
    $specimenID5b = $orderID5 . '-S02';
    $internalSID5b = $this->createSpecimen([
      'SID' => $specimenID5b,
      'SiteID' => '1',
      'OrderID' => $internalOID5,
      'ConDefID' => 1,
      'Qty' => 1,
      'Unit' => 'tube',
      'GenerateBy' => 'ORDER',
      'CreateDate' => $now
    ]);

    $this->createSpecimenStatus($specimenID5b, $internalOID5, 'PENDING', $now);

    echo "  Created Specimen: {$specimenID5b} (SST)\n";

    // Create pending results for CBC
    foreach ($cbcTests as $test) {
      if (isset($testIDs[$test['code']])) {
        $this->createPatRes([
          'OrderID' => $internalOID5,
          'InternalSID' => $internalSID5a,
          'SID' => $specimenID5a,
          'TestSiteID' => $testIDs[$test['code']],
          'TestSiteCode' => $test['code'],
          'Result' => null,
          'SampleType' => 'Whole Blood',
          'ResultDateTime' => $now,
          'CreateDate' => $now
        ]);
      }
    }

    // Create pending results for Chemistry
    $chemTests = ['GLU', 'CREA', 'UREA', 'SGOT', 'SGPT'];
    foreach ($chemTests as $testCode) {
      if (isset($testIDs[$testCode])) {
        $this->createPatRes([
          'OrderID' => $internalOID5,
          'InternalSID' => $internalSID5b,
          'SID' => $specimenID5b,
          'TestSiteID' => $testIDs[$testCode],
          'TestSiteCode' => $testCode,
          'Result' => null,
          'SampleType' => 'Serum',
          'ResultDateTime' => $now,
          'CreateDate' => $now
        ]);
      }
    }

    echo "  Created " . (count($cbcTests) + count($chemTests)) . " pending results\n";

    // Create order status
    $this->createOrderStatus($internalOID5, 'ORDERED', $now);

    // ========================================
    // ORDER 6: Patient 2 - Bilirubin Panel (TBIL, DBIL, IBIL)
    // ========================================
    $orderID6 = '001' . date('ymd') . '00006';
    $internalOID6 = $this->createOrder([
      'OrderID' => $orderID6,
      'PlacerID' => 'PLC006',
      'InternalPID' => 2,
      'SiteID' => '1',
      'PVADTID' => 3,
      'ReqApp' => 'HIS',
      'Priority' => 'R',
      'TrnDate' => $now,
      'EffDate' => $now,
      'CreateDate' => $now
    ]);

    echo "\nCreated Order 6: {$orderID6} (InternalOID: {$internalOID6}) [Bilirubin Panel]\n";

    // Create specimen for Bilirubin tests (SST tube - ConDefID = 1)
    $specimenID6 = $orderID6 . '-S01';
    $internalSID6 = $this->createSpecimen([
      'SID' => $specimenID6,
      'SiteID' => '1',
      'OrderID' => $internalOID6,
      'ConDefID' => 1,
      'Qty' => 1,
      'Unit' => 'tube',
      'GenerateBy' => 'ORDER',
      'CreateDate' => $now
    ]);

    $this->createSpecimenStatus($specimenID6, $internalOID6, 'PENDING', $now);
    $this->createSpecimenStatus($specimenID6, $internalOID6, 'COLLECTED', date('Y-m-d H:i:s', strtotime('+30 minutes')));
    $this->createSpecimenStatus($specimenID6, $internalOID6, 'RECEIVED', date('Y-m-d H:i:s', strtotime('+2 hours')));
    $this->createSpecimenStatus($specimenID6, $internalOID6, 'COMPLETED', date('Y-m-d H:i:s', strtotime('+6 hours')));

    echo "  Created Specimen: {$specimenID6} (SST)\n";

    // Create order status
    $this->createOrderStatus($internalOID6, 'ORDERED', $now);
    $this->createOrderStatus($internalOID6, 'SPECIMEN_COLLECTED', date('Y-m-d H:i:s', strtotime('+30 minutes')));
    $this->createOrderStatus($internalOID6, 'IN_LAB', date('Y-m-d H:i:s', strtotime('+2 hours')));
    $this->createOrderStatus($internalOID6, 'COMPLETED', date('Y-m-d H:i:s', strtotime('+6 hours')));
    $this->createOrderStatus($internalOID6, 'REPORTED', date('Y-m-d H:i:s', strtotime('+7 hours')));

    // Create order comment
    $this->createOrderComment($internalOID6, 'Bilirubin panel ordered for liver function assessment', $now);

    // ========================================
    // SUMMARY
    // ========================================
    echo "\n";
    echo "========================================\n";
    echo "ORDER SEEDING COMPLETED SUCCESSFULLY!\n";
    echo "========================================\n";
    echo "Orders Created: 6\n";
    echo "  - Order 1: CBC (Complete Blood Count) - COMPLETED\n";
    echo "  - Order 2: Lipid + Liver Profile - COMPLETED\n";
    echo "  - Order 3: Renal + Glucose - COMPLETED (URGENT)\n";
    echo "  - Order 4: Urinalysis - PENDING\n";
    echo "  - Order 5: CBC + Chemistry - PENDING (Multi-container)\n";
    echo "  - Order 6: Bilirubin Panel (TBIL, DBIL, IBIL) - COMPLETED\n";
    echo "----------------------------------------\n";
    echo "Specimens Created: 7\n";
    echo "  - SST tubes: 5\n";
    echo "  - EDTA tubes: 2\n";
    echo "  - Urine containers: 1\n";
    echo "----------------------------------------\n";
    echo "Patient Results: 29 total\n";
    echo "  - With results: 16\n";
    echo "  - Pending: 13\n";
    echo "========================================\n";
  }

  private function getTestIDs(): array
  {
    $tests = $this->db->table('testdefsite')
      ->select('TestSiteID, TestSiteCode')
      ->where('EndDate IS NULL')
      ->get()
      ->getResultArray();

    $testIDs = [];
    foreach ($tests as $test) {
      $testIDs[$test['TestSiteCode']] = $test['TestSiteID'];
    }

    return $testIDs;
  }

  private function createOrder(array $data): int
  {
    $this->db->table('ordertest')->insert($data);
    return $this->db->insertID();
  }

  private function createSpecimen(array $data): int
  {
    $this->db->table('specimen')->insert($data);
    return $this->db->insertID();
  }

  private function createSpecimenStatus(string $specimenID, int $orderID, string $status, string $dateTime): void
  {
    $this->db->table('specimenstatus')->insert([
      'SID' => $specimenID,
      'OrderID' => $orderID,
      'SpcStatus' => $status,
      'CreateDate' => $dateTime
    ]);
  }

  private function createPatRes(array $data): void
  {
    $this->db->table('patres')->insert($data);
  }

  private function createOrderStatus(int $orderID, string $status, string $dateTime): void
  {
    $this->db->table('orderstatus')->insert([
      'InternalOID' => $orderID,
      'OrderStatus' => $status,
      'CreateDate' => $dateTime
    ]);
  }

  private function createOrderComment(int $orderID, string $comment, string $dateTime): void
  {
    $this->db->table('ordercom')->insert([
      'InternalOID' => $orderID,
      'Comment' => $comment,
      'CreateDate' => $dateTime
    ]);
  }
}
