<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Models\Appointment;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

final class AppointmentsController
{
    public function index(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
    {
        $tenantId = $request->getAttribute('tenant_id');
        $from = $request->getQueryParam('from');
        $to = $request->getQueryParam('to');

        $query = Appointment::where('tenant_id', $tenantId)->with(['student', 'instructor', 'lessonType']);
        if ($from && $to) {
            $query->whereBetween('start_at', [$from, $to]);
        }
        return $this->json($response, $query->get()->toArray());
    }

    public function store(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
    {
        $tenantId = $request->getAttribute('tenant_id');
        $user = $request->getAttribute('user');
        $data = json_decode($request->getBody()->getContents(), true);

        $appointment = Appointment::create([
            'tenant_id' => $tenantId,
            'student_id' => $data['student_id'] ?? null,
            'instructor_id' => $data['instructor_id'],
            'lesson_type_id' => $data['lesson_type_id'],
            'title' => $data['title'] ?? '',
            'category' => $data['category'] ?? 'student',
            'start_at' => $data['start_at'],
            'end_at' => $data['end_at'],
            'units' => $data['units'] ?? 1,
            'status' => 'planned',
            'notes' => $data['notes'] ?? '',
            'created_by' => $user['id'],
            'updated_by' => $user['id'],
        ]);

        return $this->json($response, $appointment->toArray(), 201);
    }

    public function update(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        $tenantId = $request->getAttribute('tenant_id');
        $user = $request->getAttribute('user');
        $appointment = Appointment::where('id', $args['id'])->where('tenant_id', $tenantId)->first();
        if (!$appointment) return $this->json($response, ['message' => 'Not found'], 404);

        $data = json_decode($request->getBody()->getContents(), true);
        $data['updated_by'] = $user['id'];
        $appointment->update(array_intersect_key($data, array_flip([
            'student_id', 'instructor_id', 'lesson_type_id', 'title', 'start_at', 'end_at', 'units', 'status', 'notes', 'warning_acknowledged', 'updated_by'
        ])));

        return $this->json($response, $appointment->fresh()->toArray());
    }

    public function destroy(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        $tenantId = $request->getAttribute('tenant_id');
        $appointment = Appointment::where('id', $args['id'])->where('tenant_id', $tenantId)->first();
        if (!$appointment) return $this->json($response, ['message' => 'Not found'], 404);
        $appointment->delete();
        return $this->json($response, ['message' => 'Deleted']);
    }

    private function json(ResponseInterface $response, array $data, int $status = 200): ResponseInterface
    {
        $response->getBody()->write(json_encode($data));
        return $response->withStatus($status)->withHeader('Content-Type', 'application/json');
    }
}