use std::f64::consts::PI;
use num_complex::Complex;

use crate::filters::iir::lib::hyperbolic::{arcsinh, cosh, sinh};

pub fn cheb1ap(n: usize, rp: f64) -> Result<(Vec<Complex<f64>>, Vec<Complex<f64>>, f64), String> {
    if n == 0 {
        let k = 10f64.powf(-rp / 20.0);
        return Ok((vec![], vec![], k));
    }

    let z = vec![];
    let eps = ((10f64.powf(0.1 * rp) - 1.0) as f64).sqrt();
    let mu = arcsinh(1.0 / eps) / n as f64;

    let m: Vec<i32> = (-((n as i32) - 1)..=(n as i32 - 1))
        .step_by(2)
        .collect();
    let mut p = Vec::with_capacity(n);
    for &mi in m.iter() {
        let theta = PI * mi as f64 / (2.0 * n as f64);
        let pole = -Complex::new(sinh(mu) * theta.cos(), cosh(mu) * theta.sin());
        p.push(pole);
    }

    let mut k = p.iter().fold(1.0, |acc, x| acc * (-x).norm());
    if n % 2 == 0 {
        k /= (1.0 + eps * eps).sqrt();
    }

    Ok((z, p, k))
}