using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace {{namespace}}.Controllers;

/// <summary>
/// API controller for {{name}} operations
/// </summary>
[ApiController]
[Route("api/[controller]")]
{{#if navRoute}}
[NavRoute("{{navRoute}}")]
{{/if}}
[Authorize]
[Produces("application/json")]
public class {{name}}Controller : ControllerBase
{
    private readonly ILogger<{{name}}Controller> _logger;
    // private readonly I{{name}}Service _{{nameCamel}}Service;

    public {{name}}Controller(
        ILogger<{{name}}Controller> logger
        // I{{name}}Service {{nameCamel}}Service
    )
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        // _{{nameCamel}}Service = {{nameCamel}}Service ?? throw new ArgumentNullException(nameof({{nameCamel}}Service));
    }

    /// <summary>
    /// Get all {{namePlural}}
    /// </summary>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>List of {{namePlural}}</returns>
    [HttpGet]
{{#if navRoute}}
    [Authorize(Policy = "{{navRoute}}.read")]
{{/if}}
    [ProducesResponseType(typeof(IEnumerable<{{name}}Dto>), 200)]
    public async Task<ActionResult<IEnumerable<{{name}}Dto>>> GetAll(CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("Getting all {{namePlural}}");

        // TODO: Implement using service
        // var result = await _{{nameCamel}}Service.GetAllAsync(cancellationToken);
        // return Ok(result);

        return Ok(Array.Empty<{{name}}Dto>());
    }

    /// <summary>
    /// Get {{nameCamel}} by ID
    /// </summary>
    /// <param name="id">{{name}} ID</param>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>{{name}} details</returns>
    [HttpGet("{id:guid}")]
{{#if navRoute}}
    [Authorize(Policy = "{{navRoute}}.read")]
{{/if}}
    [ProducesResponseType(typeof({{name}}Dto), 200)]
    [ProducesResponseType(404)]
    public async Task<ActionResult<{{name}}Dto>> GetById(
        Guid id,
        CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("Getting {{nameCamel}} {Id}", id);

        // TODO: Implement using service
        // var result = await _{{nameCamel}}Service.GetByIdAsync(id, cancellationToken);
        // if (result == null) return NotFound();
        // return Ok(result);

        return NotFound();
    }

    /// <summary>
    /// Create new {{nameCamel}}
    /// </summary>
    /// <param name="request">Create request</param>
    /// <param name="cancellationToken">Cancellation token</param>
    /// <returns>Created {{nameCamel}}</returns>
    [HttpPost]
{{#if navRoute}}
    [Authorize(Policy = "{{navRoute}}.create")]
{{/if}}
    [ProducesResponseType(typeof({{name}}Dto), 201)]
    [ProducesResponseType(400)]
    public async Task<ActionResult<{{name}}Dto>> Create(
        [FromBody] Create{{name}}Request request,
        CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("Creating new {{nameCamel}}");

        // TODO: Validate and create using service
        // var result = await _{{nameCamel}}Service.CreateAsync(request, cancellationToken);
        // return CreatedAtAction(nameof(GetById), new { id = result.Id }, result);

        var id = Guid.NewGuid();
        return CreatedAtAction(nameof(GetById), new { id }, null);
    }

    /// <summary>
    /// Update {{nameCamel}}
    /// </summary>
    /// <param name="id">{{name}} ID</param>
    /// <param name="request">Update request</param>
    /// <param name="cancellationToken">Cancellation token</param>
    [HttpPut("{id:guid}")]
{{#if navRoute}}
    [Authorize(Policy = "{{navRoute}}.update")]
{{/if}}
    [ProducesResponseType(204)]
    [ProducesResponseType(404)]
    [ProducesResponseType(400)]
    public async Task<ActionResult> Update(
        Guid id,
        [FromBody] Update{{name}}Request request,
        CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("Updating {{nameCamel}} {Id}", id);

        // TODO: Implement using service
        // await _{{nameCamel}}Service.UpdateAsync(id, request, cancellationToken);

        return NoContent();
    }

    /// <summary>
    /// Delete {{nameCamel}}
    /// </summary>
    /// <param name="id">{{name}} ID</param>
    /// <param name="cancellationToken">Cancellation token</param>
    [HttpDelete("{id:guid}")]
{{#if navRoute}}
    [Authorize(Policy = "{{navRoute}}.delete")]
{{/if}}
    [ProducesResponseType(204)]
    [ProducesResponseType(404)]
    public async Task<ActionResult> Delete(
        Guid id,
        CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("Deleting {{nameCamel}} {Id}", id);

        // TODO: Implement using service
        // await _{{nameCamel}}Service.DeleteAsync(id, cancellationToken);

        return NoContent();
    }
}

// ============================================================================
// DTOs
// ============================================================================

/// <summary>
/// {{name}} data transfer object
/// </summary>
public record {{name}}Dto(
    Guid Id,
    DateTime CreatedAt,
    DateTime? UpdatedAt
    // TODO: Add additional properties
);

/// <summary>
/// Request to create a new {{nameCamel}}
/// </summary>
public record Create{{name}}Request(
    // TODO: Add creation properties
);

/// <summary>
/// Request to update a {{nameCamel}}
/// </summary>
public record Update{{name}}Request(
    // TODO: Add update properties
);
