<?php

namespace App\Http\Controllers\Credit;

use App\Http\Controllers\Controller;
use App\Models\Credit\CreditInquiry;
use App\Models\Tenants\Tenant;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

/**
 * 신용평가 조회회수 집계 컨트롤러
 */
class CreditUsageController extends Controller
{
    // 과금 정책: 월 기본 무료 제공 건수
    const FREE_MONTHLY_QUOTA = 5;

    // 과금 정책: 추가 건당 요금 (원)
    const ADDITIONAL_FEE_PER_INQUIRY = 2000;

    /**
     * 조회회수 집계 페이지
     */
    public function index(Request $request): View|Response
    {
        if ($request->header('HX-Request')) {
            return response('', 200)->header('HX-Redirect', route('credit.usage.index'));
        }

        $user = auth()->user();
        $selectedTenantId = session('selected_tenant_id');
        $isHQ = $selectedTenantId == 1; // 본사(코드브릿지엑스)

        // 기간 필터 (기본값: 현재 월)
        $year = $request->input('year', date('Y'));
        $month = $request->input('month', date('m'));
        $viewType = $request->input('view_type', 'monthly'); // monthly, yearly, custom

        // 기간 설정
        if ($viewType === 'yearly') {
            $startDate = "{$year}-01-01 00:00:00";
            $endDate = "{$year}-12-31 23:59:59";
        } elseif ($viewType === 'custom') {
            $startDate = $request->input('start_date', date('Y-m-01')).' 00:00:00';
            $endDate = $request->input('end_date', date('Y-m-t')).' 23:59:59';
        } else {
            $startDate = "{$year}-{$month}-01 00:00:00";
            $endDate = date('Y-m-t 23:59:59', strtotime($startDate));
        }

        // 본사는 전체 테넌트 조회, 일반 테넌트는 자기 것만
        if ($isHQ) {
            $usageData = $this->getAllTenantsUsage($startDate, $endDate, $viewType, $year);
            $tenants = Tenant::whereNull('deleted_at')
                ->orderBy('company_name')
                ->get(['id', 'company_name', 'code']);
        } else {
            $usageData = $this->getSingleTenantUsage($selectedTenantId, $startDate, $endDate, $viewType, $year);
            $tenants = collect();
        }

        // 선택된 테넌트 필터
        $filterTenantId = $request->input('tenant_id');
        if ($isHQ && $filterTenantId) {
            $usageData['details'] = collect($usageData['details'])->filter(function ($item) use ($filterTenantId) {
                return $item['tenant_id'] == $filterTenantId;
            })->values()->all();
        }

        return view('credit.usage.index', [
            'isHQ' => $isHQ,
            'usageData' => $usageData,
            'tenants' => $tenants,
            'filters' => [
                'year' => $year,
                'month' => $month,
                'view_type' => $viewType,
                'start_date' => substr($startDate, 0, 10),
                'end_date' => substr($endDate, 0, 10),
                'tenant_id' => $filterTenantId,
            ],
            'policy' => [
                'free_quota' => self::FREE_MONTHLY_QUOTA,
                'additional_fee' => self::ADDITIONAL_FEE_PER_INQUIRY,
            ],
        ]);
    }

    /**
     * 전체 테넌트 사용량 조회 (본사용)
     */
    private function getAllTenantsUsage(string $startDate, string $endDate, string $viewType, string $year): array
    {
        // 테넌트별 조회 건수
        $query = CreditInquiry::select(
            'tenant_id',
            DB::raw('COUNT(*) as total_count'),
            DB::raw('DATE_FORMAT(inquired_at, "%Y-%m") as month')
        )
            ->whereBetween('inquired_at', [$startDate, $endDate])
            ->whereNotNull('tenant_id')
            ->groupBy('tenant_id', DB::raw('DATE_FORMAT(inquired_at, "%Y-%m")'));

        $rawData = $query->get();

        // 테넌트 정보 조회
        $tenantIds = $rawData->pluck('tenant_id')->unique();
        $tenants = Tenant::whereIn('id', $tenantIds)->get()->keyBy('id');

        // 월별로 그룹화하여 계산
        $monthlyData = [];
        foreach ($rawData as $row) {
            $tenantId = $row->tenant_id;
            $month = $row->month;

            if (! isset($monthlyData[$tenantId])) {
                $monthlyData[$tenantId] = [];
            }
            $monthlyData[$tenantId][$month] = $row->total_count;
        }

        // 결과 데이터 생성
        $details = [];
        $totalCount = 0;
        $totalFee = 0;

        foreach ($monthlyData as $tenantId => $months) {
            $tenant = $tenants->get($tenantId);
            $tenantTotalCount = 0;
            $tenantTotalFee = 0;

            foreach ($months as $month => $count) {
                $fee = $this->calculateFee($count);
                $tenantTotalCount += $count;
                $tenantTotalFee += $fee;

                if ($viewType === 'yearly') {
                    // 연간 조회 시 월별 상세 표시
                    $details[] = [
                        'tenant_id' => $tenantId,
                        'tenant_name' => $tenant?->company_name ?? '(삭제됨)',
                        'tenant_code' => $tenant?->code ?? '-',
                        'month' => $month,
                        'count' => $count,
                        'free_count' => min($count, self::FREE_MONTHLY_QUOTA),
                        'paid_count' => max(0, $count - self::FREE_MONTHLY_QUOTA),
                        'fee' => $fee,
                    ];
                }
            }

            if ($viewType !== 'yearly') {
                // 월간/기간 조회 시 테넌트별 합계만
                $totalMonthCount = array_sum($months);
                $fee = $this->calculateFee($totalMonthCount);

                $details[] = [
                    'tenant_id' => $tenantId,
                    'tenant_name' => $tenant?->company_name ?? '(삭제됨)',
                    'tenant_code' => $tenant?->code ?? '-',
                    'count' => $totalMonthCount,
                    'free_count' => min($totalMonthCount, self::FREE_MONTHLY_QUOTA),
                    'paid_count' => max(0, $totalMonthCount - self::FREE_MONTHLY_QUOTA),
                    'fee' => $fee,
                ];
            }

            $totalCount += $tenantTotalCount;
            $totalFee += $tenantTotalFee;
        }

        // 정렬: 조회 건수 내림차순
        usort($details, fn ($a, $b) => $b['count'] - $a['count']);

        return [
            'total_count' => $totalCount,
            'total_fee' => $totalFee,
            'details' => $details,
        ];
    }

    /**
     * 단일 테넌트 사용량 조회
     */
    private function getSingleTenantUsage(int $tenantId, string $startDate, string $endDate, string $viewType, string $year): array
    {
        $tenant = Tenant::find($tenantId);

        // 월별 조회 건수
        $query = CreditInquiry::select(
            DB::raw('COUNT(*) as total_count'),
            DB::raw('DATE_FORMAT(inquired_at, "%Y-%m") as month')
        )
            ->where('tenant_id', $tenantId)
            ->whereBetween('inquired_at', [$startDate, $endDate])
            ->groupBy(DB::raw('DATE_FORMAT(inquired_at, "%Y-%m")'))
            ->orderBy('month');

        $rawData = $query->get();

        $details = [];
        $totalCount = 0;
        $totalFee = 0;

        foreach ($rawData as $row) {
            $count = $row->total_count;
            $fee = $this->calculateFee($count);

            $details[] = [
                'tenant_id' => $tenantId,
                'tenant_name' => $tenant?->company_name ?? '(삭제됨)',
                'month' => $row->month,
                'count' => $count,
                'free_count' => min($count, self::FREE_MONTHLY_QUOTA),
                'paid_count' => max(0, $count - self::FREE_MONTHLY_QUOTA),
                'fee' => $fee,
            ];

            $totalCount += $count;
            $totalFee += $fee;
        }

        // 연간 조회 시 없는 월도 표시
        if ($viewType === 'yearly') {
            $existingMonths = collect($details)->pluck('month')->toArray();
            for ($m = 1; $m <= 12; $m++) {
                $monthKey = sprintf('%s-%02d', $year, $m);
                if (! in_array($monthKey, $existingMonths)) {
                    $details[] = [
                        'tenant_id' => $tenantId,
                        'tenant_name' => $tenant?->company_name ?? '(삭제됨)',
                        'month' => $monthKey,
                        'count' => 0,
                        'free_count' => 0,
                        'paid_count' => 0,
                        'fee' => 0,
                    ];
                }
            }
            // 월 순서로 정렬
            usort($details, fn ($a, $b) => strcmp($a['month'], $b['month']));
        }

        return [
            'total_count' => $totalCount,
            'total_fee' => $totalFee,
            'details' => $details,
        ];
    }

    /**
     * 요금 계산
     */
    private function calculateFee(int $count): int
    {
        $paidCount = max(0, $count - self::FREE_MONTHLY_QUOTA);

        return $paidCount * self::ADDITIONAL_FEE_PER_INQUIRY;
    }
}
