<?php

namespace App\Http\Controllers;

use App\Http\Requests\ReceiveRoomRegisterRequest;
use App\Http\Requests\ReceiveRoomStatusDataRequest;
use App\Http\Requests\SendRoomSwitchCommandRequest;
use App\Http\Requests\ReceiveSongIncrementRequest;
use App\Services\TcpSocketClient;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use App\Models\Song;
use App\Models\Branch;
use App\Models\Room;
use App\Models\MachineStatus;
use App\Enums\RoomStatus;
use App\Http\Responses\ApiResponse;

use Illuminate\Support\Facades\Log;
/**
 * @OA\Tag(
 *     name="Auth",
 *     description="包廂控制"
 * )
 */
class RoomControlController extends Controller
{
    /**
     * @OA\Post(
     *     path="/api/room/receiveRegister",
     *     summary="包廂註冊控制指令",
     *     description="依據傳入的 branch_id 與 room_name，知道過來的設備來之於那個IP設備。",
     *     operationId="registerRoomCommand",
     *     tags={"Room Control"},
     *     @OA\RequestBody(
     *         required=true,
     *         @OA\JsonContent(ref="#/components/schemas/ReceiveRoomRegisterRequest")
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="成功傳送指令並回傳 TCP 回應",
     *         @OA\JsonContent(
     *             allOf={
     *                 @OA\Schema(ref="#/components/schemas/ApiResponse"),
     *                 @OA\Schema(
     *                     @OA\Property(property="data", ref="#/components/schemas/Room")
     *                 )
     *             }
     *         )
     *     ),
     *     @OA\Response(
     *         response=401,
     *         description="Unauthorized",
     *         @OA\JsonContent(
     *             allOf={
     *                 @OA\Schema(ref="#/components/schemas/ApiResponse"),
     *                 @OA\Schema(
     *                     @OA\Property(property="code", type="string", example="UNAUTHORIZED"),
     *                     @OA\Property(property="message", type="string", example="Unauthorized"),
     *                     @OA\Property(property="data", type="null")
     *                 )
     *             }
     *         )
     *     ),
     *     @OA\Parameter(
     *         name="Accept",
     *         in="header",
     *         required=true,
     *         @OA\Schema(type="string", default="application/json")
     *     )
     * )
     */
    public function receiveRegister(ReceiveRoomRegisterRequest $request): JsonResponse 
    {
        // 1. 驗證帳密（登入用）
        $credentials = $request->only('email', 'password');

        if (!Auth::attempt($credentials)) {
            return ApiResponse::unauthorized(); 
        }

        // 2. 取得登入使用者
        $user = Auth::user();

        // 3. 產生或取得 Token
        if (empty($user->api_plain_token)) {
            $token = $user->createToken('pc-heartbeat')->plainTextToken;
            $user->api_plain_token = $token;
            $user->save();
        } else {
            $token = $user->api_plain_token;
        }

        // 4. 驗證其他註冊欄位
        $validated = $request->validated(); // branch_id, room_name, room_ip

        // 5. 找出對應包廂
        $roomType = null;
        $roomName = null;
        // 從 room_name（例如 PC101, SVR01）中擷取 type 與 name
        if (preg_match('/^([A-Za-z]+)(\d+)$/', $validated['room_name'], $matches)) {
            $roomType = strtolower($matches[1]); // 'PC' → 'pc'
            $roomName = $matches[2];             // '101'
        }
        $branch=Branch::where('name',$validated['branch_name'])->first();
        $room = Room::where('branch_id', $branch->id)
            ->where('name', $roomName)
            ->where('type', $roomType)
            ->first();

        if (!$room) {
            return ApiResponse::error('找不到對應包廂');
        }

        // 6. 更新包廂資訊
        $room->internal_ip = $validated['room_ip']; 
        $room->port = 1000; // 預設值
        $room->is_online =1;
        $room->touch(); // 更新 updated_at
        $room->save();

        // 7. 回傳 token 與包廂資料
        return ApiResponse::success([
            'token' => $token,
            'room' => $room,
        ]);
    }

    /**
     * @OA\Post(
     *     path="/api/room/heartbeat",
     *     summary="包廂心跳封包指令",
     *     description="記錄設備連線狀況",
     *     operationId="heartbeatRoomCommand",
     *     tags={"Room Control"},
     *     security={{"Authorization":{}}},
     *     @OA\RequestBody(
     *         required=true,
     *         @OA\JsonContent(ref="#/components/schemas/ReceiveRoomStatusDataRequest")
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="成功傳送指令並回傳 TCP 回應",
     *         @OA\JsonContent(
     *             allOf={
     *                 @OA\Schema(ref="#/components/schemas/ApiResponse"),
     *                 @OA\Schema(
     *                     @OA\Property(property="data", ref="#/components/schemas/MachineStatus")
     *                 )
     *             }
     *         )
     *     ),
     *     @OA\Response(
     *         response=401,
     *         description="Unauthorized",
     *         @OA\JsonContent(
     *             allOf={
     *                 @OA\Schema(ref="#/components/schemas/ApiResponse"),
     *                 @OA\Schema(
     *                     @OA\Property(property="code", type="string", example="UNAUTHORIZED"),
     *                     @OA\Property(property="message", type="string", example="Unauthorized"),
     *                     @OA\Property(property="data", type="null")
     *                 )
     *             }
     *         )
     *     ),
     *     @OA\Parameter(
     *         name="Accept",
     *         in="header",
     *         required=true,
     *         @OA\Schema(type="string", default="application/json")
     *     )
     * )
     */
    public function StatusReport(ReceiveRoomStatusDataRequest $request)
    {
        $validated = $request->validated();
        $roomType = null;
        $roomName = null;
        // 從 room_name（例如 PC101, SVR01）中擷取 type 與 name
        if (preg_match('/^([A-Za-z]+)(\d+)$/', $validated['hostname'], $matches)) {
            $roomType = strtolower($matches[1]); // 'PC' → 'pc'
            $roomName = $matches[2];             // '101'
        }
        $branch=Branch::where('name',$validated['branch_name'])->first();
        $room = Room::where('branch_id', $branch->id)
            ->where('name', $roomName)
            ->where('type', $roomType)
            ->first();
        // 決定 status 欄位值
        $validated['status']=  'error';
        if($room){
            $validated['status']=  'online';
            if($room->internal_ip != $validated['ip']){
                $room->internal_ip = $validated['ip'];
                $validated['status']='error';
            }
            $room->is_online=1;
            $room->touch(); // 更新 updated_at
            $room->save();
        }

        return ApiResponse::success([
            'data' => MachineStatus::create($validated),
        ]);
    }
    /**
     * @OA\Post(
     *     path="/api/room/sendSwitch",
     *     summary="送出包廂控制指令",
     *     description="依據傳入的 room_id 與 command，透過 TCP 傳送對應指令給包廂電腦。",
     *     operationId="sendRoomSwitchCommand",
     *     tags={"Room Control"},
     *     security={{"Authorization":{}}},
     *     @OA\RequestBody(
     *         required=true,
     *         @OA\JsonContent(ref="#/components/schemas/SendRoomSwitchCommandRequest")
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="成功傳送指令並回傳 TCP 回應",
     *         @OA\JsonContent(
     *             allOf={
     *                 @OA\Schema(ref="#/components/schemas/ApiResponse"),
     *                 @OA\Schema(
     *                     @OA\Property(property="data", ref="#/components/schemas/Room")
     *                 )
     *             }
     *         )
     *     ),
     *     @OA\Response(
     *         response=401,
     *         description="Unauthorized",
     *         @OA\JsonContent(
     *             allOf={
     *                 @OA\Schema(ref="#/components/schemas/ApiResponse"),
     *                 @OA\Schema(
     *                     @OA\Property(property="code", type="string", example="UNAUTHORIZED"),
     *                     @OA\Property(property="message", type="string", example="Unauthorized"),
     *                     @OA\Property(property="data", type="null")
     *                 )
     *             }
     *         )
     *     ),
     *     @OA\Parameter(
     *         name="Accept",
     *         in="header",
     *         required=true,
     *         @OA\Schema(type="string", default="application/json")
     *     )
     * )
     */
    public function sendSwitch(SendRoomSwitchCommandRequest $request): JsonResponse
    {
        $validated = $request->validated();
        $branch = Branch::where('name',$validated['branch_name'])->first();
        $roomType = null;
        $roomName = null;
        // 從 room_name（例如 PC101, SVR01）中擷取 type 與 name
        if (preg_match('/^([A-Za-z]+)(\d+)$/', $validated['room_name'], $matches)) {
            $roomType = strtolower($matches[1]); // 'PC' → 'pc'
            $roomName = $matches[2];             // '101'
        }
        $room = Room::where('branch_id', $branch->id)
            ->where('name', $roomName)
            ->where('type', $roomType)
            ->first();

        if (!$room) {
            return ApiResponse::error('房間不存在');
        }

        // 檢查必要欄位是否缺失或狀態為錯誤
        if (empty($room->internal_ip) || empty($room->port)) {
            return ApiResponse::error('房間未設定 IP 或 Port');
        }

        $suffix = substr($room->name, -3) ?: $room->name;
        $signal = match ($validated['command']) {
            'active' => 'O',
            'closed' => 'X',
            'fire'   => 'F',
            default  => 'X', // fallback 保險起見
        };
        $data = $suffix . "," . $signal;
        
        //dd($data);
        $client = new TcpSocketClient($room->internal_ip, $room->port);
        try {
            $response = $client->send($data);
        } catch (\Throwable $e) {
            logger()->error('❌ TCP 傳送失敗: ' . $e->getMessage(), [
                'room_id' => $room->id,
                'ip'      => $room->internal_ip,
                'port'    => $room->port,
            ]);
            $validated['command']="error";
            $validated['started_at']=null;
            $validated['ended_at']=null;
        }

        $room->status=$validated['command'];
        $room->started_at=$validated['started_at'];
        $room->ended_at=$validated['ended_at'];
        $room->save();
        return $validated['command']==='error' ? ApiResponse::error('機房控制失敗') : ApiResponse::success($room);
    }
    /**
     * @OA\Post(
     *     path="/api/room/incrementSongCount",
     *     summary="歌曲點歌",
     *     description="歌曲點歌 依據 song_id 對歌曲加1",
     *     operationId="incrementSong",
     *     tags={"Room Control"},
     *     security={{"Authorization":{}}},
     *     @OA\RequestBody(
     *         required=true,
     *         @OA\JsonContent(ref="#/components/schemas/ReceiveSongIncrementRequest")
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="成功遞增 song_counts 並回傳歌曲資訊",
     *         @OA\JsonContent(
     *             allOf={
     *                 @OA\Schema(ref="#/components/schemas/ApiResponse"),
     *                 @OA\Schema(
     *                     @OA\Property(property="data", ref="#/components/schemas/SongCounts")
     *                 )
     *             }
     *         )
     *     ),
     *     @OA\Response(
     *         response=404,
     *         description="找不到歌曲",
     *         @OA\JsonContent(
     *             @OA\Property(property="code", type="string", example="NOT_FOUND"),
     *             @OA\Property(property="message", type="string", example="歌曲不存在"),
     *             @OA\Property(property="data", type="null")
     *         )
     *     )
     * )
     */
    public function incrementSongCount(ReceiveSongIncrementRequest $request): JsonResponse
    {
        $request->validate([
            'song_id' => 'required|integer|exists:songs,id',
        ]);

        $song = Song::find($request->input('song_id'));

        if (!$song) {
            return ApiResponse::error('歌曲不存在', 404);
        }

        $song->increment('song_counts');

        return ApiResponse::success($song->only(['id', 'name', 'song_counts']));
    }
}
