import express from "express";
import dotenv from "dotenv";
import cors from "cors";
import pkg from "pg";
const { Client } = pkg;
import bcrypt from "bcrypt";
import knex from "knex";
import jwt from "jsonwebtoken";

dotenv.config();

const postgres = knex({
  client: "pg",
  connection: process.env.LOCALDB_URL,
});

dotenv.config();

const jwtToken = process.env.JWT;
const port = process.env.PORT || 5000;
const app = express();
app.use(cors());
app.use("/img", express.static("./img"));
app.use(express.json());

app.get("/api/test", (_, res) => {
  res.json({ message: "Server connected to frontend" });
});

app.post("/api/login", async (req, res) => {
  const { username, password } = req.body;

  try {
    const user = await postgres("users").where({ username }).first();

    if (!user) {
      return res.status(401).json({ message: "Неверные учетные данные" });
    }

    const isPasswordValid = await bcrypt.compare(password, user.password);

    if (!isPasswordValid) {
      return res.status(401).json({ message: "Неверные учетные данные" });
    }

    const token = jwt.sign(
      {
        userId: user.id,
        username: user.username,
      },
      jwtToken,
      { expiresIn: "1h" }
    );

    res.status(200).json({ token });
  } catch (error) {
    console.error("Ошибка при логине:", error);
    res.status(500).json({ message: "Ошибка сервера" });
  }
});

app.get("/api/cards", async (req, res) => {
  try {
    const searchTerm = req.query.search ? req.query.search.toLowerCase() : "";

    let projectsQuery = postgres("projects").select("*");
    if (searchTerm) {
      projectsQuery = projectsQuery.where(function () {
        this.whereRaw("LOWER(title) LIKE ?", [`%${searchTerm}%`]).orWhereRaw(
          "LOWER(description) LIKE ?",
          [`%${searchTerm}%`]
        );
      });
    }
    const projects = await projectsQuery;

    const apiBaseUrl =
      process.env.LOCALSERVER ?? `https://server-ancient-grass-9030.fly.dev`;
    const projectsWithImgSrc = projects.map((project) => ({
      ...project,
      imgSrc: `${apiBaseUrl}${project.img_src}`,
    }));

    res.json(projectsWithImgSrc);
  } catch (error) {
    console.error("Error fetching projects:", error);
    res.status(500).json({ error: "Failed to fetch projects" });
  }
});

app.post("/api/signup", async (req, res) => {
  const { firstName, lastName, username, password, confirmPassword, age } =
    req.body;

  const errors = {};

  if (!firstName || firstName.trim().length < 3) {
    errors.firstName = "Имя должно содержать не менее 3 символов.";
  }

  if (!lastName || lastName.trim().length < 3) {
    errors.lastName = "Фамилия должна содержать не менее 3 символов.";
  }

  if (!username || username.trim().length < 3) {
    errors.username = "Имя пользователя должно содержать не менее 3 символов.";
  }

  if (!password) {
    errors.password = "Введите пароль.";
  } else {
    if (password.length < 4) {
      errors.password = "Пароль должен содержать не менее 4 символов.";
    }
    if (!/[a-zA-Z]/.test(password) || !/[0-9]/.test(password)) {
      errors.password =
        "Пароль должен содержать как минимум одну букву и одну цифру.";
    }
  }

  if (!confirmPassword) {
    errors.confirmPassword = "Пожалуйста, подтвердите пароль.";
  } else if (password !== confirmPassword) {
    errors.confirmPassword = "Пароли не совпадают.";
  }

  const ageNumber = Number(age);
  if (!age) {
    errors.age = "Укажите ваш возраст.";
  } else if (isNaN(ageNumber)) {
    errors.age = "Возраст должен быть числом.";
  } else if (ageNumber <= 0) {
    errors.age = "Возраст не может быть равен нулю или меньше.";
  }

  if (Object.keys(errors).length > 0) {
    return res.status(400).json({ errors });
  }

  try {
    const existingUser = await postgres("users").where({ username }).first();

    if (existingUser) {
      return res
        .status(400)
        .json({ errors: { username: "Такое имя пользователя уже занято." } });
    }

    const hashedPassword = await bcrypt.hash(password, 12);

    await postgres("users").insert({
      firstName,
      lastName,
      username,
      password: hashedPassword,
      age: ageNumber,
    });

    res.status(201).json({ message: "Пользователь успешно зарегистрирован" });
  } catch (error) {
    console.error("Ошибка при регистрации:", error);
    res.status(500).json({ message: "Ошибка сервера" });
  }
});

app.listen(port, () => console.log(`Server is running on port ${port}`));

const client = new Client({
  connectionString: process.env.LOCALDB_URL,
});

async function connectToDatabase() {
  try {
    await client.connect();
    console.log("Successfully connected to the database");
  } catch (error) {
    console.error("Error connecting to the database:", error);
  } finally {
    await client.end();
  }
}

connectToDatabase();

переведи все логи на сервере на английский