package com.dynamicwallpaper.gui;

import com.dynamicwallpaper.core.SunPositionUtil;
import com.dynamicwallpaper.model.WallpaperImage;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.util.List;

/**
 * Lets the user add any number of images and assign each one a sun altitude
 * and azimuth (in degrees). "Auto-Distribute" fills in a reasonable
 * sunrise-to-sunset-to-night arc automatically; users can still edit any
 * value by double-clicking its cell.
 */
public final class SolarPanel extends JPanel {

    private final SolarImageTableModel tableModel = new SolarImageTableModel();
    private final JTable table = new JTable(tableModel);

    public SolarPanel() {
        setLayout(new BorderLayout(8, 8));
        setBorder(BorderFactory.createEmptyBorder(16, 16, 16, 16));

        table.setRowHeight(44);
        table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        table.getColumnModel().getColumn(0).setMaxWidth(48);

        JLabel help = new JLabel(
                "<html>Add several images that represent the sun at different points in the day. "
                        + "Altitude is the sun's height above the horizon (-90 to 90, negative = night); "
                        + "azimuth is its compass direction (0 to 360). Check \"Light Ref.\" / \"Dark Ref.\" "
                        + "on the frames that best represent Light and Dark appearance.</html>");
        help.setBorder(BorderFactory.createEmptyBorder(0, 0, 8, 0));

        JPanel toolbar = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JButton addButton = new JButton("Add Images…");
        JButton removeButton = new JButton("Remove Selected");
        JButton clearButton = new JButton("Clear All");
        JButton upButton = new JButton("Move Up");
        JButton downButton = new JButton("Move Down");
        JButton autoButton = new JButton("Auto-Distribute Sun Positions");

        addButton.addActionListener(e -> addImages());
        removeButton.addActionListener(e -> removeSelected());
        clearButton.addActionListener(e -> tableModel.clear());
        upButton.addActionListener(e -> moveSelected(-1));
        downButton.addActionListener(e -> moveSelected(1));
        autoButton.addActionListener(e -> autoDistribute());

        toolbar.add(addButton);
        toolbar.add(removeButton);
        toolbar.add(clearButton);
        toolbar.add(upButton);
        toolbar.add(downButton);
        toolbar.add(autoButton);

        JPanel north = new JPanel(new BorderLayout());
        north.add(help, BorderLayout.NORTH);
        north.add(toolbar, BorderLayout.SOUTH);

        add(north, BorderLayout.NORTH);
        add(new JScrollPane(table), BorderLayout.CENTER);
    }

    public List<WallpaperImage> images() {
        return tableModel.images();
    }

    private void addImages() {
        JFileChooser chooser = new JFileChooser();
        chooser.setMultiSelectionEnabled(true);
        chooser.setFileFilter(new FileNameExtensionFilter(
                "Images", "png", "jpg", "jpeg", "tif", "tiff", "bmp", "gif", "heic"));
        if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            for (var file : chooser.getSelectedFiles()) {
                tableModel.add(new WallpaperImage(file));
            }
        }
    }

    private void removeSelected() {
        int[] rows = table.getSelectedRows();
        if (rows.length == 0) {
            return;
        }
        tableModel.removeRows(rows);
    }

    private void moveSelected(int delta) {
        int row = table.getSelectedRow();
        if (row < 0) {
            return;
        }
        tableModel.moveRow(row, row + delta);
        int newRow = row + delta;
        if (newRow >= 0 && newRow < table.getRowCount()) {
            table.setRowSelectionInterval(newRow, newRow);
        }
    }

    private void autoDistribute() {
        int count = tableModel.getRowCount();
        if (count < 2) {
            JOptionPane.showMessageDialog(this, "Add at least two images first.",
                    "Not enough images", JOptionPane.INFORMATION_MESSAGE);
            return;
        }
        List<SunPositionUtil.SunPosition> positions = SunPositionUtil.distribute(count);
        List<WallpaperImage> images = tableModel.images();
        for (int i = 0; i < count; i++) {
            images.get(i).setAltitude(positions.get(i).altitude());
            images.get(i).setAzimuth(positions.get(i).azimuth());
        }
        tableModel.fireTableDataChanged();
    }
}
