import { Injectable, inject } from '@angular/core';

import { CalculatorResult, WeightSizeRange, weightSizes } from '@models';
import { UtilitiesService } from '@services';

@Injectable({ providedIn: 'root' })
export class CalculatorService {
    private _utilitiesService = inject(UtilitiesService);

    public coeffKgLbs: number = this._utilitiesService.getCoeffKgLbs();
    public coeffFtM: number = this._utilitiesService.getCoeffFtM();

    private _getTableColumn(jumps: number): number {
        let column: number = 0;
        weightSizes[0].ranges.some((range: WeightSizeRange) => {
            if (jumps >= range.start && jumps <= range.end) {
                column = range.num - 1;
                return true;
            }
            return false;
        });

        return column;
    }

    private _getTableLine(weight: number): number {
        let line: number;
        const min = 60;
        const max = 110;
        if (weight < min) {
            line = min;
        } else if (weight > max) {
            line = max;
        } else {
            line = weight;
        }
        return line;
    }

    private _isInRange(nb: number, range: WeightSizeRange): boolean {
        return nb >= range.start && nb <= range.end;
    }

    private _reduceLimit(surface: number, percentOff: number): number {
        return Math.ceil((surface * (100 - percentOff)) / 100);
    }

    public canopySizeCalc(weight: number, jumps: number): CalculatorResult {
        /* DT48 - 13 mars 2020 */
        /* const maxRange = 2000; */
        /* DT48 - 08 février 2024 */
        const maxRange = 1600;
        const result: CalculatorResult = {
            min: 59,
            min11: 34,
        };
        if (jumps > maxRange) {
            return result;
        }
        const index: number = this._getTableLine(weight) - this._getTableLine(0);
        result.min = weightSizes[index].ranges[this._getTableColumn(jumps)].value!;
        result.min11 = this._reduceLimit(result.min, 11);

        return result;
    }

    public convertFeet2Meters(size: number): number {
        return size * this._utilitiesService.getCoeffFtM();
    }

    public getCanopySizes(weight: number, reduce = false): number[] {
        if (weight < 60) {
            weight = 60;
        }
        if (weight > 110) {
            weight = 110;
        }
        const line = weight - this._getTableLine(0);
        const data = weightSizes[line];
        if (reduce) {
            return data.ranges.map((range: WeightSizeRange): number => {
                return Math.ceil((range.value! * (100 - 11)) / 100);
            });
        } else {
            return data.ranges.map((range: WeightSizeRange): number => {
                return range.value!;
            });
        }
    }

    public getCharge(canopySize: number, nakedWeight: number, equipementWeight: number): number {
        return ((nakedWeight + equipementWeight) * this.coeffKgLbs) / canopySize;
    }

    public getRangeNum(jumps: number): number {
        const data: WeightSizeRange[] = weightSizes[0].ranges;
        let num: number = 1;
        /* DT48 - 13 mars 2020 */
        /* const maxRange = 2000; */
        /* DT48 - 08 février 2024 */
        const maxRange = 1600;
        data.some((range: WeightSizeRange): boolean => {
            if (jumps >= range.start && jumps <= range.end) {
                num = range.num;
                return true;
            } else if (jumps > maxRange) {
                num = 9;
                return true;
            }
            return false;
        });
        return num;
    }

    public getStateColor(values: CalculatorResult): string {
        let color: string = 'danger';
        if (values.current! >= values.min11 && values.current! < values.min) {
            color = 'warning';
        }
        if (values.current! >= values.min) {
            color = 'success';
        }

        return color;
    }
}
