import javax.swing.*;
import java.awt.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class GeneGuiApp {
    private JFrame frame;
    private JTextField inputField;
    private JLabel fileStatusLabel;
    private JEditorPane outputDisplay;
    private File selectedFile;

    public GeneGuiApp() {
        createAndShowGUI();
    }

    private void createAndShowGUI() {
        frame = new JFrame("Central Dogma Bio-Processor");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(1000, 650);

        JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
        mainPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
        mainPanel.setBackground(new Color(245, 247, 250));

        // Control Header Row Panel
        JPanel controlPanel = new JPanel();
        controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.X_AXIS));
        controlPanel.setOpaque(false);

        inputField = new JTextField();
        inputField.setFont(new Font("Monospaced", Font.PLAIN, 14));
        inputField.setMaximumSize(new Dimension(300, 35));
        inputField.setPreferredSize(new Dimension(200, 35));

        JButton processTextButton = new JButton("Process Text");
        styleButton(processTextButton, new Color(70, 130, 180));

        fileStatusLabel = new JLabel("No file selected ");
        fileStatusLabel.setFont(new Font("SansSerif", Font.ITALIC, 12));
        fileStatusLabel.setForeground(Color.GRAY);

        JButton fileChooserButton = new JButton("Choose File");
        styleButton(fileChooserButton, new Color(108, 117, 125));

        JButton processFileButton = new JButton("Process File");
        styleButton(processFileButton, new Color(40, 167, 69));

        controlPanel.add(inputField);
        controlPanel.add(Box.createHorizontalStrut(8));
        controlPanel.add(processTextButton);
        controlPanel.add(Box.createHorizontalStrut(20));
        controlPanel.add(fileStatusLabel);
        controlPanel.add(Box.createHorizontalStrut(8));
        controlPanel.add(fileChooserButton);
        controlPanel.add(Box.createHorizontalStrut(8));
        controlPanel.add(processFileButton);

        // Main Display Engine
        outputDisplay = new JEditorPane();
        outputDisplay.setContentType("text/html");
        outputDisplay.setEditable(false);
        outputDisplay.setBackground(Color.WHITE);
        
        JScrollPane scrollPane = new JScrollPane(outputDisplay);
        scrollPane.setBorder(BorderFactory.createLineBorder(new Color(210, 215, 225)));

        mainPanel.add(controlPanel, BorderLayout.NORTH);
        mainPanel.add(scrollPane, BorderLayout.CENTER);

        processTextButton.addActionListener(e -> executeProcessingPipeline(inputField.getText().trim()));

        fileChooserButton.addActionListener(e -> {
            // Instantiate at current working project directory context path "."
            JFileChooser fileChooser = new JFileChooser(".");
            if (fileChooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
                selectedFile = fileChooser.getSelectedFile();
                fileStatusLabel.setText(selectedFile.getName() + " ");
                fileStatusLabel.setForeground(new Color(40, 167, 69));
            }
        });

        processFileButton.addActionListener(e -> {
            if (selectedFile == null) {
                outputDisplay.setText("<html><body style='font-family:sans-serif;padding:15px;color:red;'><b>Error:</b> Choose a file first!</body></html>");
                return;
            }
            String extracted = parseFastaFile(selectedFile);
            if (!extracted.isEmpty()) {
                inputField.setText(extracted);
                executeProcessingPipeline(extracted);
            }
        });

        frame.add(mainPanel);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        renderWelcomeScreen();
    }

    private void styleButton(JButton button, Color bg) {
        button.setFont(new Font("SansSerif", Font.BOLD, 12));
        button.setBackground(bg);
        button.setForeground(Color.WHITE);
        button.setOpaque(true);
        button.setBorderPainted(false);
        button.setFocusPainted(false);
        button.setContentAreaFilled(true);
    }

    private String parseFastaFile(File file) {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = br.readLine()) != null) {
                line = line.trim();
                if (line.startsWith(">") || line.isEmpty()) continue;
                sb.append(line.replaceAll("\\s|\\d", ""));
            }
        } catch (IOException ex) { return ""; }
        return sb.toString().toUpperCase();
    }

    private void executeProcessingPipeline(String rawDna) {
        if (rawDna == null || rawDna.isEmpty()) return;
		
		// GURANTEES absolute sanitization for manual text box entry/copy-pastes
    	rawDna = rawDna.replaceAll("\\s|\\d", "").toUpperCase();

        // Invoke student business operations layers
        String mrna = GeneUtils.transcribeToMrna(rawDna);
        int startIndex = GeneUtils.findStartCodonIndex(mrna);
        String aminoAcids = GeneUtils.translateMrna(mrna, startIndex);

        // Find stop index independently for layout visualization highlights
        int stopIndex = -1;
        if (startIndex != -1) {
            for (int i = startIndex; i <= mrna.length() - 3; i += 3) {
                String codon = mrna.substring(i, i + 3);
                if (codon.equals("UAA") || codon.equals("UAG") || codon.equals("UGA")) {
                    stopIndex = i;
                    break;
                }
            }
        }

        // Generate dot-separated tracking view for mRNA codons
        StringBuilder mrnaFormatted = new StringBuilder();
        if (startIndex == -1) {
            mrnaFormatted.append(mrna);
        } else {
            mrnaFormatted.append(mrna, 0, startIndex);
            
            int current = startIndex;
            boolean insideCodingRegion = true;
            
            while (current <= mrna.length() - 3) {
                String codon = mrna.substring(current, current + 3);
                
                if (current == startIndex) {
                    mrnaFormatted.append("<span style='background-color:#ABEBC6; font-weight:bold; border:1px solid #27AE60; padding:1px;'>AUG</span>");
                } else if (codon.equals("UAA") || codon.equals("UAG") || codon.equals("UGA")) {
                    mrnaFormatted.append("<span style='background-color:#F5B7B1; font-weight:bold; border:1px solid #C0392B; padding:1px;'>").append(codon).append("</span>");
                    insideCodingRegion = false;
                    current += 3;
                    if (current < mrna.length()) mrnaFormatted.append(".");
                    break; 
                } else {
                    if (insideCodingRegion) {
                        mrnaFormatted.append("<span style='background-color:#FCF3CF;'>").append(codon).append("</span>");
                    } else {
                        mrnaFormatted.append(codon);
                    }
                }
                
                current += 3;
                if (current <= mrna.length() - 3) {
                    mrnaFormatted.append(".");
                }
            }
            
            if (current < mrna.length()) {
                if (current > startIndex) mrnaFormatted.append(".");
                mrnaFormatted.append(mrna.substring(current));
            }
        }

        StringBuilder html = new StringBuilder();
        html.append("<html><body style='font-family:sans-serif; padding:10px; color:#2C3E50;'>");
        html.append("<h2 style='color:#2980B9; margin-top:0;'>Genetics Pipeline Trace Analysis</h2>");
        html.append("<hr style='border: 0; height: 1px; background: #D6DBDF; margin-bottom:12px;'>");

        // 1. DNA panel with precise block dimension and scrolling constraints
        html.append("<p style='margin:4px 0;'><b>Original 3' &rarr; 5' DNA Template Strand:</b></p>");
        html.append("<div style='font-family:monospace; font-size:13px; background:#F8F9F9; padding:10px; border-left:4px solid #BDC3C7; width:920px; min-width:920px; max-width:920px; overflow-x:scroll; overflow-y:hidden; white-space:nowrap;'>")
            .append(rawDna).append("</div><br>");

        // 2. mRNA panel with precise block dimension and scrolling constraints
        html.append("<p style='margin:4px 0;'><b>Transcribed 5' &rarr; 3' mRNA Strand (Triplet Track):</b></p>");
        html.append("<div style='font-family:monospace; font-size:13px; background:#F8F9F9; padding:10px; border-left:4px solid #E67E22; width:920px; min-width:920px; max-width:920px; overflow-x:scroll; overflow-y:hidden; white-space:nowrap;'>")
            .append(mrnaFormatted).append("</div>");
        
        // Status Messaging Output Logs
        if (startIndex == -1) {
            html.append("<p style='font-size:11px; color:#C0392B; margin-top:4px;'>⚠️ Warning: findStartCodonIndex returned -1. Translation step skipped.</p><br>");
        } else if (stopIndex == -1) {
            html.append("<p style='font-size:11px; color:#D35400; margin-top:4px;'>⚠️ Warning: No structural STOP codon encountered in reading frame. translateMrna returned null.</p><br>");
        } else {
            html.append("<p style='font-size:11px; color:#27AE60; margin-top:4px;'>✔ Valid transcription and translation parameters mapped cleanly.</p><br>");
        }

        // 3. Polypeptide Panel: ONLY rendered and shown if the translation was successful (!= null)
        if (aminoAcids != null) {
            html.append("<p style='margin:4px 0;'><b>Translated Polypeptide Chain:</b></p>");
            html.append("<div style='font-family:sans-serif; font-size:14px; font-weight:bold; background:#EAFAF1; color:#145A32; padding:12px; border:1px solid #A9DFBF; border-radius:4px; width:920px; min-width:920px; max-width:920px; overflow-x:scroll; overflow-y:hidden; white-space:nowrap;'>");
            html.append("&nbsp;[N-Terminus]&nbsp; &rArr; &nbsp;").append(aminoAcids).append("&nbsp; &rArr; &nbsp;[C-Terminus]");
            html.append("</div>");
        }

        html.append("</body></html>");
        outputDisplay.setText(html.toString());
    }

    private void renderWelcomeScreen() {
        outputDisplay.setText("<html><body style='font-family:sans-serif; padding:20px; color:#34495E;'><h3>Bio-Processor Workspace Ready</h3></body></html>");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new GeneGuiApp());
    }
}