<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use App\Models\webfax\FaxModel;
use App\Libraries\Qrcode;
use CodeIgniter\CLI\CLI;
use CodeIgniter\Exceptions\PageNotFoundException;

class Crontab extends BaseController
{
  /**
   * Fax 수신 이미지(tiff)를 jpg로 변경하고 Thumbnail을 만드는 작업...
   * (CLI 전용)
   */
  public function convertedFaxImages()
  {
    // ✅ CLI 전용 보호
    if (!is_cli()) {
      throw new PageNotFoundException();
    }

    /** @var FaxModel $faxModel */
    $faxModel = model(FaxModel::class);
    $qrCode = new Qrcode();

    $res = $faxModel->selectFaxListNotExistsThumb();
    $fileCnt = 0;
    $receiver = 'uds_tiff';

    if (empty($res)) {
      CLI::write('No target fax images.', 'yellow');
      return;
    }

    foreach ($res as $row) {
      $fileCnt++;
      CLI::write("\n\n[{$fileCnt}] Processing...", 'green');

      $mid = $row['mid'] ?? null;
      $file_name = $row['file_name'] ?? '';
      $save_path = $row['save_path'] ?? '';
      $caller_no = $row['caller_no'] ?? '';
      $callee_no = $row['callee_no'] ?? '';
      $tiff_file_name = $row['file_name'] ?? '';
      $tiff_file_size = $row['file_size'] ?? '';
      $recv_time = $row['recv_time'] ?? '';
      $save_time = $row['save_time'] ?? '';

      if (empty($save_path) || empty($file_name)) {
        CLI::write(' - skip: save_path or file_name empty', 'yellow');
        continue;
      }

      // ✅ pathinfo로 안전하게 처리
      $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
      $base = pathinfo($file_name, PATHINFO_FILENAME);

      if (!in_array($ext, ['tif', 'tiff'], true)) {
        CLI::write(" - skip: not tif/tiff ({$ext})", 'yellow');
        continue;
      }

      if (substr($save_path, -1) !== '/') {
        $save_path .= '/';
      }

      $tiffPath = $save_path . $file_name;
      if (!is_file($tiffPath)) {
        CLI::write(" - skip: file not found ({$tiffPath})", 'yellow');
        continue;
      }

      CLI::write(" - TIFF: {$tiffPath}");

      try {
        // ✅ TIFF 다중 페이지 안전 처리
        $im = new \Imagick();
        $im->readImage($tiffPath);

        // coalesce: 멀티프레임 안정화(특히 tiff/gif 계열)
        $frames = $im->coalesceImages();

        $index = 0;
        foreach ($frames as $frame) {
          try {
            // 페이지별 정보
            $image_width = (int) $frame->getImageWidth();
            $image_height = (int) $frame->getImageHeight();
            $image_size = (int) $frame->getImageLength();

            // 출력 경로
            $jpgName = "{$base}_{$index}.jpg";
            $jpgPath = $save_path . $jpgName;
            $thumbName = "{$base}_{$index}_thumb.jpg";
            $thumbPath = $save_path . $thumbName;

            // ✅ JPG로 변환(페이지별로 frame clone 사용 권장)
            $page = clone $frame;

            // 이미지 포맷/품질(필요시 조정)
            $page->setImageFormat('jpeg');
            $page->setImageCompression(\Imagick::COMPRESSION_JPEG);
            $page->setImageCompressionQuality(85);

            // ✅ 리사이즈 (가로 800 제한)
            if ($image_width > 800) {
              $resize_width = 800;
              $ratio = $resize_width / max(1, $image_width);
              $resize_height = (int) round($image_height * $ratio);
              $page->resizeImage($resize_width, $resize_height, \Imagick::FILTER_LANCZOS, 1, true);
            }

            if (!$page->writeImage($jpgPath)) {
              CLI::write("   - fail: write jpg ({$jpgPath})", 'red');
              $page->clear();
              $page->destroy();
              $index++;
              continue;
            }

            // ✅ QR scan (실패해도 계속)
            $qrcode_data = '';
            try {
              $qrcode_data = (string) $qrCode->scan($jpgPath);
            } catch (\Throwable $e) {
              log_message('error', 'QR scan failed: ' . $e->getMessage());
            }

            // ✅ 썸네일은 clone으로 (원본/페이지 훼손 방지)
            $thumb = clone $page;
            $thumb->thumbnailImage(105, 80, true);

            if (!$thumb->writeImage($thumbPath)) {
              CLI::write("   - fail: write thumb ({$thumbPath})", 'red');
              // 그래도 JPG는 만들어졌으니 다음 진행은 정책에 따라 선택
            }

            CLI::write("   - JPG:   {$jpgPath}");
            CLI::write("   - THUMB: {$thumbPath}");

            // ✅ DB 저장 (기존 시그니처 유지)
            $faxModel->insertFaxImgs(
              $mid,
              $jpgName,
              $save_path,
              $thumbName,
              $image_width,
              $image_height,
              $image_size,
              $qrcode_data,
              $caller_no,
              $callee_no,
              $tiff_file_name,
              $tiffPath,
              $tiff_file_size,
              $recv_time,
              $save_time,
              $receiver
            );

            // ✅ 권한 처리 (에러 숨기지 말고 로그)
            if (!@chmod($jpgPath, 0666)) {
              log_message('error', "chmod failed: {$jpgPath}");
            }
            if (!@chmod($thumbPath, 0666)) {
              log_message('error', "chmod failed: {$thumbPath}");
            }

            log_message('debug', $jpgPath);
            log_message('debug', $thumbPath);

            // ✅ 메모리 정리(프레임 단위)
            $thumb->clear();
            $thumb->destroy();
            $page->clear();
            $page->destroy();
          } catch (\Throwable $e) {
            log_message('error', 'Frame 처리 실패: ' . $e->getMessage());
          }

          // 다음 페이지
          $index++;
        }

        // ✅ 전체 메모리 정리
        $frames->clear();
        $frames->destroy();

        $im->clear();
        $im->destroy();

        gc_collect_cycles();

        CLI::write(" - done.\n", 'green');
      } catch (\Throwable $e) {
        // 기존 writeLog 사용 중이면 그걸로 교체 가능
        log_message('error', 'TIFF 처리 실패: ' . $e->getMessage());
        CLI::write(" - error: " . $e->getMessage(), 'red');
      }
    }
  }
}
