from __future__ import annotations
from math import sqrt
from .point import Point
from .line import Line


def foot_of_perpendicular(p: Point, line: Line) -> Point:
    """
    Foot of perpendicular from point P(x1, y1) to line ax + by + c = 0.

    Formula:
      H = ( x1 - a*(ax1+by1+c)/(a^2+b^2),
            y1 - b*(ax1+by1+c)/(a^2+b^2) )
    """
    a, b, c = line.a, line.b, line.c
    x1, y1 = p.x, p.y

    denom = a * a + b * b
    t = (a * x1 + b * y1 + c) / denom
    x = x1 - a * t
    y = y1 - b * t
    return Point(x, y)


def perpendicular_distance(p: Point, line: Line) -> float:
    """
    Perpendicular distance of P(x1, y1) from line ax + by + c = 0:

        |ax1 + by1 + c| / sqrt(a^2 + b^2)
    """
    a, b, c = line.a, line.b, line.c
    return abs(a * p.x + b * p.y + c) / sqrt(a * a + b * b)


def reflect_point(p: Point, line: Line) -> Point:
    """
    Image of P(x1, y1) in line ax + by + c = 0.

    Reflection formula:
        P' = P - 2 * ((ax1 + by1 + c) / (a^2 + b^2)) * (a, b)
    """
    a, b, c = line.a, line.b, line.c
    x1, y1 = p.x, p.y
    denom = a * a + b * b
    t = (a * x1 + b * y1 + c) / denom
    xr = x1 - 2 * a * t
    yr = y1 - 2 * b * t
    return Point(xr, yr)
