import dotenv from "dotenv";
dotenv.config({ path: ".env" });

import express, { Application, Request, Response } from "express";
import pg from "./database/pg";
import { PoolClient } from "pg";

const app: Application = express();
const port: number = parseInt(process.env.PORT as string) || 3000;

//Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

//Setting up for EJS
app.set("views", `./src/views`);
app.set("view engine", "ejs");

//Static route
app.use(express.static(`${__dirname}/../public`));

//check and send index ejs
//Query postgres database to get all todos (async await)
app.get("/", (_req: Request, res: Response): void => {
	pg.query("SELECT * FROM todos", (err: Error, result: any) => {
		if (err) {
			console.log("Error querying todos", err);
			res.status(500).send("Internal Server Error");
			return;
		}

		// Extract all rows from the database
		const todos = result.rows.map((row: { todo: string }) => row.todo);

		res.render("index", {
			todos, // Pass todos to the template
		});
	});
});

app.post("/form-action", (req: Request, res: Response): void => {
	const todo: string = req.body.todo;

	//query postgres to insert todo, $1 is a placeholder for the value of todo
	pg.query("INSERT INTO todos (todo) VALUES ($1)", [todo], (err: Error) => {
		if (err) {
			console.log("Error inserting todo", err);
			return;
		}

		console.log(`Inserted ${todo} successfully`);
	});

	res.redirect("/");
});

app.delete("/todo", (req: Request, res: Response): void => {
	const { todo } = req.body;

	pg.query("DELETE FROM todos WHERE todo = $1", [todo], (err: Error) => {
		if (err) {
			console.log("Error deleting todo", err);
			return;
		}

		res.status(200).send({ message: "Todo deleted successfully" });
	});
});

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

//Connect to postgres, postgres initialization
pg.connect(
	(err: Error | undefined, client: PoolClient | undefined, done): void => {
		if (err) {
			console.log("Error connecting to pg", err);
			return;
		}
		if (!client) {
			console.log("No client found");
			return;
		}

		// Attempt to Query (asking the database, to check it is connected), it might take us a while and we wont be able to run the rest of the program
		// Async this
		client.query("SELECT NOW()", async (err: Error, _result: any) => {
			if (err) {
				console.log("Error querying pg", err);
				return;
			}

			//Create the table if no error (await)
			//Query statement, instruction "CREATE TABLE IF NOT EXISTS todos", there is a whole table, https://www.w3schools.com/sql/default.asp
			//VACHAR is a string, 255 is the max length of the string
			await client.query(
				`CREATE TABLE IF NOT EXISTS todos (
				todo VARCHAR(255) NOT NULL
			)`,
				(err: Error) => {
					console.log("Error creating table", err);
					return;
				}
			);

			console.log("Connected to postgres successfully");
			done();
		});
	}
);
