using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using WebClientTpos.Server.Infrastructure;

namespace WebClientTpos.Server.Controllers;

/// <summary>
/// EN: Booking controller — proxies to BookingService for appointments and resources.
/// VI: Controller đặt lịch — proxy đến BookingService cho lịch hẹn và tài nguyên.
/// </summary>
[ApiController]
[Route("api/bff")]
public class BookingController : ControllerBase
{
    private readonly HttpClient _booking;

    public BookingController(IHttpClientFactory httpClientFactory)
    {
        _booking = httpClientFactory.CreateClient("BookingService");
    }

    /// <summary>
    /// EN: Create an appointment.
    /// VI: Tạo lịch hẹn.
    /// </summary>
    [HttpPost("appointments")]
    public Task<IActionResult> CreateAppointment([FromBody] JsonElement body) =>
        _booking.PostAsJsonAsync("/api/v1/appointments", body).ProxyAsync();

    /// <summary>
    /// EN: Update an appointment.
    /// VI: Cập nhật lịch hẹn.
    /// </summary>
    [HttpPut("appointments/{apptId:guid}")]
    public Task<IActionResult> UpdateAppointment(Guid apptId, [FromBody] JsonElement body) =>
        _booking.PutAsJsonAsync($"/api/v1/appointments/{apptId}", body).ProxyAsync();

    /// <summary>
    /// EN: Cancel an appointment — forwards reason from body if provided.
    /// VI: Hủy lịch hẹn — chuyển tiếp lý do từ body nếu có.
    /// </summary>
    [HttpDelete("appointments/{apptId:guid}/cancel")]
    public async Task<IActionResult> CancelAppointment(Guid apptId)
    {
        string? reason = "Cancelled from POS";
        try
        {
            using var bodyDoc = await JsonDocument.ParseAsync(Request.Body);
            if (bodyDoc.RootElement.TryGetProperty("reason", out var reasonProp))
                reason = reasonProp.GetString() ?? reason;
        }
        catch { /* no body or invalid JSON — use default reason */ }

        using var request = new HttpRequestMessage(HttpMethod.Delete, $"/api/v1/appointments/{apptId}");
        request.Content = System.Net.Http.Json.JsonContent.Create(new { reason });
        return await _booking.SendAsync(request).ProxyAsync();
    }

    // ═══ THERAPIST / SPA STAFF ENDPOINTS ═══

    /// <summary>
    /// EN: Get therapists for a specific shop.
    /// VI: Lấy danh sách nhân viên trị liệu của một cửa hàng.
    /// </summary>
    [HttpGet("shops/{shopId}/therapists")]
    public Task<IActionResult> GetTherapists(Guid shopId) =>
        _booking.GetAsync($"/api/v1/therapists?shopId={shopId}").ProxyAsync();

    /// <summary>
    /// EN: Create a therapist.
    /// VI: Tạo nhân viên trị liệu.
    /// </summary>
    [HttpPost("therapists")]
    public Task<IActionResult> CreateTherapist([FromBody] JsonElement body) =>
        _booking.PostAsJsonAsync("/api/v1/therapists", body).ProxyAsync();

    /// <summary>
    /// EN: Update a therapist.
    /// VI: Cập nhật nhân viên trị liệu.
    /// </summary>
    [HttpPut("therapists/{therapistId:guid}")]
    public Task<IActionResult> UpdateTherapist(Guid therapistId, [FromBody] JsonElement body) =>
        _booking.PutAsJsonAsync($"/api/v1/therapists/{therapistId}", body).ProxyAsync();

    /// <summary>
    /// EN: Deactivate (soft-delete) a therapist.
    /// VI: Vô hiệu hóa (xóa mềm) nhân viên trị liệu.
    /// </summary>
    [HttpDelete("therapists/{therapistId:guid}")]
    public Task<IActionResult> DeactivateTherapist(Guid therapistId) =>
        _booking.DeleteAsync($"/api/v1/therapists/{therapistId}").ProxyAsync();

    /// <summary>
    /// EN: Get appointments for a specific shop, optionally filtered by date.
    /// VI: Lấy lịch hẹn của một cửa hàng, có thể lọc theo ngày.
    /// </summary>
    [HttpGet("shops/{shopId}/appointments")]
    public Task<IActionResult> GetAppointments(Guid shopId, [FromQuery] string? date = null)
    {
        var qs = !string.IsNullOrEmpty(date) ? $"&date={date}" : "";
        return _booking.GetAsync($"/api/v1/appointments?shopId={shopId}{qs}").ProxyAsync();
    }

    /// <summary>
    /// EN: Update appointment status (confirm, start, complete, noshow).
    /// VI: Cập nhật trạng thái lịch hẹn (xác nhận, bắt đầu, hoàn thành, vắng mặt).
    /// </summary>
    [HttpPatch("appointments/{apptId:guid}/status")]
    public Task<IActionResult> UpdateAppointmentStatus(Guid apptId, [FromBody] JsonElement body) =>
        _booking.PatchAsync($"/api/v1/appointments/{apptId}/status",
            System.Net.Http.Json.JsonContent.Create(body)).ProxyAsync();

    /// <summary>
    /// EN: Get resources for a specific shop.
    /// VI: Lấy tài nguyên của một cửa hàng cụ thể.
    /// </summary>
    [HttpGet("shops/{shopId}/resources")]
    public Task<IActionResult> GetResources(Guid shopId) =>
        _booking.GetAsync($"/api/v1/resources?shopId={shopId}").ProxyAsync();

    /// <summary>
    /// EN: Create a resource.
    /// VI: Tạo tài nguyên.
    /// </summary>
    [HttpPost("resources")]
    public Task<IActionResult> CreateResource([FromBody] JsonElement body) =>
        _booking.PostAsJsonAsync("/api/v1/resources", body).ProxyAsync();

    /// <summary>
    /// EN: Update a resource.
    /// VI: Cập nhật tài nguyên.
    /// </summary>
    [HttpPut("resources/{resourceId:guid}")]
    public Task<IActionResult> UpdateResource(Guid resourceId, [FromBody] JsonElement body) =>
        _booking.PutAsJsonAsync($"/api/v1/resources/{resourceId}", body).ProxyAsync();

    /// <summary>
    /// EN: Soft-delete a resource.
    /// VI: Xóa mềm tài nguyên.
    /// </summary>
    [HttpDelete("resources/{resourceId:guid}")]
    public Task<IActionResult> DeleteResource(Guid resourceId) =>
        _booking.DeleteAsync($"/api/v1/resources/{resourceId}").ProxyAsync();
}
