<?php

namespace App\Http\Controllers\Sales;

use App\Http\Controllers\Controller;
use App\Models\Sales\SalesManagerDocument;
use App\Models\Sales\SalesPartner;
use App\Models\User;
use App\Services\Sales\SalesManagerService;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;

/**
 * 영업파트너 관리 컨트롤러
 */
class SalesManagerController extends Controller
{
    public function __construct(
        private SalesManagerService $service
    ) {}

    /**
     * 목록 페이지
     */
    public function index(Request $request): View|Response
    {
        if ($request->header('HX-Request')) {
            return response('', 200)->header('HX-Redirect', route('sales.managers.index'));
        }

        $filters = [
            'search' => $request->get('search'),
            'role' => $request->get('role'),
            'approval_status' => $request->get('approval_status'),
            'parent_id' => auth()->id(),  // 현재 로그인한 사용자가 유치한 파트너만 조회
        ];

        $partners = $this->service->getSalesPartners($filters)->paginate(20);
        $stats = $this->service->getStats(auth()->id());  // 통계도 현재 사용자 기준

        return view('sales.managers.index', compact('partners', 'stats'));
    }

    /**
     * 등록 폼
     */
    public function create(): View
    {
        if (auth()->user()->isGroupPartner()) {
            abort(403, '단체 파트너는 하위 파트너를 등록할 수 없습니다.');
        }

        // 영업 역할 목록
        $roles = $this->service->getSalesRoles();

        // 문서 타입 목록
        $documentTypes = SalesManagerDocument::DOCUMENT_TYPES;

        return view('sales.managers.create', compact('roles', 'documentTypes'));
    }

    /**
     * 등록 처리
     */
    public function store(Request $request)
    {
        if (auth()->user()->isGroupPartner()) {
            abort(403, '단체 파트너는 하위 파트너를 등록할 수 없습니다.');
        }

        $validated = $request->validate([
            'user_id' => 'nullable|string|max:50|unique:users,user_id',
            'name' => 'required|string|max:100',
            'email' => 'required|email|max:255|unique:users,email',
            'phone' => 'nullable|string|max:20',
            'password' => 'required|string|min:4|confirmed',
            'role_ids' => 'required|array|min:1',
            'role_ids.*' => 'exists:roles,id',
            'company_name' => 'nullable|string|max:100',
            'biz_no' => 'nullable|string|max:20',
            'address' => 'nullable|string|max:255',
            'partner_type' => 'nullable|in:individual,corporate',
            'documents' => 'nullable|array',
            'documents.*.file' => 'nullable|file|max:10240',
            'documents.*.document_type' => 'nullable|string',
            'documents.*.description' => 'nullable|string|max:500',
        ]);

        // 등록자를 추천인(parent)으로 자동 설정
        // 본사 관리자가 등록해도 해당 관리자가 추천인이 됨
        $validated['parent_id'] = auth()->id();

        // 단체(corporate) 등록 시: 등록자를 유치 파트너로 자동 지정
        if (($validated['partner_type'] ?? '') === 'corporate') {
            $myPartner = SalesPartner::where('user_id', auth()->id())->first();
            $validated['referrer_partner_id'] = $myPartner?->id;
        }

        // 문서 배열 구성
        $documents = [];
        if ($request->hasFile('documents')) {
            foreach ($request->file('documents') as $index => $file) {
                $documents[] = [
                    'file' => $file,
                    'document_type' => $request->input("documents.{$index}.document_type", 'other'),
                    'description' => $request->input("documents.{$index}.description"),
                ];
            }
        }

        $this->service->createSalesPartner($validated, $documents);

        return redirect()->route('sales.managers.index')
            ->with('success', '영업파트너 등록 신청이 완료되었습니다. 본사 승인 후 활성화됩니다.');
    }

    /**
     * 상세 페이지
     */
    public function show(int $id): View
    {
        $partner = User::with(['parent', 'children', 'userRoles.role', 'salesDocuments', 'approver'])
            ->findOrFail($id);

        // 계층 레벨
        $level = $this->service->getPartnerLevel($partner);

        // 하위 파트너
        $children = User::where('parent_id', $partner->id)
            ->with('userRoles.role')
            ->get();

        // 역할 위임 가능한 하위 파트너
        $delegationCandidates = $this->service->getDelegationCandidates($partner);

        return view('sales.managers.show', compact('partner', 'level', 'children', 'delegationCandidates'));
    }

    /**
     * 상세 모달용
     */
    public function modalShow(int $id): View
    {
        $partner = User::with(['parent', 'children', 'userRoles.role', 'salesDocuments', 'approver'])
            ->findOrFail($id);

        $level = $this->service->getPartnerLevel($partner);

        $children = User::where('parent_id', $partner->id)
            ->with('userRoles.role')
            ->get();

        return view('sales.managers.partials.show-modal', compact('partner', 'level', 'children'));
    }

    /**
     * 수정 모달용
     */
    public function modalEdit(int $id): View
    {
        $partner = User::with(['userRoles.role', 'salesDocuments', 'parent', 'salesPartner'])->findOrFail($id);
        $roles = $this->service->getSalesRoles();
        $currentRoleIds = $partner->userRoles->pluck('role_id')->toArray();
        $documentTypes = SalesManagerDocument::DOCUMENT_TYPES;

        return view('sales.managers.partials.edit-modal', compact(
            'partner', 'roles', 'currentRoleIds', 'documentTypes'
        ));
    }

    /**
     * 수정 폼
     */
    public function edit(int $id): View
    {
        $partner = User::with(['userRoles.role', 'salesDocuments', 'parent'])->findOrFail($id);

        // 영업 역할 목록
        $roles = $this->service->getSalesRoles();

        // 현재 역할 ID 목록
        $currentRoleIds = $partner->userRoles->pluck('role_id')->toArray();

        // 문서 타입 목록
        $documentTypes = SalesManagerDocument::DOCUMENT_TYPES;

        return view('sales.managers.edit', compact(
            'partner', 'roles', 'currentRoleIds', 'documentTypes'
        ));
    }

    /**
     * 수정 처리
     */
    public function update(Request $request, int $id)
    {
        $partner = User::findOrFail($id);

        $validated = $request->validate([
            'name' => 'required|string|max:100',
            'email' => 'required|email|max:255|unique:users,email,'.$id,
            'phone' => 'nullable|string|max:20',
            'password' => 'nullable|string|min:4|confirmed',
            'role_ids' => 'required|array|min:1',
            'role_ids.*' => 'exists:roles,id',
            'partner_type' => 'nullable|in:individual,corporate',
            'company_name' => 'nullable|string|max:100',
            'biz_no' => 'nullable|string|max:20',
            'address' => 'nullable|string|max:255',
            'documents' => 'nullable|array',
            'documents.*.file' => 'nullable|file|max:10240',
            'documents.*.document_type' => 'nullable|string',
            'documents.*.description' => 'nullable|string|max:500',
        ]);

        // 문서 배열 구성
        $documents = [];
        if ($request->hasFile('documents')) {
            foreach ($request->file('documents') as $index => $file) {
                $documents[] = [
                    'file' => $file,
                    'document_type' => $request->input("documents.{$index}.document_type", 'other'),
                    'description' => $request->input("documents.{$index}.description"),
                ];
            }
        }

        $this->service->updateSalesPartner($partner, $validated, $documents);

        if ($request->expectsJson()) {
            return response()->json(['success' => true, 'message' => '영업파트너 정보가 수정되었습니다.']);
        }

        return redirect()->route('sales.managers.index')
            ->with('success', '영업파트너 정보가 수정되었습니다.');
    }

    /**
     * 삭제 처리 (비활성화) - 최고관리자만 가능
     */
    public function destroy(int $id)
    {
        // 권한 체크: admin 역할만 삭제 가능
        if (! auth()->user()->isAdmin()) {
            abort(403, '삭제 권한이 없습니다.');
        }

        $partner = User::findOrFail($id);
        $partner->update(['is_active' => false]);

        return redirect()->route('sales.managers.index')
            ->with('success', '영업파트너가 비활성화되었습니다.');
    }

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

        return redirect()->back()
            ->with('success', '영업파트너가 승인되었습니다.');
    }

    /**
     * 반려 처리
     */
    public function reject(Request $request, int $id)
    {
        $validated = $request->validate([
            'rejection_reason' => 'required|string|max:1000',
        ]);

        $partner = User::findOrFail($id);
        $this->service->reject($partner, auth()->id(), $validated['rejection_reason']);

        return redirect()->back()
            ->with('success', '영업파트너가 반려되었습니다.');
    }

    /**
     * 역할 위임 처리
     */
    public function delegateRole(Request $request, int $id)
    {
        $validated = $request->validate([
            'to_user_id' => 'required|exists:users,id',
            'role_name' => 'required|string|in:manager',
        ]);

        $fromUser = User::findOrFail($id);
        $toUser = User::findOrFail($validated['to_user_id']);

        try {
            $this->service->delegateRole($fromUser, $toUser, $validated['role_name']);

            $roleLabel = '상담매니저';

            return redirect()->back()
                ->with('success', "{$roleLabel} 역할이 {$toUser->name}님에게 위임되었습니다.");
        } catch (\InvalidArgumentException $e) {
            return redirect()->back()
                ->with('error', $e->getMessage());
        }
    }

    /**
     * 역할 부여
     */
    public function assignRole(Request $request, int $id)
    {
        $validated = $request->validate([
            'role_name' => 'required|string|in:sales,manager',
        ]);

        $partner = User::findOrFail($id);
        $this->service->assignRole($partner, $validated['role_name']);

        $roleLabels = ['sales' => '영업파트너', 'manager' => '상담매니저'];

        return redirect()->back()
            ->with('success', "{$roleLabels[$validated['role_name']]} 역할이 부여되었습니다.");
    }

    /**
     * 역할 제거
     */
    public function removeRole(Request $request, int $id)
    {
        $validated = $request->validate([
            'role_name' => 'required|string|in:sales,manager',
        ]);

        $partner = User::findOrFail($id);
        $this->service->removeRole($partner, $validated['role_name']);

        $roleLabels = ['sales' => '영업파트너', 'manager' => '상담매니저'];

        return redirect()->back()
            ->with('success', "{$roleLabels[$validated['role_name']]} 역할이 제거되었습니다.");
    }

    /**
     * 서류 다운로드
     */
    public function downloadDocument(int $id, int $documentId)
    {
        $document = SalesManagerDocument::where('user_id', $id)
            ->findOrFail($documentId);

        return $document->download();
    }

    /**
     * 서류 삭제
     */
    public function deleteDocument(int $id, int $documentId)
    {
        $document = SalesManagerDocument::where('user_id', $id)
            ->findOrFail($documentId);

        $this->service->deleteDocument($document);

        return redirect()->back()
            ->with('success', '서류가 삭제되었습니다.');
    }

    /**
     * 영업파트너 승인 목록 (본사 관리자 전용)
     */
    public function approvals(Request $request): View|Response
    {
        // 권한 체크: admin 역할만 접근 가능
        if (! auth()->user()->isAdmin()) {
            abort(403, '접근 권한이 없습니다.');
        }

        if ($request->header('HX-Request')) {
            return response('', 200)->header('HX-Redirect', route('sales.managers.approvals'));
        }

        $search = $request->get('search');

        // 승인 대기자 목록
        $pendingPartners = $this->service->getSalesPartners([
            'search' => $search,
            'approval_status' => 'pending',
        ])->paginate(10, ['*'], 'pending_page');

        // 승인된 파트너 목록 (최근 승인 순)
        $approvedPartners = $this->service->getSalesPartners([
            'search' => $search,
            'approval_status' => 'approved',
        ])->reorder()->latest('approved_at')->paginate(10, ['*'], 'approved_page');

        $stats = $this->service->getApprovalStats();

        return view('sales.managers.approvals', compact('pendingPartners', 'approvedPartners', 'stats'));
    }

    /**
     * 승인 목록에서 승인 처리
     */
    public function approveFromList(Request $request, int $id)
    {
        // 권한 체크
        if (! auth()->user()->isAdmin()) {
            abort(403, '접근 권한이 없습니다.');
        }

        $partner = User::findOrFail($id);
        $this->service->approve($partner, auth()->id());

        if ($request->header('HX-Request')) {
            return response()->json([
                'success' => true,
                'message' => "{$partner->name}님이 승인되었습니다.",
            ]);
        }

        return redirect()->route('sales.managers.approvals')
            ->with('success', "{$partner->name}님이 승인되었습니다.");
    }

    /**
     * 승인 목록에서 반려 처리
     */
    public function rejectFromList(Request $request, int $id)
    {
        // 권한 체크
        if (! auth()->user()->isAdmin()) {
            abort(403, '접근 권한이 없습니다.');
        }

        $validated = $request->validate([
            'rejection_reason' => 'required|string|max:1000',
        ]);

        $partner = User::findOrFail($id);
        $this->service->reject($partner, auth()->id(), $validated['rejection_reason']);

        if ($request->header('HX-Request')) {
            return response()->json([
                'success' => true,
                'message' => "{$partner->name}님이 반려되었습니다.",
            ]);
        }

        return redirect()->route('sales.managers.approvals')
            ->with('success', "{$partner->name}님이 반려되었습니다.");
    }
}
