<?php

namespace App\Services;

use App\Models\Tenants\ExpenseAccount;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

/**
 * 접대비 현황 서비스
 *
 * CEO 대시보드용 접대비 데이터를 제공합니다.
 */
class EntertainmentService extends Service
{
    // 접대비 기본 한도율 (중소기업 기준: 매출의 0.3%)
    private const DEFAULT_LIMIT_RATE = 0.003;

    // 기업 규모별 기본 한도 (연간)
    private const COMPANY_TYPE_LIMITS = [
        'large' => 36000000,   // 대기업: 연 3,600만원
        'medium' => 36000000,  // 중견기업: 연 3,600만원
        'small' => 24000000,   // 중소기업: 연 2,400만원
    ];

    /**
     * 접대비 현황 요약 조회
     *
     * @param  string|null  $limitType  기간 타입 (annual|quarterly, 기본: quarterly)
     * @param  string|null  $companyType  기업 유형 (large|medium|small, 기본: medium)
     * @param  int|null  $year  연도 (기본: 현재 연도)
     * @param  int|null  $quarter  분기 (1-4, 기본: 현재 분기)
     * @return array{cards: array, check_points: array}
     */
    public function getSummary(
        ?string $limitType = 'quarterly',
        ?string $companyType = 'medium',
        ?int $year = null,
        ?int $quarter = null
    ): array {
        $tenantId = $this->tenantId();
        $now = Carbon::now();

        // 기본값 설정
        $year = $year ?? $now->year;
        $limitType = $limitType ?? 'quarterly';
        $companyType = $companyType ?? 'medium';
        $quarter = $quarter ?? $now->quarter;

        // 기간 범위 계산
        if ($limitType === 'annual') {
            $startDate = Carbon::create($year, 1, 1)->format('Y-m-d');
            $endDate = Carbon::create($year, 12, 31)->format('Y-m-d');
            $periodLabel = "{$year}년";
        } else {
            $startDate = Carbon::create($year, ($quarter - 1) * 3 + 1, 1)->format('Y-m-d');
            $endDate = Carbon::create($year, $quarter * 3, 1)->endOfMonth()->format('Y-m-d');
            $periodLabel = "{$quarter}사분기";
        }

        // 연간 시작일 (매출 계산용)
        $yearStartDate = Carbon::create($year, 1, 1)->format('Y-m-d');
        $yearEndDate = Carbon::create($year, 12, 31)->format('Y-m-d');

        // 매출액 조회 (연간)
        $annualSales = $this->getAnnualSales($tenantId, $yearStartDate, $yearEndDate);

        // 접대비 한도 계산
        $annualLimit = $this->calculateLimit($annualSales, $companyType);
        $periodLimit = $limitType === 'annual' ? $annualLimit : ($annualLimit / 4);

        // 접대비 사용액 조회
        $usedAmount = $this->getUsedAmount($tenantId, $startDate, $endDate);

        // 잔여 한도
        $remainingLimit = max(0, $periodLimit - $usedAmount);

        // 카드 데이터 구성
        $cards = [
            [
                'id' => 'et_sales',
                'label' => '매출',
                'amount' => (int) $annualSales,
            ],
            [
                'id' => 'et_limit',
                'label' => "{{$periodLabel}} 접대비 총 한도",
                'amount' => (int) $periodLimit,
            ],
            [
                'id' => 'et_remaining',
                'label' => "{{$periodLabel}} 접대비 잔여한도",
                'amount' => (int) $remainingLimit,
            ],
            [
                'id' => 'et_used',
                'label' => "{{$periodLabel}} 접대비 사용금액",
                'amount' => (int) $usedAmount,
            ],
        ];

        // 체크포인트 생성
        $checkPoints = $this->generateCheckPoints(
            $periodLabel,
            $periodLimit,
            $usedAmount,
            $remainingLimit,
            $tenantId,
            $startDate,
            $endDate
        );

        return [
            'cards' => $cards,
            'check_points' => $checkPoints,
        ];
    }

    /**
     * 연간 매출액 조회
     */
    private function getAnnualSales(int $tenantId, string $startDate, string $endDate): float
    {
        // orders 테이블에서 확정된 수주 합계 조회
        $amount = DB::table('orders')
            ->where('tenant_id', $tenantId)
            ->where('status_code', 'confirmed')
            ->whereBetween('received_at', [$startDate, $endDate])
            ->whereNull('deleted_at')
            ->sum('total_amount');

        return $amount ?: 30530000000; // 임시 기본값 (305억)
    }

    /**
     * 접대비 한도 계산
     */
    private function calculateLimit(float $annualSales, string $companyType): float
    {
        // 기본 한도 (기업 규모별)
        $baseLimit = self::COMPANY_TYPE_LIMITS[$companyType] ?? self::COMPANY_TYPE_LIMITS['medium'];

        // 매출 기반 한도 (0.3%)
        $salesBasedLimit = $annualSales * self::DEFAULT_LIMIT_RATE;

        // 기본 한도 + 매출 기반 한도 (실제 세법은 더 복잡하지만 간소화)
        return $baseLimit + $salesBasedLimit;
    }

    /**
     * 접대비 사용액 조회
     */
    private function getUsedAmount(int $tenantId, string $startDate, string $endDate): float
    {
        // TODO: 실제 접대비 계정과목에서 조회
        // expense_accounts 또는 card_transactions에서 접대비 항목 합계
        $amount = DB::table('expense_accounts')
            ->where('tenant_id', $tenantId)
            ->where('account_type', 'entertainment')
            ->whereBetween('expense_date', [$startDate, $endDate])
            ->whereNull('deleted_at')
            ->sum('amount');

        return $amount ?: 10000000; // 임시 기본값
    }

    /**
     * 거래처 누락 건수 조회
     */
    private function getMissingVendorCount(int $tenantId, string $startDate, string $endDate): array
    {
        // TODO: 거래처 정보 누락 건수 조회
        $result = DB::table('expense_accounts')
            ->where('tenant_id', $tenantId)
            ->where('account_type', 'entertainment')
            ->whereBetween('expense_date', [$startDate, $endDate])
            ->whereNull('vendor_id')
            ->whereNull('deleted_at')
            ->selectRaw('COUNT(*) as count, COALESCE(SUM(amount), 0) as total')
            ->first();

        return [
            'count' => $result->count ?? 0,
            'total' => $result->total ?? 0,
        ];
    }

    /**
     * 체크포인트 생성
     */
    private function generateCheckPoints(
        string $periodLabel,
        float $limit,
        float $used,
        float $remaining,
        int $tenantId,
        string $startDate,
        string $endDate
    ): array {
        $checkPoints = [];
        $usageRate = $limit > 0 ? ($used / $limit) * 100 : 0;
        $usedFormatted = number_format($used / 10000);
        $limitFormatted = number_format($limit / 10000);
        $remainingFormatted = number_format($remaining / 10000);

        // 사용률에 따른 체크포인트
        if ($usageRate <= 75) {
            // 정상 운영
            $remainingRate = round(100 - $usageRate);
            $checkPoints[] = [
                'id' => 'et_cp_normal',
                'type' => 'success',
                'message' => "{$periodLabel} 접대비 사용 {$usedFormatted}만원 / 한도 {$limitFormatted}만원 ({$remainingRate}%). 여유 있게 운영 중입니다.",
                'highlights' => [
                    ['text' => "{$usedFormatted}만원", 'color' => 'green'],
                    ['text' => "{$limitFormatted}만원 ({$remainingRate}%)", 'color' => 'green'],
                ],
            ];
        } elseif ($usageRate <= 100) {
            // 주의 (85% 이상)
            $usageRateRounded = round($usageRate);
            $checkPoints[] = [
                'id' => 'et_cp_warning',
                'type' => 'warning',
                'message' => "접대비 한도 {$usageRateRounded}% 도달. 잔여 한도 {$remainingFormatted}만원입니다. 사용 계획을 점검해 주세요.",
                'highlights' => [
                    ['text' => "잔여 한도 {$remainingFormatted}만원", 'color' => 'orange'],
                ],
            ];
        } else {
            // 한도 초과
            $overAmount = $used - $limit;
            $overFormatted = number_format($overAmount / 10000);
            $checkPoints[] = [
                'id' => 'et_cp_over',
                'type' => 'error',
                'message' => "접대비 한도 초과 {$overFormatted}만원 발생. 초과분은 손금불산입되어 법인세 부담이 증가합니다.",
                'highlights' => [
                    ['text' => "{$overFormatted}만원 발생", 'color' => 'red'],
                ],
            ];
        }

        // 거래처 정보 누락 체크
        $missingVendor = $this->getMissingVendorCount($tenantId, $startDate, $endDate);
        if ($missingVendor['count'] > 0) {
            $missingTotal = number_format($missingVendor['total'] / 10000);
            $checkPoints[] = [
                'id' => 'et_cp_missing',
                'type' => 'error',
                'message' => "접대비 사용 중 {$missingVendor['count']}건({$missingTotal}만원)의 거래처 정보가 누락되었습니다. 기록을 보완해 주세요.",
                'highlights' => [
                    ['text' => "{$missingVendor['count']}건({$missingTotal}만원)", 'color' => 'red'],
                    ['text' => '거래처 정보가 누락', 'color' => 'red'],
                ],
            ];
        }

        return $checkPoints;
    }
}