// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
/*
hi hello this is for future me can ids 1-12 and 17 are taken up thus far 
13 the intake motor,
14 the arm, 
15 the feeder,
16 the first shooter motor, and
18 the second shooter motor
*/
package frc.robot;

import edu.wpi.first.math.util.Units;
import com.revrobotics.spark.FeedbackSensor;
import com.revrobotics.spark.config.SparkFlexConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import com.revrobotics.spark.config.SparkMaxConfig;
import edu.wpi.first.math.geometry.Rectangle2d;
import edu.wpi.first.math.geometry.Translation2d;
import edu.wpi.first.math.geometry.Translation3d;
import frc.robot.math.PolynomialRegression;
import swervelib.math.Matter;

/**
 * The Constants class provides a convenient place for teams to hold robot-wide numerical or boolean constants. This
 * class should not be used for any other purpose. All constants should be declared globally (i.e. public static). Do
 * not put anything functional in this class.
 *
 * <p>It is advised to statically import this class (or one of its inner classes) wherever the
 * constants are needed, to reduce verbosity.
 */
public final class Constants
{
  public static final double ROBOT_MASS = (50) * 0.453592; // 32lbs * kg per pound HI HELLO FUTURE ME I HAVE TO CHANGE THIS THANK YOU
  public static final Matter CHASSIS    = new Matter(new Translation3d(0, 0, Units.inchesToMeters(8)), ROBOT_MASS);
  public static final double LOOP_TIME  = 0.13; //s, 20ms + 110ms sprk max velocity lag
  public static final double MAX_SPEED  = Units.feetToMeters(17);
  public static final Rectangle2d ROBOT_PERIMETER = new Rectangle2d(new Translation2d(), new Translation2d(Units.inchesToMeters(27), Units.inchesToMeters(27)));
  public static final double BUMPER_RADIUS = Units.inchesToMeters(3);
  public static final double ROBOTFULLRADIUS = (Math.sqrt(Math.pow(ROBOT_PERIMETER.getXWidth(), 2) + Math.pow(ROBOT_PERIMETER.getYWidth(), 2))/2)+BUMPER_RADIUS;
  // Maximum speed of the robot in meters per second, used to limit acceleration.

//  public static final class AutonConstants
//  {
//
//    public static final PIDConstants TRANSLATION_PID = new PIDConstants(0.7, 0, 0);
//    public static final PIDConstants ANGLE_PID       = new PIDConstants(0.4, 0, 0.01);
//  }
  public static final class Shooter
  {
    public static final int MOTOR_ID = 16;
    public static final int MOTOR_IDSLAVE = 18;
    public static final SparkFlexConfig MOTORCONFIG = new SparkFlexConfig();
    static 
    { 
      MOTORCONFIG
      .idleMode(IdleMode.kCoast)
      .smartCurrentLimit(20); 

      MOTORCONFIG.closedLoop
                    .feedbackSensor(FeedbackSensor.kPrimaryEncoder)
                    // These are example gains you may need to them for your own robot!
                    .pid(0, 0, 0)//(0.0001, 0.000001, 0.01)
                    .outputRange(-1, 1);
                    // Enable PID wrap around for the turning motor. This will allow the PID
                    // controller to go through 0 to get to the setpoint i.e. going from 350 degrees
                    // to 10 degrees will go through 0 rather than the other direction which is a
                    // longer route.
      MOTORCONFIG.closedLoop.feedForward
                    .kV(0.004); // UNTESTED UNTESTED UNTESTED UNTESTED UNTESTED UNTESTED UNTESTED UNTESTED UNTESTED UNTESTED UNTESTED 
    }
    public static final double ASFASTASSAFERPM = 3000; // fast as safe
    public static final double ABSMINDISTANCE = 90; //cm
    public static final double ABSMAXDISTANCE = 130; //cm
    public static final double MINDISTANCEFOR80P = 100; //cm
    public static final double MAXDISTANCEFOR80P = 120; //cm
    public static final PolynomialRegression kFlywheelAutoAimPolynomial;
    public static final double[][] kFlywheelDistanceRpmValues = { // placeholder for now but should be in the format of {meters from center of hub, rpm that hits there}
      { 0.90, 2890.0 },
      { 0.95, 2940.0 },
      { 1.00, 2990.0 },
      { 1.05, 3025.0 },
      { 1.10, 3075.0 },
      { 1.15, 3125.0 },
      { 1.20, 3175.0 },
      { 1.25, 3225.0 },
      { 1.30, 3275.0 },
    };

    static {
      kFlywheelAutoAimPolynomial = new PolynomialRegression(kFlywheelDistanceRpmValues, 2);
    }
  }
  public static final class Intake
  {
    public static final double ARMGEARRATIO = (4/1)*(21/18); // 18t pulley on the motor through 4:1 gearbox and 21t pulley on the arm
    public static final SparkMaxConfig ARMMOTORCONFIG = new SparkMaxConfig();
    static 
    { 
      ARMMOTORCONFIG
      .idleMode(IdleMode.kCoast)
      .smartCurrentLimit(20); 

      ARMMOTORCONFIG.closedLoop
                    .feedbackSensor(FeedbackSensor.kPrimaryEncoder)
                    // These are example gains you may need to them for your own robot!
                    .pid(0.5, 0.001, 1)
                    .outputRange(-1, 1)
                    .positionWrappingEnabled(true);
      ARMMOTORCONFIG.encoder
                    .positionConversionFactor(ARMGEARRATIO);
    }
    public static final SparkMaxConfig INTAKEMOTORCONFIG = new SparkMaxConfig();
    static 
    { 
      INTAKEMOTORCONFIG
      .idleMode(IdleMode.kCoast)
      .smartCurrentLimit(40); 

      INTAKEMOTORCONFIG.closedLoop
                    .feedbackSensor(FeedbackSensor.kPrimaryEncoder)
                    // These are example gains you may need to them for your own robot!
                    .pid(1, 0, 0)
                    .outputRange(-1, 1);
    }
    public static final int ENCODER_PORT = 0;
    public static final int ARMMOTOR_ID = 14;
    public static final int INTAKEMOTOR_ID = 13;
    public static final double INTAKESPEED = 1;
    public static final double INTAKEFEEDERMODESPEED = -0.5;
    public static final double ABSOLUTEOFFSET = -((1-0.420)-0.01);
    public static final double ABSOLUTEMAXANGLE = 45/360;
    public static final double ABSOLUTEMINANGLE = 0/360;
    public static final double SHOOTINGANGLE = 40/360;
    public static final double INTAKEANGLE = 0/360;
    public static final double BUMP_HYSTERESIS = 0.2;
  }
  public static final class Feeder
  {
    public static final int MOTOR_ID = 15;
    public static final SparkMaxConfig MOTORCONFIG = new SparkMaxConfig();
    static 
    { 
      MOTORCONFIG
      .idleMode(IdleMode.kBrake)
      .smartCurrentLimit(40)
      .inverted(true); 

      MOTORCONFIG.closedLoop
                    .feedbackSensor(FeedbackSensor.kPrimaryEncoder)
                    // These are example gains you may need to them for your own robot!
                    .pid(1, 0, 0)
                    .outputRange(-1, 1);
                    // Enable PID wrap around for the turning motor. This will allow the PID
                    // controller to go through 0 to get to the setpoint i.e. going from 350 degrees
                    // to 10 degrees will go through 0 rather than the other direction which is a
                    // longer route.
    }
  }
  public static final class FieldMiscellaneous {
    public static final Rectangle2d gBUMPS[] = { // rect2d array of all four bumps relative to the wpilib blue orgin (although orgin shouldn't matter as they are symmetrical in x) in meters. source: https://firstfrc.blob.core.windows.net/frc2026/FieldAssets/2026-field-dimension-dwgs.pdf
      new Rectangle2d(new Translation2d(Units.inchesToMeters(182.11-(47/2)),          Units.inchesToMeters(50.59+12            )),
                      new Translation2d(Units.inchesToMeters(182.11+(47/2)),          Units.inchesToMeters(50.59+12+73         ))),

      new Rectangle2d(new Translation2d(Units.inchesToMeters(182.11-(47/2)),          Units.inchesToMeters(317.688-(50.59+12   ))),
                      new Translation2d(Units.inchesToMeters(182.11+(47/2)),          Units.inchesToMeters(317.688-(50.59+12+73)))),

      new Rectangle2d(new Translation2d(Units.inchesToMeters(651.22-(182.11-(47/2))), Units.inchesToMeters(50.59+12            )),
                      new Translation2d(Units.inchesToMeters(651.22-(182.11+(47/2))), Units.inchesToMeters(50.59+12+73         ))),

      new Rectangle2d(new Translation2d(Units.inchesToMeters(651.22-(182.11-(47/2))), Units.inchesToMeters(317.688-(50.59+12   ))),
                      new Translation2d(Units.inchesToMeters(651.22-(182.11+(47/2))), Units.inchesToMeters(317.688-(50.59+12+73))))
    };
    public static final Translation3d gBLUALLIANCEHUB = new Translation3d(Units.inchesToMeters(182.11), Units.inchesToMeters(317.688/2), Units.inchesToMeters(72)); // translation3d of the blue alliance hub relative
    public static final Translation3d gREDALLIANCEHUB = new Translation3d(Units.inchesToMeters(651.22-182.11), Units.inchesToMeters(317.688/2), Units.inchesToMeters(72)); // translation3d of the red alliance hub relative
  }
  public static final class DrivebaseConstants
  {

    // Hold time on motor brakes when disabled
    public static final double WHEEL_LOCK_TIME = 10; // seconds
  }

  public static class OperatorConstants
  {

    // Joystick Deadband
    public static final double DEADBAND        = 0.1;
    public static final double LEFT_Y_DEADBAND = 0.1;
    public static final double RIGHT_X_DEADBAND = 0.25;
    public static final double TURN_CONSTANT    = 6;
  }
}
