@page "/materials/new"
@page "/materials/{Id:int}"
@inject MaterialService MaterialService
@inject NavigationManager Navigation
@using CutList.Core.Formatting
@using CutList.Web.Data.Entities
@using CutList.Web.Components.Shared

<PageTitle>@(IsNew ? "Add Material" : "Edit Material")</PageTitle>

<h1>@(IsNew ? "Add Material" : material.DisplayName)</h1>

@if (loading)
{
    <p><em>Loading...</em></p>
}
else
{
    <div class="row">
        <div class="col-lg-6 mb-4">
            <div class="card">
                <div class="card-header">
                    <h5 class="mb-0">Material Details</h5>
                </div>
                <div class="card-body">
                    <EditForm Model="material" OnValidSubmit="SaveAsync">
                        <DataAnnotationsValidator />

                        <div class="mb-3">
                            <label class="form-label">Shape</label>
                            <InputSelect class="form-select" @bind-Value="selectedShape" @bind-Value:after="OnShapeChanged">
                                <option value="">-- Select Shape --</option>
                                @foreach (var shape in Enum.GetValues<MaterialShape>())
                                {
                                    <option value="@shape">@shape.GetDisplayName()</option>
                                }
                            </InputSelect>
                            <ValidationMessage For="@(() => material.Shape)" />
                        </div>

                        <div class="row">
                            <div class="col-md-6 mb-3">
                                <label class="form-label">Type</label>
                                <InputSelect class="form-select" @bind-Value="material.Type">
                                    @foreach (var type in Enum.GetValues<MaterialType>())
                                    {
                                        <option value="@type">@type</option>
                                    }
                                </InputSelect>
                            </div>
                            <div class="col-md-6 mb-3">
                                <label class="form-label">Grade</label>
                                <InputText class="form-control" @bind-Value="material.Grade" placeholder="e.g., A36, Hot Roll, 304" />
                            </div>
                        </div>

                        @if (selectedShape != null)
                        {
                            @RenderDimensionInputs()
                        }

                        <div class="mb-3">
                            <label class="form-label">Size Display (auto-generated)</label>
                            <InputText class="form-control" @bind-Value="material.Size" placeholder="Will be auto-generated from dimensions" />
                            <div class="form-text">Leave blank to auto-generate from dimensions, or customize as needed.</div>
                        </div>

                        <div class="mb-3">
                            <label class="form-label">Description (optional)</label>
                            <InputText class="form-control" @bind-Value="material.Description" placeholder="Optional description" />
                        </div>

                        @if (!string.IsNullOrEmpty(errorMessage))
                        {
                            <div class="alert alert-danger">@errorMessage</div>
                        }

                        <div class="d-flex gap-2">
                            <button type="submit" class="btn btn-primary" disabled="@saving">
                                @if (saving)
                                {
                                    <span class="spinner-border spinner-border-sm me-1"></span>
                                }
                                @(IsNew ? "Create Material" : "Save Changes")
                            </button>
                            <a href="materials" class="btn btn-outline-secondary">@(IsNew ? "Cancel" : "Back to List")</a>
                        </div>
                    </EditForm>
                </div>
            </div>
        </div>

        @if (selectedShape != null)
        {
            <div class="col-lg-6 mb-4">
                <div class="card">
                    <div class="card-header">
                        <h5 class="mb-0">Preview</h5>
                    </div>
                    <div class="card-body">
                        <dl class="row mb-0">
                            <dt class="col-sm-4">Shape</dt>
                            <dd class="col-sm-8">@selectedShape.Value.GetDisplayName()</dd>

                            <dt class="col-sm-4">Type</dt>
                            <dd class="col-sm-8">@material.Type</dd>

                            @if (!string.IsNullOrWhiteSpace(material.Grade))
                            {
                                <dt class="col-sm-4">Grade</dt>
                                <dd class="col-sm-8">@material.Grade</dd>
                            }

                            <dt class="col-sm-4">Size</dt>
                            <dd class="col-sm-8">@GetPreviewSize()</dd>

                            @if (!string.IsNullOrWhiteSpace(material.Description))
                            {
                                <dt class="col-sm-4">Description</dt>
                                <dd class="col-sm-8">@material.Description</dd>
                            }
                        </dl>
                    </div>
                </div>
            </div>
        }
    </div>
}

@code {
    [Parameter]
    public int? Id { get; set; }

    private Material material = new();
    private MaterialShape? selectedShape;
    private bool loading = true;
    private bool saving;
    private string? errorMessage;

    // Typed dimension objects for each shape
    private RoundBarDimensions roundBarDims = new();
    private RoundTubeDimensions roundTubeDims = new();
    private FlatBarDimensions flatBarDims = new();
    private SquareBarDimensions squareBarDims = new();
    private SquareTubeDimensions squareTubeDims = new();
    private RectangularTubeDimensions rectTubeDims = new();
    private AngleDimensions angleDims = new();
    private ChannelDimensions channelDims = new();
    private IBeamDimensions ibeamDims = new();
    private PipeDimensions pipeDims = new();

    private bool IsNew => !Id.HasValue;

    protected override async Task OnInitializedAsync()
    {
        if (Id.HasValue)
        {
            var existing = await MaterialService.GetByIdAsync(Id.Value);
            if (existing == null)
            {
                Navigation.NavigateTo("materials");
                return;
            }
            material = existing;
            selectedShape = existing.Shape;
            LoadDimensionsFromMaterial(existing);
        }
        loading = false;
    }

    private void LoadDimensionsFromMaterial(Material m)
    {
        if (m.Dimensions == null) return;

        switch (m.Dimensions)
        {
            case RoundBarDimensions d: roundBarDims = d; break;
            case RoundTubeDimensions d: roundTubeDims = d; break;
            case FlatBarDimensions d: flatBarDims = d; break;
            case SquareBarDimensions d: squareBarDims = d; break;
            case SquareTubeDimensions d: squareTubeDims = d; break;
            case RectangularTubeDimensions d: rectTubeDims = d; break;
            case AngleDimensions d: angleDims = d; break;
            case ChannelDimensions d: channelDims = d; break;
            case IBeamDimensions d: ibeamDims = d; break;
            case PipeDimensions d: pipeDims = d; break;
        }
    }

    private MaterialDimensions GetCurrentDimensions() => selectedShape switch
    {
        MaterialShape.RoundBar => roundBarDims,
        MaterialShape.RoundTube => roundTubeDims,
        MaterialShape.FlatBar => flatBarDims,
        MaterialShape.SquareBar => squareBarDims,
        MaterialShape.SquareTube => squareTubeDims,
        MaterialShape.RectangularTube => rectTubeDims,
        MaterialShape.Angle => angleDims,
        MaterialShape.Channel => channelDims,
        MaterialShape.IBeam => ibeamDims,
        MaterialShape.Pipe => pipeDims,
        _ => throw new InvalidOperationException("No shape selected")
    };

    private void OnShapeChanged()
    {
        if (selectedShape.HasValue)
        {
            material.Shape = selectedShape.Value;
        }
    }

    private string GetPreviewSize()
    {
        if (!string.IsNullOrWhiteSpace(material.Size))
        {
            return material.Size;
        }

        if (selectedShape.HasValue)
        {
            try
            {
                var generated = GetCurrentDimensions().GenerateSizeString();
                return string.IsNullOrWhiteSpace(generated) ? "(enter dimensions)" : generated;
            }
            catch
            {
                return "(enter dimensions)";
            }
        }

        return "(select shape and enter dimensions)";
    }

    private RenderFragment RenderDimensionInputs() => __builder =>
    {
        switch (selectedShape!.Value)
        {
            case MaterialShape.RoundBar:
                <div class="mb-3">
                    <label class="form-label">Diameter</label>
                    <LengthInput @bind-Value="roundBarDims.Diameter" Placeholder="e.g., 1/2&quot; or 0.5" />
                </div>
                break;

            case MaterialShape.RoundTube:
                <div class="mb-3">
                    <label class="form-label">Outer Diameter</label>
                    <LengthInput @bind-Value="roundTubeDims.OuterDiameter" Placeholder="e.g., 1&quot; or 1.0" />
                </div>
                <div class="mb-3">
                    <label class="form-label">Wall Thickness</label>
                    <LengthInput @bind-Value="roundTubeDims.Wall" Placeholder="e.g., 0.065 or 1/16&quot;" />
                </div>
                break;

            case MaterialShape.FlatBar:
                <div class="mb-3">
                    <label class="form-label">Width</label>
                    <LengthInput @bind-Value="flatBarDims.Width" Placeholder="e.g., 2&quot; or 2.0" />
                </div>
                <div class="mb-3">
                    <label class="form-label">Thickness</label>
                    <LengthInput @bind-Value="flatBarDims.Thickness" Placeholder="e.g., 1/4&quot; or 0.25" />
                </div>
                break;

            case MaterialShape.SquareBar:
                <div class="mb-3">
                    <label class="form-label">Size</label>
                    <LengthInput @bind-Value="squareBarDims.Size" Placeholder="e.g., 1&quot; or 1.0" />
                </div>
                break;

            case MaterialShape.SquareTube:
                <div class="mb-3">
                    <label class="form-label">Size</label>
                    <LengthInput @bind-Value="squareTubeDims.Size" Placeholder="e.g., 2&quot; or 2.0" />
                </div>
                <div class="mb-3">
                    <label class="form-label">Wall Thickness</label>
                    <LengthInput @bind-Value="squareTubeDims.Wall" Placeholder="e.g., 0.125 or 1/8&quot;" />
                </div>
                break;

            case MaterialShape.RectangularTube:
                <div class="mb-3">
                    <label class="form-label">Width</label>
                    <LengthInput @bind-Value="rectTubeDims.Width" Placeholder="e.g., 2&quot; or 2.0" />
                </div>
                <div class="mb-3">
                    <label class="form-label">Height</label>
                    <LengthInput @bind-Value="rectTubeDims.Height" Placeholder="e.g., 3&quot; or 3.0" />
                </div>
                <div class="mb-3">
                    <label class="form-label">Wall Thickness</label>
                    <LengthInput @bind-Value="rectTubeDims.Wall" Placeholder="e.g., 0.125 or 1/8&quot;" />
                </div>
                break;

            case MaterialShape.Angle:
                <div class="mb-3">
                    <label class="form-label">Leg 1</label>
                    <LengthInput @bind-Value="angleDims.Leg1" Placeholder="e.g., 2&quot; or 2.0" />
                </div>
                <div class="mb-3">
                    <label class="form-label">Leg 2</label>
                    <LengthInput @bind-Value="angleDims.Leg2" Placeholder="e.g., 2&quot; or 2.0" />
                </div>
                <div class="mb-3">
                    <label class="form-label">Thickness</label>
                    <LengthInput @bind-Value="angleDims.Thickness" Placeholder="e.g., 1/4&quot; or 0.25" />
                </div>
                break;

            case MaterialShape.Channel:
                <div class="mb-3">
                    <label class="form-label">Height</label>
                    <LengthInput @bind-Value="channelDims.Height" Placeholder="e.g., 4&quot; or 4.0" />
                </div>
                <div class="mb-3">
                    <label class="form-label">Flange Width</label>
                    <LengthInput @bind-Value="channelDims.Flange" Placeholder="e.g., 1.58" />
                </div>
                <div class="mb-3">
                    <label class="form-label">Web Thickness</label>
                    <LengthInput @bind-Value="channelDims.Web" Placeholder="e.g., 0.18" />
                </div>
                break;

            case MaterialShape.IBeam:
                <div class="mb-3">
                    <label class="form-label">Height (nominal)</label>
                    <LengthInput @bind-Value="ibeamDims.Height" Placeholder="e.g., 8" />
                </div>
                <div class="mb-3">
                    <label class="form-label">Weight per Foot (lbs)</label>
                    <input type="number" class="form-control" step="0.01" @bind="ibeamDims.WeightPerFoot" placeholder="e.g., 31" />
                </div>
                break;

            case MaterialShape.Pipe:
                <div class="mb-3">
                    <label class="form-label">Nominal Pipe Size (NPS)</label>
                    <LengthInput @bind-Value="pipeDims.NominalSize" Placeholder="e.g., 1&quot; or 1.0" />
                </div>
                <div class="mb-3">
                    <label class="form-label">Schedule (optional)</label>
                    <InputText class="form-control" @bind-Value="pipeDims.Schedule" placeholder="e.g., 40, 80, STD" />
                </div>
                <div class="mb-3">
                    <label class="form-label">Wall Thickness (if no schedule)</label>
                    <LengthInput @bind-NullableValue="pipeDims.Wall" Placeholder="e.g., 0.133" />
                </div>
                break;
        }
    };

    private async Task SaveAsync()
    {
        errorMessage = null;
        saving = true;

        try
        {
            if (!selectedShape.HasValue)
            {
                errorMessage = "Shape is required";
                return;
            }

            material.Shape = selectedShape.Value;
            var dimensions = GetCurrentDimensions();

            // Auto-generate Size if empty
            if (string.IsNullOrWhiteSpace(material.Size))
            {
                material.Size = dimensions.GenerateSizeString();
            }

            if (string.IsNullOrWhiteSpace(material.Size))
            {
                errorMessage = "Size is required. Please enter dimensions or provide a size string.";
                return;
            }

            // Check for duplicates
            if (await MaterialService.ExistsAsync(material.Shape, material.Size, Id))
            {
                errorMessage = "A material with this shape and size already exists";
                return;
            }

            if (IsNew)
            {
                var created = await MaterialService.CreateWithDimensionsAsync(material, dimensions);
                Navigation.NavigateTo($"materials/{created.Id}");
            }
            else
            {
                await MaterialService.UpdateWithDimensionsAsync(material, dimensions);
            }
        }
        finally
        {
            saving = false;
        }
    }
}
