<?php

namespace App\Http\Controllers\Finance;

use App\Http\Controllers\Controller;
use App\Models\Sales\SalesCommission;
use App\Models\Sales\SalesPartner;
use App\Models\Sales\SalesTenantManagement;
use App\Services\SalesCommissionService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;

/**
 * 영업수수료 정산 컨트롤러
 */
class SalesCommissionController extends Controller
{
    public function __construct(
        private SalesCommissionService $service
    ) {}

    /**
     * 정산 목록
     */
    public function index(Request $request): View|Response
    {
        // HTMX 요청 시 전체 페이지로 리다이렉트 (JavaScript 필요)
        if ($request->header('HX-Request') && ! $request->header('HX-Boosted')) {
            return response('', 200)->header('HX-Redirect', route('finance.sales-commissions.index'));
        }

        // 필터 파라미터
        $year = $request->input('year', now()->year);
        $month = $request->input('month', now()->month);

        $filters = [
            'scheduled_year' => $year,
            'scheduled_month' => $month,
            'status' => $request->input('status'),
            'payment_type' => $request->input('payment_type'),
            'partner_id' => $request->input('partner_id'),
            'search' => $request->input('search'),
        ];

        // 정산 목록
        $commissions = $this->service->getCommissions($filters);

        // 통계
        $stats = $this->service->getSettlementStats($year, $month);

        // 영업파트너 목록 (필터용)
        $partners = SalesPartner::with('user')
            ->active()
            ->orderBy('partner_code')
            ->get();

        // 입금 대기 테넌트 목록
        $pendingTenants = $this->service->getPendingPaymentTenants();

        return view('finance.sales-commission.index', compact(
            'commissions',
            'stats',
            'partners',
            'pendingTenants',
            'year',
            'month',
            'filters'
        ));
    }

    /**
     * 정산 상세 조회
     */
    public function show(int $id): JsonResponse
    {
        $commission = $this->service->getCommissionById($id);

        if (! $commission) {
            return response()->json([
                'success' => false,
                'message' => '정산 정보를 찾을 수 없습니다.',
            ], 404);
        }

        return response()->json([
            'success' => true,
            'data' => $commission,
        ]);
    }

    /**
     * 정산 상세 모달 (HTMX)
     */
    public function detail(int $id): View
    {
        $commission = $this->service->getCommissionById($id);

        return view('finance.sales-commission.partials.detail-modal', compact('commission'));
    }

    /**
     * 입금 등록 (수당 생성)
     */
    public function registerPayment(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'management_id' => 'required|integer|exists:sales_tenant_managements,id',
            'payment_type' => 'required|in:deposit,balance',
            'payment_amount' => 'required|numeric|min:0',
            'payment_date' => 'required|date',
        ]);

        try {
            $commission = $this->service->createCommission(
                $validated['management_id'],
                $validated['payment_type'],
                $validated['payment_amount'],
                $validated['payment_date']
            );

            return response()->json([
                'success' => true,
                'message' => '입금이 등록되었습니다.',
                'data' => $commission,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 승인 처리
     */
    public function approve(int $id): JsonResponse
    {
        try {
            $commission = $this->service->approve($id, auth()->id());

            return response()->json([
                'success' => true,
                'message' => '승인되었습니다.',
                'data' => $commission,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 일괄 승인
     */
    public function bulkApprove(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'ids' => 'required|array|min:1',
            'ids.*' => 'integer|exists:sales_commissions,id',
        ]);

        try {
            $count = $this->service->bulkApprove($validated['ids'], auth()->id());

            return response()->json([
                'success' => true,
                'message' => "{$count}건이 승인되었습니다.",
                'count' => $count,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 지급완료 처리
     */
    public function markPaid(int $id, Request $request): JsonResponse
    {
        $validated = $request->validate([
            'bank_reference' => 'nullable|string|max:100',
        ]);

        try {
            $commission = $this->service->markAsPaid($id, $validated['bank_reference'] ?? null);

            return response()->json([
                'success' => true,
                'message' => '지급완료 처리되었습니다.',
                'data' => $commission,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 일괄 지급완료
     */
    public function bulkMarkPaid(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'ids' => 'required|array|min:1',
            'ids.*' => 'integer|exists:sales_commissions,id',
            'bank_reference' => 'nullable|string|max:100',
        ]);

        try {
            $count = $this->service->bulkMarkAsPaid($validated['ids'], $validated['bank_reference'] ?? null);

            return response()->json([
                'success' => true,
                'message' => "{$count}건이 지급완료 처리되었습니다.",
                'count' => $count,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 승인취소 처리
     */
    public function unapprove(int $id): JsonResponse
    {
        try {
            $commission = $this->service->unapprove($id);

            return response()->json([
                'success' => true,
                'message' => '승인이 취소되었습니다.',
                'data' => $commission,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 취소 처리
     */
    public function cancel(int $id): JsonResponse
    {
        try {
            $commission = $this->service->cancel($id);

            return response()->json([
                'success' => true,
                'message' => '취소되었습니다.',
                'data' => $commission,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 수당지급일/협업지원금 인라인 수정
     */
    public function updateCommissionDate(int $id, Request $request): JsonResponse
    {
        $validated = $request->validate([
            'field' => 'required|in:first_partner_paid_at,second_partner_paid_at,manager_paid_at,referrer_commission',
            'value' => 'nullable',
        ]);

        $commission = SalesCommission::findOrFail($id);

        // 수당지급일은 인계 상태일 때만 변경 가능
        $paidFields = ['first_partner_paid_at', 'second_partner_paid_at', 'manager_paid_at'];
        if (in_array($validated['field'], $paidFields) && $commission->management?->hq_status !== 'handover') {
            return response()->json(['success' => false, 'message' => '인계 상태일 때만 수당지급일 설정 가능'], 422);
        }

        $value = $validated['value'];
        if ($validated['field'] === 'referrer_commission') {
            $value = (int) ($value ?: 0);
        } else {
            $value = $value ?: null;
        }

        $commission->update([$validated['field'] => $value]);

        return response()->json(['success' => true]);
    }

    /**
     * 정산 테이블 부분 새로고침 (HTMX)
     */
    public function table(Request $request): View
    {
        $year = $request->input('year', now()->year);
        $month = $request->input('month', now()->month);

        $filters = [
            'scheduled_year' => $year,
            'scheduled_month' => $month,
            'status' => $request->input('status'),
            'payment_type' => $request->input('payment_type'),
            'partner_id' => $request->input('partner_id'),
            'search' => $request->input('search'),
        ];

        $commissions = $this->service->getCommissions($filters);

        return view('finance.sales-commission.partials.commission-table', compact('commissions'));
    }

    /**
     * 통계 카드 부분 새로고침 (HTMX)
     */
    public function stats(Request $request): View
    {
        $year = $request->input('year', now()->year);
        $month = $request->input('month', now()->month);

        $stats = $this->service->getSettlementStats($year, $month);

        return view('finance.sales-commission.partials.stats-cards', compact('stats', 'year', 'month'));
    }

    /**
     * 입금 등록 폼 (HTMX 모달)
     */
    public function paymentForm(Request $request): View
    {
        $managementId = $request->input('management_id');
        $management = null;

        if ($managementId) {
            $management = SalesTenantManagement::with(['tenant', 'salesPartner.user', 'contractProducts.product'])
                ->find($managementId);
        }

        // 입금 대기 테넌트 목록
        $pendingTenants = $this->service->getPendingPaymentTenants();

        return view('finance.sales-commission.partials.payment-form', compact('management', 'pendingTenants'));
    }

    /**
     * 엑셀 다운로드
     */
    public function export(Request $request)
    {
        $year = $request->input('year', now()->year);
        $month = $request->input('month', now()->month);

        $filters = [
            'scheduled_year' => $year,
            'scheduled_month' => $month,
            'status' => $request->input('status'),
            'payment_type' => $request->input('payment_type'),
            'partner_id' => $request->input('partner_id'),
        ];

        // 전체 데이터 조회 (페이지네이션 없이)
        $commissions = SalesCommission::query()
            ->with(['tenant', 'partner.user', 'manager'])
            ->when(! empty($filters['status']), fn ($q) => $q->where('status', $filters['status']))
            ->when(! empty($filters['payment_type']), fn ($q) => $q->where('payment_type', $filters['payment_type']))
            ->when(! empty($filters['partner_id']), fn ($q) => $q->where('partner_id', $filters['partner_id']))
            ->forScheduledMonth($year, $month)
            ->orderBy('scheduled_payment_date')
            ->get();

        // CSV 생성
        $filename = "sales_commission_{$year}_{$month}.csv";

        $headers = [
            'Content-Type' => 'text/csv; charset=UTF-8',
            'Content-Disposition' => "attachment; filename=\"{$filename}\"",
        ];

        $callback = function () use ($commissions) {
            $file = fopen('php://output', 'w');

            // BOM for UTF-8
            fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));

            // 헤더
            fputcsv($file, [
                '번호', '테넌트', '입금구분', '입금액', '입금일',
                '기준액', '영업파트너', '파트너수당', '매니저', '매니저수당',
                '지급예정일', '상태', '실제지급일',
            ]);

            // 데이터
            foreach ($commissions as $commission) {
                fputcsv($file, [
                    $commission->id,
                    $commission->tenant->name ?? $commission->tenant->company_name,
                    $commission->payment_type_label,
                    number_format($commission->payment_amount),
                    $commission->payment_date->format('Y-m-d'),
                    number_format($commission->base_amount),
                    $commission->partner?->user?->name ?? '-',
                    number_format($commission->partner_commission),
                    $commission->manager?->name ?? '-',
                    number_format($commission->manager_commission),
                    $commission->scheduled_payment_date->format('Y-m-d'),
                    $commission->status_label,
                    $commission->actual_payment_date?->format('Y-m-d') ?? '-',
                ]);
            }

            fclose($file);
        };

        return response()->stream($callback, 200, $headers);
    }
}
