<?php

namespace App\Http\Controllers;
//namespace App\Exports;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\PtConfig;
use App\Models\Patients;
use App\Models\Followup_general;
use App\Models\Dispensing;
use App\Models\tb_registerO3;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use Carbon\Carbon;
use Illuminate\Support\Facades\Schema;
use App\Exports\TB03\TB03_Report;
use App\Exports\TB03\TB08_Report;
use App\Exports\TB03\TB_IPT_Report;
use App\Exports\TB03\TB03_Export;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Arr;
use App\Exports\Export_age;

class Tb03Controller extends Controller
{
  public function tb03_View()
  {
    return view('TB.tb03', ["report_view" => null]);
  }

  public function Tb03(Request $request)
  {
    $table = "General";
    $notice = $request->input('notice');
    if ($notice == "Find TB03 patient") {
      $Tb03_general = [];
      $Pid03 = $request->input('Pid03');
      $Fid03 = $request->input('Fid03');
      $TB03_Id = $request->input('TB03_Id');
      $NewRc_sameId = $request->input('NewRc_sameId');
      if (($Pid03 === null || $Pid03 === '') && ($Fid03 === null || $Fid03 === '') && ($TB03_Id === null || $TB03_Id === '')) {
        return response()->json(['message' => 'ID required'], 400);
      }

      if ($request["ID_change"] != "yes") {
        $historyQuery = tb_registerO3::query()
          ->where(function ($query) use ($Pid03, $Fid03, $TB03_Id) {
            if ($Pid03 !== null && $Pid03 !== '') {
              $query->where('Pid_TB03', $Pid03);
            }
            if ($Fid03 !== null && $Fid03 !== '' && $Fid03 !== "-") {
              $query->orWhere('FuchiaID_TB03', $Fid03);
            }
            if ($TB03_Id !== null && $TB03_Id !== '' && $TB03_Id !== "-") {
              $query->orWhere('TNumber_TB03', $TB03_Id);
            }
          });

        $clinic = $request->session()->get('tb.clinic');
        $clinicHistory = clone $historyQuery;
        if ($clinic) {
          $clinicHistory->where('Clinic_code', $clinic);
        }
        $Tb03_general[1] = $clinicHistory->orderBy('TreDate_TB03')->orderBy('id')->get();
        if ($Tb03_general[1]->isEmpty()) {
          $Tb03_general[1] = $historyQuery->orderBy('TreDate_TB03')->orderBy('id')->get();
        }
      } else {
        $Tb03_general[1] = collect();
      }

      $latest = $Tb03_general[1]->last();
      $Tb03_general[0] = [
        'Pid' => $latest->Pid_TB03 ?? $Pid03,
        'FuchiaID' => $latest->FuchiaID_TB03 ?? $Fid03,
        'Name' => $latest->Name_TB03 ?? '',
        'Name_TB03' => $latest->Name_TB03 ?? '',
        'Township' => $latest->Township_TB03 ?? '',
        'Region' => $latest->State_TB03 ?? '',
        'Agey' => $latest->Age_TB03 ?? '',
        'Agem' => '',
        'Gender' => $latest->Gender ?? '',
        'Clinic Code' => $latest->Clinic_code ?? $request->session()->get('tb.clinic'),
        'Reg Date' => $latest->TreDate_TB03 ?? '',
        'Date of Birth' => '',
      ];

      return response()->json([
        $Tb03_general[0],
        $Tb03_general[1]->values(),
      ]);
    } else if ($notice == "TB_03 Register") {

      tb_registerO3::create([
        'Clinic_code' => $request->input("Clinic Code"),
        'Pid_TB03' => $request->input("TB03_pid"),
        'Name_TB03' => $request->input("TB03_name"),
        'FuchiaID_TB03' => $request->input("TB03_fuchiaId"),
        'TNumber_TB03' => $request->input("TB03_id"),
        'Age_TB03' => $request->input("TB03_age"),
        'Gender' => $request->input("TB03_gender"),
        'TreDate_TB03' => $request->input("TB03_tremDate"),
        'State_TB03' => $request->input("TB03_state"),
        'Township_TB03' => $request->input("TB03_town"),
        'Nationality_TB03' => $request->input("TB03_nationality"),
        'FaciName_TB03' => $request->input("TB03_facility"),
        'RePariod_TB03' => $request->input("TB03_reportPeriod"),
        'TranferIn_TB03' => $request->input("TB03_transfer"),
        'ReferFrom_TB03' => $request->input("TB03_referFrom"),
        'TypePatient_TB03' => $request->input("TB03_typePatient"),
        'TBsite_TB03' => $request->input("TB03_site"),
        'EPTBsite_TB03' => $request->input("TB03_EPTB"),
        'TreRegimens_TB03' => $request->input("TB03_treRegimens"),
        'Smoke_status_TB03' => $request->input("TB03_smoke"),
        'DMstatue_TB03' => $request->input("TB03_dm"),
        'Hivstatus_TB03' => $request->input("TB03_hiv"),
        'ART_start_TB03' => $request->input("TB03_ART"),
        'CPT_start_TB03' => $request->input("TB03_CPT"),
        'Microscope_Res_TB03' => $request->input("TB03_microscope"),
        'Xpert_Res_TB03' => $request->input("TB03_Xpert"),
        'XRay_Res_TB03' => $request->input("TB03_Xray"),
        'Calture_Res_TB03' => $request->input("TB03_culture"),
        'Counsellor_TB03' => $request->input("TB03_counselor"),
        'BioClinical_TB03' => $request->input("TB03_bactlogical"),
        '2ndMicroscope_Res_TB03' => $request->input("TB03_2ndmicroscope"),
        '2ndXpert_Res_TB03' => $request->input("TB03_2ndXpert"),
        '3rdMicroscope_Res_TB03' => $request->input("TB03_3rdmicroscope"),
        '3rdXpert_Res_TB03' => $request->input("TB03_3rdXpert"),
        '5rdMicroscope_Res_TB03' => $request->input("TB03_5thmicroscope"),
        '5rdXpert_Res_TB03' => $request->input("TB03_5thXpert"),
        'EndTX_Microscope_Res_TB03' => $request->input("TB03_endmicroscope"),
        'EndTX_XRay_Res_TB03' => $request->input("TB03_endXray"),
        'EndTX_Xpert_Res_TB03' => $request->input("TB03_endXpert"),
        'TrementOut_TB03' => $request->input("TB03_outcome"),
        'Intial_RegimenDate_TB03' => $request->input("TB03_IRSD"),
        'TrementOut_Date_TB03' => $request->input("TB03_outDate"),
        'EstimentOut_Date_TB03' => $request->input("TB03_EoutDate"),
        'Remark_TB03' => $request->input("TB03_remark"),
        '2ndCulture_Res_TB03' => $request->input('TB03_culture_m2'),
        '3rdCulture_Res_TB03' => $request->input('TB03_culture_m3'),
        '5rdCulture_Res_TB03' => $request->input('TB03_culture_m5'),
        '1stDst' => $request->input('1st_dst'),

      ]);
      return response()->json(["Register 03 save Successfully"]);
    } else if ($notice == "TB_03 Update") {
      $rid = $request->input("Rid");
      tb_registerO3::where("id", $rid)->update([
        'Clinic_code' => $request->input("Clinic Code"),
        'Pid_TB03' => $request->input("TB03_pid"),
        'Name_TB03' => $request->input("TB03_name"),
        'FuchiaID_TB03' => $request->input("TB03_fuchiaId"),
        'TNumber_TB03' => $request->input("TB03_id"),
        'Age_TB03' => $request->input("TB03_age"),
        'Gender' => $request->input("TB03_gender"),
        'TreDate_TB03' => $request->input("TB03_tremDate"),
        'State_TB03' => $request->input("TB03_state"),
        'Township_TB03' => $request->input("TB03_town"),
        'Nationality_TB03' => $request->input("TB03_nationality"),
        'FaciName_TB03' => $request->input("TB03_facility"),
        'RePariod_TB03' => $request->input("TB03_reportPeriod"),
        'TranferIn_TB03' => $request->input("TB03_transfer"),
        'ReferFrom_TB03' => $request->input("TB03_referFrom"),
        'TypePatient_TB03' => $request->input("TB03_typePatient"),
        'TBsite_TB03' => $request->input("TB03_site"),
        'EPTBsite_TB03' => $request->input("TB03_EPTB"),
        'TreRegimens_TB03' => $request->input("TB03_treRegimens"),
        'Smoke_status_TB03' => $request->input("TB03_smoke"),
        'DMstatue_TB03' => $request->input("TB03_dm"),
        'Hivstatus_TB03' => $request->input("TB03_hiv"),
        'ART_start_TB03' => $request->input("TB03_ART"),
        'CPT_start_TB03' => $request->input("TB03_CPT"),
        'Microscope_Res_TB03' => $request->input("TB03_microscope"),
        'Xpert_Res_TB03' => $request->input("TB03_Xpert"),
        'XRay_Res_TB03' => $request->input("TB03_Xray"),
        'Calture_Res_TB03' => $request->input("TB03_culture"),
        'Counsellor_TB03' => $request->input("TB03_counselor"),
        'BioClinical_TB03' => $request->input("TB03_bactlogical"),
        '2ndMicroscope_Res_TB03' => $request->input("TB03_2ndmicroscope"),
        '2ndXpert_Res_TB03' => $request->input("TB03_2ndXpert"),
        '3rdMicroscope_Res_TB03' => $request->input("TB03_3rdmicroscope"),
        '3rdXpert_Res_TB03' => $request->input("TB03_3rdXpert"),
        '5rdMicroscope_Res_TB03' => $request->input("TB03_5thmicroscope"),
        '5rdXpert_Res_TB03' => $request->input("TB03_5thXpert"),
        'EndTX_Microscope_Res_TB03' => $request->input("TB03_endmicroscope"),
        'EndTX_XRay_Res_TB03' => $request->input("TB03_endXray"),
        'EndTX_Xpert_Res_TB03' => $request->input("TB03_endXpert"),
        'TrementOut_TB03' => $request->input("TB03_outcome"),
        'Intial_RegimenDate_TB03' => $request->input("TB03_IRSD"),
        'TrementOut_Date_TB03' => $request->input("TB03_outDate"),
        'EstimentOut_Date_TB03' => $request->input("TB03_EoutDate"),
        'Remark_TB03' => $request->input("TB03_remark"),
        '2ndCulture_Res_TB03' => $request['TB03_culture_m2'],
        '3rdCulture_Res_TB03' => $request['TB03_culture_m3'],
        '5rdCulture_Res_TB03' => $request['TB03_culture_m5'],
        '1stDst' => $request['1st_dst'],
      ]);
      return response()->json(["Register Update save Successfully"]);
    } else if ($notice == "TB 03 Report" || $notice == "TB 03 Export") {
      $dateForm = date("Y-m-d", strtotime($request["dateFrom"]));
      $dateTo = date("Y-m-d", strtotime($request["dateTo"]));
      $TB03_report_dataes = tb_registerO3::whereBetween("TreDate_TB03", [$dateForm, $dateTo])
        ->with([
          'ptconfig' => function ($query) {
            $query->select("Pid", 'Date of Birth', 'Agey', 'Agem', "Main Risk", "Sub Risk", "Gender", "FuchiaID");
          }
        ])->get()->makeHidden(['created_at', 'updated_at']);

      $TB03_report_date = ["TreDate_TB03", "ART_start_TB03", "CPT_start_TB03", "Intial_RegimenDate_TB03", "TrementOut_Date_TB03", "EstimentOut_Date_TB03"];
      foreach ($TB03_report_dataes as $index => $TB03_report_data) {
        if ($TB03_report_data["ptconfig"] != null) {
          $TB03_report_data = Export_age::Export_general($TB03_report_data["ptconfig"], $TB03_report_data["TreDate_TB03"], $TB03_report_data["ptconfig"]["Date of Birth"], $TB03_report_data);
          //dd($TB03_report_data);
          $TB03_report_data["Gender"] = Crypt::decrypt_light($TB03_report_data["ptconfig"]["Gender"], "General");
          if ($TB03_report_data["Gender"] == "Male") {
            $TB03_report_data["Gender"] = "M";
          } else {
            $TB03_report_data["Gender"] = "F";
          };
        }



        if ($notice != "TB 03 Report") {
          foreach ($TB03_report_date as $column) {
            if ($TB03_report_data[$column] != null) {
              $carbonDate = Carbon::createFromFormat('Y-m-d', $TB03_report_data[$column]);
              $carbonDate = Carbon::createFromFormat('d-m-Y', $carbonDate->format('d-m-Y'));
              $TB03_report_dataes[$index][$column] = Date::dateTimeToExcel($carbonDate->toDateTime());
            }
          }
        }
      }

      if ($notice == "TB 03 Report") {
        $selected_report = $request["TB_03_report"];
        $report_type = $request["TB_03_report_type"];
        $cal_resultes = [];
        if ($selected_report == "TB_O7") {
          if ($report_type == "Report_view") {
            $report_view = new TB03_Report($TB03_report_dataes, $cal_resultes);
            $report_view->calculating_report();
            $report_view->cal_resultes["report_type"] = "Report_view";
            // dd($test->cal_resultes);
            return view('TB.export.tb03_report_07', [
              'cal_resultes' => $report_view->cal_resultes,
            ]);
          } else {

            return Excel::download(new TB03_Report($TB03_report_dataes, $cal_resultes), 'TB03 Report' . date("d-m-Y") . '.xlsx');
          }
        } //07
        else if ($selected_report == "TB_O8") {
          if ($report_type == "Report_view") {
            $report_view = new TB08_Report($TB03_report_dataes, $cal_resultes);
            $report_view->calculate_report_O8();
            $report_view->cal_resultes["report_type"] = "Report_view";

            return view('TB.export.tb03_report_08', [
              'cal_resultes' => $report_view->cal_resultes,
            ]);
          } else {
            return Excel::download(new TB08_Report($TB03_report_dataes, $cal_resultes), 'TB_08 Report' . date("d-m-Y") . '.xlsx');
          }
        } //08
        else {
          if ($report_type == "Report_view") {
            $report_view = new TB_IPT_Report($TB03_report_dataes, $cal_resultes);
            $report_view->calculate_report_IPT();
            $report_view->cal_resultes["report_type"] = "Report_view";
            // dd($test->cal_resultes);
            return view('TB.export.tb03_report_IPT', [
              'cal_resultes' => $report_view->cal_resultes,
            ]);
          } else {
            return Excel::download(new TB_IPT_Report($TB03_report_dataes, $cal_resultes), 'TB_IPT Report' . date("d-m-Y") . '.xlsx');
          }
        } //IPT






      } //TB all Report
      else {

        return Excel::download(new TB03_Export($TB03_report_dataes), 'TB03 Export' . date("d-m-Y") . '.xlsx');
      } //TB all Export

    } else if ($notice == "Remvoe TB03") {
      $delete = tb_registerO3::where('id', $request["id"])->where('Pid_TB03', $request["Pid"])->delete();
      if ($delete) {
        DB::connection('MAM_NAP')->statement('SET @id := 0');
        DB::connection('MAM_NAP')->statement('UPDATE tb_register_o3_s SET id = @id := @id + 1');
        DB::connection('MAM_NAP')->statement('ALTER TABLE tb_register_o3_s AUTO_INCREMENT = 1');
      }
      return response()->json($delete);
    }
  }

  public function tb03_goback()
  {
    return redirect()->back();
  }

  public function downloadSync(Request $request)
  {
    $request->validate([
      'since' => ['nullable', 'date'],
    ]);

    $query = tb_registerO3::query()->latest('updated_at');
    $clinic = $request->session()->get('tb.clinic');
    if ($clinic) {
      $query->where('Clinic_code', $clinic);
    }

    if ($request->filled('since')) {
      try {
        $query->where('updated_at', '>=', Carbon::parse($request->input('since')));
      } catch (\Throwable $e) {
        // validation already handles invalid dates
      }
    }

    return response()->json([
      'records' => $query->get()->map(fn (tb_registerO3 $record) => $this->transformForSync($record)),
      'synced_at' => now()->toISOString(),
    ]);
  }

  public function uploadSync(Request $request)
  {
    $payload = $request->validate([
      'records' => ['array'],
      'records.*' => ['array'],
    ]);

    $results = [
      'synced' => [],
      'errors' => [],
    ];

    foreach (($payload['records'] ?? []) as $index => $row) {
      $localUuid = $row['_local_uuid'] ?? $row['local_uuid'] ?? null;
      $serverId = $row['server_id'] ?? $row['id'] ?? $row['Rid'] ?? null;

      try {
        $data = $this->normalizeSyncPayload($row, $request->session()->get('tb.clinic'));
        $record = null;

        if ($serverId) {
          $record = tb_registerO3::find($serverId);
        }

        if (!$record && !empty($data['Pid_TB03']) && !empty($data['TreDate_TB03'])) {
          $record = tb_registerO3::query()
            ->where('Pid_TB03', $data['Pid_TB03'])
            ->where('TreDate_TB03', $data['TreDate_TB03'])
            ->when(!empty($data['Clinic_code']), fn ($query) => $query->where('Clinic_code', $data['Clinic_code']))
            ->first();
        }

        if ($record) {
          $record->fill($data);
          $record->save();
        } else {
          $record = tb_registerO3::create($data);
        }

        $results['synced'][] = [
          'index' => $index,
          'local_uuid' => $localUuid,
          'server_id' => $record->id,
          'record' => $this->transformForSync($record->fresh()),
        ];
      } catch (\Throwable $e) {
        $results['errors'][] = [
          'index' => $index,
          'local_uuid' => $localUuid,
          'message' => $e->getMessage(),
        ];
      }
    }

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

  private function normalizeSyncPayload(array $row, ?string $sessionClinic): array
  {
    $mapping = [
      'Clinic_code' => 'Clinic Code',
      'Pid_TB03' => 'TB03_pid',
      'Name_TB03' => 'TB03_name',
      'FuchiaID_TB03' => 'TB03_fuchiaId',
      'TNumber_TB03' => 'TB03_id',
      'Age_TB03' => 'TB03_age',
      'Gender' => 'TB03_gender',
      'TreDate_TB03' => 'TB03_tremDate',
      'State_TB03' => 'TB03_state',
      'Township_TB03' => 'TB03_town',
      'Nationality_TB03' => 'TB03_nationality',
      'FaciName_TB03' => 'TB03_facility',
      'RePariod_TB03' => 'TB03_reportPeriod',
      'TranferIn_TB03' => 'TB03_transfer',
      'ReferFrom_TB03' => 'TB03_referFrom',
      'TypePatient_TB03' => 'TB03_typePatient',
      'TBsite_TB03' => 'TB03_site',
      'EPTBsite_TB03' => 'TB03_EPTB',
      'TreRegimens_TB03' => 'TB03_treRegimens',
      'Smoke_status_TB03' => 'TB03_smoke',
      'DMstatue_TB03' => 'TB03_dm',
      'Hivstatus_TB03' => 'TB03_hiv',
      'ART_start_TB03' => 'TB03_ART',
      'CPT_start_TB03' => 'TB03_CPT',
      'Microscope_Res_TB03' => 'TB03_microscope',
      'Xpert_Res_TB03' => 'TB03_Xpert',
      'XRay_Res_TB03' => 'TB03_Xray',
      'Calture_Res_TB03' => 'TB03_culture',
      'Counsellor_TB03' => 'TB03_counselor',
      'BioClinical_TB03' => 'TB03_bactlogical',
      '2ndMicroscope_Res_TB03' => 'TB03_2ndmicroscope',
      '2ndXpert_Res_TB03' => 'TB03_2ndXpert',
      '2ndCulture_Res_TB03' => 'TB03_culture_m2',
      '3rdMicroscope_Res_TB03' => 'TB03_3rdmicroscope',
      '3rdXpert_Res_TB03' => 'TB03_3rdXpert',
      '3rdCulture_Res_TB03' => 'TB03_culture_m3',
      '5rdMicroscope_Res_TB03' => 'TB03_5thmicroscope',
      '5rdXpert_Res_TB03' => 'TB03_5thXpert',
      '5rdCulture_Res_TB03' => 'TB03_culture_m5',
      'EndTX_Microscope_Res_TB03' => 'TB03_endmicroscope',
      'EndTX_XRay_Res_TB03' => 'TB03_endXray',
      'EndTX_Xpert_Res_TB03' => 'TB03_endXpert',
      '1stDst' => '1st_dst',
      'TrementOut_TB03' => 'TB03_outcome',
      'Intial_RegimenDate_TB03' => 'TB03_IRSD',
      'TrementOut_Date_TB03' => 'TB03_outDate',
      'EstimentOut_Date_TB03' => 'TB03_EoutDate',
      'Remark_TB03' => 'TB03_remark',
    ];

    $fillable = (new tb_registerO3())->getFillable();
    $data = Arr::only($row, $fillable);

    foreach ($mapping as $column => $input) {
      if (!array_key_exists($column, $data) && array_key_exists($input, $row)) {
        $data[$column] = $row[$input];
      }
    }

    if (empty($data['Clinic_code']) && $sessionClinic) {
      $data['Clinic_code'] = $sessionClinic;
    }

    if (($data['Gender'] ?? null) === 'Female') {
      $data['Gender'] = 'F';
    } elseif (($data['Gender'] ?? null) === 'Male') {
      $data['Gender'] = 'M';
    }

    foreach ([
      'TreDate_TB03',
      'ART_start_TB03',
      'CPT_start_TB03',
      'Intial_RegimenDate_TB03',
      'TrementOut_Date_TB03',
      'EstimentOut_Date_TB03',
    ] as $dateField) {
      if (!empty($data[$dateField])) {
        $time = strtotime((string) $data[$dateField]);
        $data[$dateField] = $time ? date('Y-m-d', $time) : null;
      } else {
        $data[$dateField] = null;
      }
    }

    return array_filter($data, fn ($value) => $value !== '');
  }

  private function transformForSync(tb_registerO3 $record): array
  {
    $payload = $record->toArray();
    $payload['server_id'] = $record->id;

    foreach ([
      'TreDate_TB03',
      'ART_start_TB03',
      'CPT_start_TB03',
      'Intial_RegimenDate_TB03',
      'TrementOut_Date_TB03',
      'EstimentOut_Date_TB03',
      'created_at',
      'updated_at',
    ] as $field) {
      if ($record->{$field}) {
        $payload[$field] = $record->{$field} instanceof \DateTimeInterface
          ? $record->{$field}->format(str_ends_with($field, '_at') ? 'c' : 'Y-m-d')
          : (string) $record->{$field};
      }
    }

    return $payload;
  }
}
