package com.mantz_it.guitartunerlibrary;

import android.content.Context;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Typeface;
import androidx.core.content.res.ResourcesCompat;

/**
 * <h1>Nixie Tube Tuner Skin</h1>
 *
 * <p>A retro-futuristic tuner skin that simulates the look of glowing Nixie tubes.</p>
 *
 * @author You and the AI Assistant
 */
public class NixieTubeTunerSkin extends DefaultTunerSkin {

    // --- PAINTS FOR THE BACKGROUND AND STRUCTURE ---
    private Paint backgroundPaint;
    private Paint glassTubePaint;
    private Paint glassGlarePaint;

    private Context context; // Store the Context directly
    // --- PAINTS FOR THE NIXIE TUBE TEXT ---
    private Paint unlitTextPaint;   // For the dark, "off" cathodes
    private Paint litTextPaint;     // For the main "lit" text
    private Paint glowTextPaint;    // For the outer glow effect

    // --- PAINTS FOR THE INDICATORS (SHARP/FLAT/IN-TUNE) ---
    private Paint sharpFlatPaint;   // For the sharp/flat symbols
    private Paint sharpFlatGlowPaint; // For the glow of the sharp/flat symbols
    private Paint inTuneLightPaint; // A simple green "LED" for when in tune

    private Typeface nixieFont; // A font that looks like Nixie tube digits/letters

    /**
     * Constructor.
     * @param context Context instance, required for loading fonts.
     */
    public NixieTubeTunerSkin(Context context) {
        super();
        this.context = context; // Store the context
    }

    @Override
    public void updateWidthAndHeight(int width, int height) {
        super.updateWidthAndHeight(width, height);

        if (width <= 0 || height <= 0) {
            // Initialize paints to default state to prevent other potential null pointer issues
            backgroundPaint = new Paint();
            glassTubePaint = new Paint();
            glassGlarePaint = new Paint();
            litTextPaint = new Paint();
            glowTextPaint = new Paint();
            unlitTextPaint = new Paint();
            sharpFlatPaint = new Paint();
            sharpFlatGlowPaint = new Paint();
            inTuneLightPaint = new Paint();
            return;
        }

        // --- SETUP FONTS ---
        try {
            // Use the stored context to load the font.
            nixieFont = ResourcesCompat.getFont(context, R.font.dseg7_00_normal);
        } catch (Exception e) {
            // Fallback if font not found
            nixieFont = Typeface.create(Typeface.MONOSPACE, Typeface.BOLD);
        }

        // --- SETUP BACKGROUND PAINTS ---
        backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        backgroundPaint.setStyle(Paint.Style.FILL);
        backgroundPaint.setShader(new LinearGradient(
                0, 0, 0, height,
                Color.parseColor("#212121"), // Dark Gray
                Color.parseColor("#424242"), // Lighter Gray
                Shader.TileMode.CLAMP
        ));

        // --- SETUP GLASS TUBE PAINTS ---
        glassTubePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        glassTubePaint.setStyle(Paint.Style.FILL);
        glassTubePaint.setColor(Color.argb(40, 50, 50, 50)); // Semi-transparent dark gray

        glassGlarePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        glassGlarePaint.setStyle(Paint.Style.STROKE);
        glassGlarePaint.setColor(Color.argb(60, 255, 255, 255)); // Semi-transparent white for glare
        glassGlarePaint.setStrokeWidth(height * 0.01f);

        // --- SETUP NIXIE TUBE TEXT PAINTS ---
        int nixieOrange = Color.parseColor("#FF7A00");

        litTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        litTextPaint.setTypeface(nixieFont);
        litTextPaint.setColor(nixieOrange);
        litTextPaint.setTextAlign(Paint.Align.CENTER);
        litTextPaint.setTextSize(height * 0.3f);

        glowTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        glowTextPaint.set(litTextPaint);
        glowTextPaint.setColor(nixieOrange);
        glowTextPaint.setMaskFilter(new BlurMaskFilter(height * 0.05f, BlurMaskFilter.Blur.NORMAL));

        unlitTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        unlitTextPaint.setTypeface(nixieFont);
        unlitTextPaint.setColor(Color.argb(50, 100, 100, 100));
        unlitTextPaint.setTextAlign(Paint.Align.CENTER);
        unlitTextPaint.setTextSize(height * 0.3f);

        // --- SETUP SHARP/FLAT INDICATOR PAINTS ---
        int indicatorRed = Color.parseColor("#F44336");

        sharpFlatPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        sharpFlatPaint.setTypeface(nixieFont);
        sharpFlatPaint.setColor(indicatorRed);
        sharpFlatPaint.setTextAlign(Paint.Align.CENTER);
        sharpFlatPaint.setTextSize(height * 0.15f);

        sharpFlatGlowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        sharpFlatGlowPaint.set(sharpFlatPaint);
        sharpFlatGlowPaint.setColor(indicatorRed);
        sharpFlatGlowPaint.setMaskFilter(new BlurMaskFilter(height * 0.03f, BlurMaskFilter.Blur.NORMAL));

        // --- SETUP IN-TUNE INDICATOR ---
        inTuneLightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        inTuneLightPaint.setColor(Color.parseColor("#4CAF50"));
        inTuneLightPaint.setStyle(Paint.Style.FILL);
    }

    @Override
    public void draw(Canvas c, GuitarTuner tuner, int frameNumber, int framesPerCycle) {
        // First, check if our paints have been initialized. This prevents crashes.
        if (backgroundPaint == null || litTextPaint == null) {
            return;
        }

        // 1. Draw the dark metal background
        c.drawRect(0, 0, width, height, backgroundPaint);

        // --- Define base positions ---
        float centerX = width / 2f;
        float centerY = height / 2f;
        float inTuneLightY = height * 0.15f;
        float inTuneLightRadius = height * 0.03f;

        // --- Determine the text to be displayed (e.g., "F2#") ---
        String noteText;
        if (tuner.isValid() && tuner.getTargetFrequency() > 0) {
            noteText = tuner.pitchLetterFromIndex(tuner.getTargetPitchIndex());
        } else {
            noteText = "---";
        }

        // --- STABLE TUBE SIZING ---
        // The tube size MUST be constant, based on the maximum possible width ("88").
        float textWidth = litTextPaint.measureText("88");
        float desiredTubeWidth = textWidth * 1.5f;
        float maxTubeWidth = width * 0.6f;
        float tubeWidth = Math.min(desiredTubeWidth, maxTubeWidth);
        float tubeHeight = litTextPaint.getTextSize() * 1.2f;
        float cornerRadius = width * 0.05f;

        // 2. DRAW THE GLASS TUBE (now a fixed size)
        RectF tubeRect = new RectF(centerX - tubeWidth / 2, centerY - tubeHeight / 2, centerX + tubeWidth / 2, centerY + tubeHeight / 2);
        c.drawRoundRect(tubeRect, cornerRadius, cornerRadius, glassTubePaint);
        c.drawRoundRect(tubeRect, cornerRadius, cornerRadius, glassGlarePaint);

        // --- Calculate the correct vertical center for the text ---
        float textCenterY = centerY - ((litTextPaint.descent() + litTextPaint.ascent()) / 2);

        // --- 3. DRAW EVERYTHING BASED ON TUNER STATE ---
        if (tuner.isValid() && tuner.getTargetFrequency() > 0) {
            // --- A REAL NOTE IS DETECTED ---

            // --- User's Alignment Strategy ---
            if (noteText.contains("#")) {
                // For sharp notes like "F2#".
                // Separate the note ("F2") from the sharp ("#").
                String mainNotePart = noteText.substring(0, noteText.length() - 1); // "F2"
                String sharpPart = "#";

                // Measure the width of the main part and the sharp.
                float mainPartWidth = litTextPaint.measureText(mainNotePart);
                float sharpWidth = litTextPaint.measureText(sharpPart);
                float totalWidth = mainPartWidth + sharpWidth;

                // Calculate positions to keep the whole thing centered.
                float mainPartX = centerX - (totalWidth / 2f) + (mainPartWidth / 2f);
                float sharpX = mainPartX + (mainPartWidth / 2f) + (sharpWidth / 2f);

                // Draw the "88" background aligned ONLY with the main part.
                c.drawText("88", mainPartX, textCenterY, unlitTextPaint);

                // Draw the main part and the sharp in their calculated positions.
                c.drawText(mainNotePart, mainPartX, textCenterY, glowTextPaint);
                c.drawText(mainNotePart, mainPartX, textCenterY, litTextPaint);
                c.drawText(sharpPart, sharpX, textCenterY, glowTextPaint);
                c.drawText(sharpPart, sharpX, textCenterY, litTextPaint);

            } else {
                // For non-sharp notes like "A4" or "G".
                // The background "88" will align perfectly.
                c.drawText("88", centerX, textCenterY, unlitTextPaint);
                c.drawText(noteText, centerX, textCenterY, glowTextPaint);
                c.drawText(noteText, centerX, textCenterY, litTextPaint);
            }

            // --- Draw the tuning indicators ---
            float sharpFlatY = centerY + (litTextPaint.getTextSize() * 0.2f);
            float indicatorXOffset = width * 0.4f;
            float sharpX = centerX + indicatorXOffset;
            float flatX = centerX - indicatorXOffset;

            double diffInCents = 1200 * Math.log(tuner.getDetectedFrequency() / tuner.getTargetFrequency()) / Math.log(2);
            final double INDICATOR_THRESHOLD = 5.0;

            if (tuner.isTuned()) {
                c.drawCircle(centerX, inTuneLightY, inTuneLightRadius, inTuneLightPaint);
            } else if (diffInCents < -INDICATOR_THRESHOLD) {
                c.drawText("♭", flatX, sharpFlatY, sharpFlatGlowPaint);
                c.drawText("♭", flatX, sharpFlatY, sharpFlatPaint);
            } else if (diffInCents > INDICATOR_THRESHOLD) {
                c.drawText("♯", sharpX, sharpFlatY, sharpFlatGlowPaint);
                c.drawText("♯", sharpX, sharpFlatY, sharpFlatPaint);
            }

        } else {
            // --- NO VALID NOTE DETECTED ---
            c.drawText(noteText, centerX, textCenterY, glowTextPaint);
            c.drawText(noteText, centerX, textCenterY, litTextPaint);
        }
    }
    @Override
    public void draw(Canvas c, GuitarTuner tuner) {
        draw(c, tuner, 0, 1);
    }
}