Shader "Custom/BrickWallTile"
{
    Properties
    {
        _TileTexture("Tile Texture", 2D) = "white" {}
        _GroutTexture("Grout Texture", 2D) = "black" {}
        _TileNormalMap("Tile Normal Map", 2D) = "bump" {}
        _TileWidth("Tile Width (in)", Float) = 8.0 
        _TileHeight("Tile Height (in)", Float) = 8.0 
        _GroutWidth("Grout Width (in)", Float) = 2.0 
        _GroutColor("Grout Color", Color) = (0.1, 0.1, 1, 1)
        _RotationAngle("Rotation Angle (degrees)", Float) = 0.0
        _TileSmoothness("Tile Smoothness", Range(0, 1)) = 0.5
        _TileNormalScale("Tile Normal Scale", Range(0, 10)) = 1.0
    }
    SubShader
    {
        Tags { "RenderType" = "Opaque" }
        LOD 200

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _TileTexture;
            sampler2D _GroutTexture;
            sampler2D _TileNormalMap;
            float _TileWidth;
            float _TileHeight;
            float _GroutWidth;
            fixed4 _GroutColor;
            float _RotationAngle;
            float _TileSmoothness;
            float _TileNormalScale;

            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                float tileWidthMeters = _TileWidth * 0.0254;
                float tileHeightMeters = _TileHeight * 0.0254;
                float groutWidthMeters = _GroutWidth * 0.0254;

                float2 tileSize = float2(tileWidthMeters, tileHeightMeters);
                float2 groutSize = float2(groutWidthMeters, groutWidthMeters);
                float2 tileWithGroutSize = tileSize + groutSize;

                // Rotation matrix
                float rad = radians(_RotationAngle);
                float2x2 rotationMatrix = float2x2(cos(rad), -sin(rad), sin(rad), cos(rad));

                // Apply rotation to UV coordinates
                float2 rotatedUV = mul(rotationMatrix, i.uv - 0.5) + 0.5;

                int rowIndex = floor(rotatedUV.y / tileWithGroutSize.y);
                int columnIndex = floor(rotatedUV.x / tileWithGroutSize.x);

                float2 adjustedUV = rotatedUV;
                if (rowIndex % 2 != 0)
                {
                    adjustedUV.x += tileWidthMeters / 2.0;
                }

                float2 tilePos = frac(adjustedUV / tileWithGroutSize);

                bool isTile = tilePos.x < tileWidthMeters / tileWithGroutSize.x && tilePos.y < tileHeightMeters / tileWithGroutSize.y;

                fixed4 color = isTile ? tex2D(_TileTexture, tilePos / (tileWidthMeters / tileWithGroutSize.x)) : tex2D(_GroutTexture, tilePos / (groutWidthMeters / tileWithGroutSize.y));

                if (isTile)
                {
                    float3 normalTex = UnpackNormal(tex2D(_TileNormalMap, tilePos / (tileWidthMeters / tileWithGroutSize.x)));
                    normalTex.xy *= _TileNormalScale; // Scale the normal map effect
                    normalTex = normalize(normalTex); // Normalize the normal vector

                    float3 normal = normalTex;

                    // Simulate fixed lighting effect
                    float3 fixedLightDir = normalize(float3(0.5, 0.5, 0.5));
                    float NdotL = max(0.0, dot(normal, fixedLightDir));
                    float3 reflectDir = reflect(-fixedLightDir, normal);
                    float3 specular = pow(max(dot(reflectDir, fixedLightDir), 0.0), 16.0) * _TileSmoothness;

                    float3 ambient = 0.5 * color.rgb; // Increased ambient for visibility
                    float3 diffuse = NdotL * color.rgb;
                    float3 finalColor = ambient + diffuse + specular;

                    return fixed4(finalColor, color.a);
                }
                else
                {
                    return _GroutColor;
                }
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}