<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Models\FeedbackFileModel;
use App\Models\FeedbackModel;
use CodeIgniter\HTTP\ResponseInterface;

/**
 * 사용자 의견 접수. 로그인 사용자가 화면에서 남긴 의견 + 스크린샷을 저장한다.
 * (계정·지자체는 클라이언트 값을 믿지 않고 세션에서 채운다.)
 */
class Feedback extends BaseController
{
    public function store(): ResponseInterface
    {
        if (! session()->get('logged_in')) {
            return $this->response->setStatusCode(401)->setJSON(['ok' => false, 'message' => '로그인이 필요합니다.']);
        }

        $content = trim((string) $this->request->getPost('content'));
        if ($content === '') {
            return $this->response->setJSON(['ok' => false, 'message' => '의견 내용을 입력해 주세요.']);
        }
        if (mb_strlen($content) > 2000) {
            $content = mb_substr($content, 0, 2000);
        }

        helper('admin');
        $lgIdx = function_exists('admin_effective_lg_idx') ? admin_effective_lg_idx() : null;
        if (! $lgIdx) {
            $raw   = session()->get('mb_lg_idx');
            $lgIdx = ($raw !== null && $raw !== '') ? (int) $raw : null;
        }

        $model = model(FeedbackModel::class);
        $id    = $model->insert([
            'fb_lg_idx'     => $lgIdx,
            'fb_mb_idx'     => (int) session()->get('mb_idx'),
            'fb_mb_name'    => (string) (session()->get('mb_name') ?? ''),
            'fb_mb_level'   => (int) session()->get('mb_level'),
            'fb_content'    => $content,
            'fb_page_url'   => mb_substr((string) $this->request->getPost('page_url'), 0, 255),
            'fb_page_title' => mb_substr((string) $this->request->getPost('page_title'), 0, 255),
            'fb_user_agent' => mb_substr((string) $this->request->getHeaderLine('User-Agent'), 0, 255),
            'fb_status'     => 'new',
        ], true);

        if (! $id) {
            return $this->response->setJSON(['ok' => false, 'message' => '저장 중 오류가 발생했습니다.']);
        }

        $dir = WRITEPATH . 'uploads/feedback/';
        if (! is_dir($dir)) {
            @mkdir($dir, 0775, true);
        }
        $fileModel = model(FeedbackFileModel::class);

        // 1) 화면 캡처(dataURL) — 실패해도 의견 본문은 이미 저장됨
        $shot = (string) $this->request->getPost('screenshot');
        if ($shot !== '' && preg_match('#^data:image/(png|jpeg);base64,#', $shot, $m) === 1) {
            $ext = $m[1] === 'png' ? 'png' : 'jpg';
            $bin = base64_decode(substr($shot, strpos($shot, ',') + 1), true);
            if ($bin !== false && strlen($bin) <= 5 * 1024 * 1024) {
                $file = 'fb_' . (int) $id . '_cap_' . bin2hex(random_bytes(4)) . '.' . $ext;
                if (@file_put_contents($dir . $file, $bin) !== false) {
                    $model->update($id, ['fb_screenshot' => $file]); // 목록 캡처여부 표시용
                    $fileModel->insert(['ff_fb_idx' => $id, 'ff_kind' => 'capture', 'ff_path' => $file, 'ff_mime' => 'image/' . ($ext === 'png' ? 'png' : 'jpeg')]);
                }
            }
        }

        // 2) 사용자가 첨부한 이미지(여러 장)
        $allowed = ['image/png' => 'png', 'image/jpeg' => 'jpg', 'image/gif' => 'gif', 'image/webp' => 'webp'];
        $count   = 0;
        foreach ($this->request->getFileMultiple('files') ?? [] as $f) {
            if ($count >= 5 || $f === null || ! $f->isValid() || $f->hasMoved()) {
                continue;
            }
            $mime = (string) $f->getMimeType();
            if (! isset($allowed[$mime]) || $f->getSize() > 5 * 1024 * 1024) {
                continue;
            }
            $file = 'fb_' . (int) $id . '_up_' . bin2hex(random_bytes(4)) . '.' . $allowed[$mime];
            try {
                $f->move($dir, $file);
                $fileModel->insert(['ff_fb_idx' => $id, 'ff_kind' => 'upload', 'ff_path' => $file, 'ff_mime' => $mime]);
                $count++;
            } catch (\Throwable $e) {
                // 개별 파일 실패는 건너뜀
            }
        }

        return $this->response->setJSON(['ok' => true]);
    }
}
