package id.co.gtc.erhacam;

import FTP.FTPCheck;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import lombok.val;
import org.bytedeco.javacv.VideoInputFrameGrabber;
import org.tinylog.Logger;

import java.io.File;
import java.util.Objects;

import static Config.SomeCodes.*;

public class SettingView {
    @FXML
    private ComboBox<String> CameraLeft90;
    @FXML
    private ComboBox<String> CameraLeft45;
    @FXML
    private ComboBox<String> CameraCenter;
    @FXML
    private ComboBox<String> CameraRight45;
    @FXML
    private ComboBox<String> CameraRight90;

    @FXML
    private TextField FTPHost;
    @FXML
    private TextField FTPPort;
    @FXML
    private TextField FTPUser;
    @FXML
    private TextField FTPPass;
    @FXML
    private TextField FTPPath;

    @FXML
    private TextField Sharpness;

    @FXML
    private TextField PhotoDirectoryPath;

    @FXML
    private CheckBox MirrorCamera;

    @FXML
    private CheckBox FlipCamera;



    final FileChooser jfc = new FileChooser();

    String[] cameranames = null;

    @FXML
    private TextField cascadeMinSize;

    @FXML
    private TextField cascadeScaleFactor;

    @FXML
    private TextField cascadeMaxSize;

    @FXML
    private void ChangePhotoDirectoryPath(){
        DirectoryChooser dc = new DirectoryChooser();
        dc.setTitle("Select Directory");
        String path = dc.showDialog(null).getAbsolutePath();

        config.SetPhotoDirectory(path);
        config.Save();
        PhotoDirectoryPath.setText(path);
    }

    @FXML
    private void SharpnessApply(){
        String str = Sharpness.getText();
        if (ValidDouble(str)){
            config.setSharpnessThreshold(Double.parseDouble(str));
            config.Save();
        } else {
            ShowAlert(Alert.AlertType.ERROR, "Sharpness Setting Error", "Sharpness Setting Error", "Sharpness Setting must be a number");
        }
    }

    @FXML
    private void CascadeSettingApply(){

        String minsize = cascadeMinSize.getText();
        String scalefactor = cascadeScaleFactor.getText();
        String maxsize = cascadeMaxSize.getText();

        if (ValidString(minsize)){
            if (ValidString(maxsize)){
                if (ValidString(scalefactor)){
                    try{
                        int min = Integer.parseInt(minsize);
                        double scale = Double.parseDouble(scalefactor);
                        int max = Integer.parseInt(maxsize);
                        if (scale> 1.0){
                            if (min>0){
                                if (max>min){
                                    config.setCascadeMaxSize(max);
                                    config.setCascadeMinSize(min);
                                    config.setCascadeScaleFactor(scale);
                                    config.Save();

                                    Detectors.setFaceMaxSize(max);
                                    Detectors.setFaceMinSize(min);
                                    Detectors.setScaleFactor(scale);
                                    ShowAlert(Alert.AlertType.INFORMATION, "Cascade Setting", "Cascade Setting Saved", "Cascade Setting Saved Successfully");

                                } else show_cascade_alert("Max Size must be greater than Min Size");
                            } else show_cascade_alert("Min Size must be greater than 0");
                        } else show_cascade_alert("Scale Factor must be greater than 1.0");
                    } catch (NumberFormatException e){
                        show_cascade_alert("Min Size, Scale Factor, and Max Size must be a number");
                    }
                } else show_cascade_alert("Scale Factor must not empty");
            } else show_cascade_alert("Max Size must not empty");
        } else show_cascade_alert("Min Size must not empty");


    }

    private void show_cascade_alert(String content){
        ShowAlert(Alert.AlertType.ERROR, "Cascade Setting Error", "Cascade Setting Error", content);
    }

    @FXML
    public void initialize(){
        FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter("Audio File", "wav","mp3");
        jfc.setSelectedExtensionFilter(filter);
        jfc.setTitle("Select Audio File");

        try{
            cameranames = VideoInputFrameGrabber.getDeviceDescriptions();
            Logger.info("Found "+cameranames.length+" Cameras");
        } catch (Exception e){
            Logger.error("Unable to detect Cameras, Msg : "+e.getMessage());
        }

        MirrorCamera.selectedProperty().addListener(((observable, oldValue, newValue) -> {
            System.out.println("Mirror option changed to : "+newValue);
            config.setMirrorCamera(newValue);
            config.Save();
        }));

        FlipCamera.selectedProperty().addListener((observable, oldValue, newValue) -> {
            System.out.println("Flip option changed to : "+newValue);
            config.setFlipCamera(newValue);
            config.Save();
        });


        Platform.runLater(()->{

            CameraLeft90.getItems().clear();
            CameraLeft45.getItems().clear();
            CameraCenter.getItems().clear();
            CameraRight45.getItems().clear();
            CameraRight90.getItems().clear();

            CameraLeft90.getItems().add("");
            CameraLeft45.getItems().add("");
            CameraCenter.getItems().add("");
            CameraRight45.getItems().add("");
            CameraRight90.getItems().add("");

            for(String camera: cameranames){
                Logger.info("adding camera : "+camera+" to camera list");
                CameraLeft90.getItems().add(camera);
                CameraLeft45.getItems().add(camera);
                CameraCenter.getItems().add(camera);
                CameraRight45.getItems().add(camera);
                CameraRight90.getItems().add(camera);
            }

            CameraLeft90.setValue(config.getCameraLeft90());
            CameraLeft45.setValue(config.getCameraLeft45());
            CameraCenter.setValue(config.getCameraCenter());
            CameraRight45.setValue(config.getCameraRight45());
            CameraRight90.setValue(config.getCameraRight90());

            FTPHost.setText(config.getFTPHost());
            FTPPort.setText(config.getFTPPort());
            FTPUser.setText(config.getFTPUser());
            FTPPass.setText(config.getFTPPass());
            FTPPath.setText(config.getFTPPath());

            PhotoDirectoryPath.setText(config.getPhotoDirectory());

            cascadeScaleFactor.setText(String.valueOf(config.getCascadeScaleFactor()));
            cascadeMinSize.setText(String.valueOf(config.getCascadeMinSize()));
            cascadeMaxSize.setText(String.valueOf(config.getCascadeMaxSize()));

            MirrorCamera.setSelected(config.isMirrorCamera());
            FlipCamera.setSelected(config.isFlipCamera());

            Sharpness.setText(String.valueOf(config.getSharpnessThreshold()));

        });
    }

    public void Unload(){
        config.Save();
    }

    @FXML
    private void ApplyCameraLeft90(){
        config.SetCameraLeft90(CameraLeft90.getValue());
    }

    @FXML
    private void ApplyCameraLeft45(){
        config.SetCameraLeft45(CameraLeft45.getValue());
    }

    @FXML
    private void ApplyCameraFront(){
        config.SetCameraCenter(CameraCenter.getValue());
    }

    @FXML
    private void ApplyCameraRight45(){
        config.SetCameraRight45(CameraRight45.getValue());
    }

    @FXML
    private void ApplyCameraRight90(){
        config.SetCameraRight90(CameraRight90.getValue());
    }

    @FXML
    private void SaveFTP(){
        boolean passive = false;
        FTPCheck ftp = new FTPCheck(FTPHost.getText(),Integer.parseInt(FTPPort.getText()),FTPUser.getText(),FTPPass.getText(),FTPPath.getText(), passive);
        if (ftp.IsCorrect()){

            config.SetFTPHost(FTPHost.getText());
            config.SetFTPPort(FTPPort.getText());
            config.SetFTPUser(FTPUser.getText());
            config.SetFTPPass(FTPPass.getText());
            config.SetFTPPath(FTPPath.getText());

            ShowAlert(Alert.AlertType.INFORMATION, "FTP Configuration", "FTP Configuration Saved", "FTP Configuration Saved Successfully");
        } else ShowAlert(Alert.AlertType.ERROR, "FTP Error", "FTP Configuration Error", "FTP Configuration is incorrect, please check your FTP Configuration");

    }
}
