<?php

namespace App\Http\Controllers\Admin\Members;

use App\Services\Admin\Member\AdminMemberMarketingService;
use Illuminate\Http\Request;
use App\Services\Admin\AdminAuditService;


final class AdminMemberMarketingController
{
    public function __construct(
        private readonly AdminMemberMarketingService $service,
        private readonly AdminAuditService $audit,
    ) {}

    public function index(Request $request)
    {
        $data = $this->service->index($request->all());
        return view('admin.members.marketing', $data);
    }

    public function export(Request $request)
    {
        $data = $request->validate([
            'zip_password' => ['required', 'string', 'min:4', 'max:64'],

            // filters
            'qf' => ['nullable','string','in:all,mem_no,name,email,phone'],
            'q'  => ['nullable','string','max:100'],

            'stat_3' => ['nullable','string','in:1,2,3,4,5,6'],

            'reg_from' => ['nullable','date'],
            'reg_to'   => ['nullable','date'],

            'no_login' => ['nullable','string','in:0,1'],
            'inactive_days_gte' => ['nullable','integer','min:0','max:36500'],

            'has_purchase' => ['nullable','string','in:all,1,0'],
            'recent_purchase' => ['nullable','string','in:all,30,90'],
            'min_purchase_count' => ['nullable','integer','min:0','max:999999'],
            'min_purchase_amount' => ['nullable','integer','min:0','max:999999999999'],

            // 추가 옵션(접기 영역)
            'optin_sms' => ['nullable','string','in:all,1,0'],
            'optin_email' => ['nullable','string','in:all,1,0'],
            'has_phone' => ['nullable','string','in:all,1,0'],
            'has_email' => ['nullable','string','in:all,1,0'],
        ]);

        $actorAdminId = (int) auth('admin')->id();
        $ip = (string) $request->ip();
        $ua = (string) $request->userAgent();

        $zipPassword = (string) $data['zip_password'];
        unset($data['zip_password']);

        // 감사로그용 필터 스냅샷(민감정보 제외: zip_password는 이미 제거됨)
        $auditFilters = $data;

        // q 마스킹(전화/이메일 검색인 경우만)
        $qf = (string)($auditFilters['qf'] ?? 'all');
        $q  = (string)($auditFilters['q']  ?? '');
        if ($q !== '') {
            if ($qf === 'phone') {
                $digits = preg_replace('/\D+/', '', $q);
                $auditFilters['q'] = $digits !== '' ? (substr($digits, 0, 3) . '****' . substr($digits, -2)) : '***';
            } elseif ($qf === 'email' && str_contains($q, '@')) {
                [$local, $domain] = explode('@', $q, 2);
                $auditFilters['q'] = (mb_substr($local, 0, 2) . '***@' . $domain);
            }
        }

        $res = $this->service->exportZip($data, $zipPassword);

        if (!($res['ok'] ?? false)) {
            // ✅ 실패도 기록(원인 추적용) — 비밀번호는 기록하지 않음
            $this->audit->log(
                actorAdminId: $actorAdminId,
                action: 'admin.member.export.fail',
                targetType: 'member',
                targetId: 0,
                before: ['filters' => $auditFilters],
                after: [
                    'ok' => false,
                    'message' => $res['message'] ?? '파일 생성 실패',
                ],
                ip: $ip,
                ua: $ua,
            );

            return redirect()->back()->with('toast', [
                'type' => 'danger',
                'title' => '다운로드 실패',
                'message' => $res['message'] ?? '파일 생성에 실패했습니다.',
            ]);
        }

        $zipPath = (string)($res['zip_path'] ?? '');
        $downloadName = (string)($res['download_name'] ?? 'members.zip');

        // ✅ 성공 기록
        $bytes = (is_string($zipPath) && $zipPath !== '' && file_exists($zipPath)) ? @filesize($zipPath) : null;

        $this->audit->log(
            actorAdminId: $actorAdminId,
            action: 'admin.member.export',
            targetType: 'member',
            targetId: 0,
            before: ['filters' => $auditFilters],
            after: [
                'ok' => true,
                'download_name' => $downloadName,
                'bytes' => $bytes,
                // exportZip에서 제공 가능하면 같이 남겨두면 좋아
                'row_count' => $res['row_count'] ?? null,
            ],
            ip: $ip,
            ua: $ua,
        );

        return response()
            ->download($zipPath, $downloadName)
            ->deleteFileAfterSend(true);
    }

}
