<?php

/**
 * 文件功能：前台婚姻控制器
 *
 * 处理求婚、接受/拒绝、查询婚姻状态、申请离婚等前台操作。
 * 所有操作通过 MarriageService 执行，Events 负责广播。
 *
 * @author  ChatRoom Laravel
 *
 * @version 1.0.0
 */

namespace App\Http\Controllers;

use App\Events\MarriageAccepted;
use App\Events\MarriageDivorced;
use App\Events\MarriageDivorceRequested;
use App\Events\MarriageProposed;
use App\Events\MarriageRejected;
use App\Models\Marriage;
use App\Models\UserPurchase;
use App\Services\MarriageConfigService;
use App\Services\MarriageService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class MarriageController extends Controller
{
    public function __construct(
        private readonly MarriageService $marriage,
        private readonly MarriageConfigService $config,
    ) {}

    /**
     * 获取离婚相关惩罚配置（供前端展示风险提示）。
     * 返回协议离婚魅力惩罚、强制离婚魅力惩罚及各冷静期天数。
     */
    public function divorceConfig(): JsonResponse
    {
        return response()->json([
            'mutual_charm_penalty' => (int) $this->config->get('divorce_mutual_charm', 100),
            'forced_charm_penalty' => (int) $this->config->get('divorce_forced_charm', 300),
            'mutual_cooldown_days' => (int) $this->config->get('divorce_mutual_cooldown', 70),
            'forced_cooldown_days' => (int) $this->config->get('divorce_forced_cooldown', 90),
        ]);
    }

    /**
     * 获取全站已婚列表（按亲密度或结婚时间排序）。
     */
    public function list(Request $request): JsonResponse
    {
        $marriages = Marriage::query()
            ->where('status', 'married')
            ->with(['user:id,username,usersf,sex', 'partner:id,username,usersf,sex', 'ringItem:id,name,icon'])
            ->orderByDesc('intimacy')
            ->orderByDesc('married_at')
            ->paginate(20);

        return response()->json([
            'status' => 'success',
            'data' => $marriages->items(),
            'pagination' => [
                'current_page' => $marriages->currentPage(),
                'last_page' => $marriages->lastPage(),
                'total' => $marriages->total(),
            ],
        ]);
    }

    /**
     * 获取当前用户的婚姻状态（名片/用户列表用）。
     */
    public function status(Request $request): JsonResponse
    {
        $user = $request->user();
        $marriage = Marriage::currentFor($user->id);

        if (! $marriage) {
            return response()->json(['married' => false]);
        }

        $marriage->load(['user:id,username,usersf', 'partner:id,username,usersf', 'ringItem:id,name,slug,icon']);

        return response()->json([
            'married' => $marriage->status === 'married',
            'status' => $marriage->status,
            'marriage' => [
                'id' => $marriage->id,
                'user' => $marriage->user,
                'partner' => $marriage->partner,
                'ring' => $marriage->ringItem?->only(['name', 'icon']),
                'intimacy' => $marriage->intimacy,
                'level' => $marriage->level,
                'level_name' => \App\Services\MarriageIntimacyService::levelName($marriage->level),
                'level_icon' => \App\Services\MarriageIntimacyService::levelIcon($marriage->level),
                'married_at' => $marriage->married_at?->toDateString(),
                'days' => $marriage->married_at?->diffInDays(now()),
                'proposed_at' => $marriage->proposed_at,
                'expires_at' => $marriage->expires_at,
                'divorce_type' => $marriage->divorce_type,
                'divorcer_id' => $marriage->divorcer_id,
            ],
        ]);
    }

    /**
     * 查询目标用户的婚姻信息（用于双击名片展示）。
     */
    public function targetStatus(Request $request): JsonResponse
    {
        $request->validate(['username' => 'required|string']);
        $target = \App\Models\User::where('username', $request->username)->firstOrFail();

        $marriage = Marriage::query()
            ->where('status', 'married')
            ->where(function ($q) use ($target) {
                $q->where('user_id', $target->id)->orWhere('partner_id', $target->id);
            })
            ->with(['user:id,username,usersf', 'partner:id,username,usersf', 'ringItem:id,name,icon'])
            ->first();

        if (! $marriage) {
            return response()->json(['married' => false, 'marriage' => ['status' => 'none']]);
        }

        $partner = $marriage->user_id === $target->id ? $marriage->partner : $marriage->user;

        return response()->json([
            'married' => true,
            'marriage' => [
                'status' => $marriage->status,
                'marriage_id' => $marriage->id,
                'partner_name' => $partner?->username,
                'is_my_partner' => $partner?->id === $request->user()?->id,
                'ring' => $marriage->ringItem?->only(['name', 'icon']),
                'level_icon' => \App\Services\MarriageIntimacyService::levelIcon($marriage->level),
                'level_name' => \App\Services\MarriageIntimacyService::levelName($marriage->level),
                'days' => $marriage->married_at?->diffInDays(now()),
                'intimacy' => $marriage->intimacy,
            ],
        ]);
    }

    /**
     * 发起求婚。
     */
    public function propose(Request $request): JsonResponse
    {
        $data = $request->validate([
            'target_username' => 'required|string',
            'ring_purchase_id' => 'required|integer',
            'wedding_tier_id' => 'nullable|integer',
        ]);

        $proposer = $request->user();
        $target = \App\Models\User::where('username', $data['target_username'])->first();

        if (! $target) {
            return response()->json(['ok' => false, 'message' => '用户不存在。'], 404);
        }

        $result = $this->marriage->propose($proposer, $target, $data['ring_purchase_id'], $data['wedding_tier_id'] ?? null);

        if ($result['ok']) {
            $marriage = Marriage::find($result['marriage_id']);
            // 广播给被求婚方（私人频道）
            broadcast(new MarriageProposed($marriage, $proposer, $target));
        }

        return response()->json($result);
    }

    /**
     * 获取当前用户持有的有效戒指列表（求婚前选择用）。
     */
    public function myRings(Request $request): JsonResponse
    {
        $rings = UserPurchase::query()
            ->where('user_id', $request->user()->id)
            ->where('status', 'active')
            ->whereHas('item', fn ($q) => $q->where('type', 'ring'))
            ->with('item:id,name,slug,icon,price,intimacy_bonus,charm_bonus')
            ->get()
            ->map(fn ($p) => [
                'purchase_id' => $p->id,
                'name' => $p->item->name,
                'icon' => $p->item->icon,
                'slug' => $p->item->slug,
                'intimacy_bonus' => (int) ($p->item->intimacy_bonus ?? 0),
                'charm_bonus' => (int) ($p->item->charm_bonus ?? 0),
            ]);

        return response()->json(['status' => 'success', 'rings' => $rings]);
    }

    /**
     * 接受求婚。
     */
    public function accept(Request $request, Marriage $marriage): JsonResponse
    {
        $result = $this->marriage->accept($marriage, $request->user());

        if ($result['ok']) {
            $marriage->refresh();
            // 广播全房间结婚公告
            broadcast(new MarriageAccepted($marriage));
        }

        return response()->json($result);
    }

    /**
     * 拒绝求婚。
     */
    public function reject(Request $request, Marriage $marriage): JsonResponse
    {
        $result = $this->marriage->reject($marriage, $request->user());

        if ($result['ok']) {
            broadcast(new MarriageRejected($marriage));
        }

        return response()->json($result);
    }

    /**
     * 申请离婚（协议或强制）。
     */
    public function divorce(Request $request, Marriage $marriage): JsonResponse
    {
        $type = $request->input('type', 'mutual'); // mutual | forced
        $result = $this->marriage->divorce($marriage, $request->user(), $type);

        if ($result['ok']) {
            $marriage->refresh();
            if ($marriage->status === 'divorced') {
                broadcast(new MarriageDivorced($marriage, $type));
            } else {
                // 协议离婚：通知对方
                broadcast(new MarriageDivorceRequested($marriage));
            }
        }

        return response()->json($result);
    }

    /**
     * 确认协议离婚。
     */
    public function confirmDivorce(Request $request, Marriage $marriage): JsonResponse
    {
        $result = $this->marriage->confirmDivorce($marriage, $request->user());

        if ($result['ok']) {
            $marriage->refresh();
            broadcast(new MarriageDivorced($marriage, 'mutual'));
        }

        return response()->json($result);
    }

    /**
     * 拒绝协议离婚申请（被申请方选择不同意 = 视为强制离婚）。
     * 申请人赔偿一半金币给对方，婚姻以 forced 类型解除。
     */
    public function rejectDivorce(Request $request, Marriage $marriage): JsonResponse
    {
        $result = $this->marriage->rejectDivorce($marriage, $request->user());

        if ($result['ok']) {
            $marriage->refresh();
            broadcast(new MarriageDivorced($marriage, 'forced'));
        }

        return response()->json($result);
    }
}
