import { Role } from "@app/shared/types/roles";
import pool from "../db";
import { Member, MemberCardDetails, MemberLight, memberSettings, MemberState } from '@app/shared/types/member'

export async function getUserData(userID: number): Promise<Member> {
  const sql = `SELECT * FROM view_member_rank_unit_status_latest WHERE member_id = ?`;
  const res: Member = await pool.query(sql, [userID]);
  return res[0] ?? null;
}

export async function setUserState(userID: number, state: MemberState) {
  const sql = `UPDATE members
        SET state = ?
        WHERE id = ?;`;
  return await pool.query(sql, [state, userID]);
}

export async function getUserState(user: number): Promise<MemberState> {
  let out = await pool.query(`SELECT state FROM members WHERE id = ?`, [user]);
  return (out[0].state as MemberState);
}

export async function getMemberSettings(id: number): Promise<memberSettings> {
  const sql = `SELECT * FROM view_member_settings WHERE id = ?`;
  let out: memberSettings[] = await pool.query(sql, [id]);

  if (out.length != 1)
    throw new Error("Could not get user settings");

  return out[0];
}

export async function setUserSettings(id: number, settings: memberSettings) {
  const sql = `UPDATE view_member_settings SET
                displayName = ?
                WHERE id = ?;`;
  let result = await pool.query(sql, [settings.displayName, id])
}

export async function getMembersLite(ids: number[]): Promise<MemberLight[]> {
  const sql = `SELECT m.member_id AS id,
                  m.member_name AS username,
                  m.displayName,
                  u.color
              FROM view_member_rank_unit_status_latest m
                  LEFT JOIN units u ON u.name = m.unit
              WHERE member_id IN (?);`;
  const res: MemberLight[] = await pool.query(sql, [ids]);
  return res;
}

export async function getAllMembersLite(): Promise<MemberLight[]> {
  const sql = `SELECT m.member_id AS id,
                  m.member_name AS username,
                  m.displayName,
                  u.color
              FROM view_member_rank_unit_status_latest m
                  LEFT JOIN units u ON u.name = m.unit;`;

  const res: MemberLight[] = await pool.query(sql);
  return res;
}

export async function getMembersFull(ids: number[]): Promise<MemberCardDetails[]> {
  const sql = `
    SELECT m.*,
      COALESCE(
        JSON_ARRAYAGG(
          CASE
            WHEN r.id IS NOT NULL THEN JSON_OBJECT(
              'id', r.id,
              'name', r.name,
              'color', r.color,
              'description', r.description
            )
          END
        ),
        JSON_ARRAY()
      ) AS roles
    FROM view_member_rank_unit_status_latest m
    LEFT JOIN members_roles mr ON m.member_id = mr.member_id
    LEFT JOIN roles r ON mr.role_id = r.id
    WHERE m.member_id IN (?)
    GROUP BY m.member_id;
  `;

  const rows: any[] = await pool.query(sql, [ids]);

  return rows.map(row => {
    const member: Member = {
      member_id: row.member_id,
      member_name: row.member_name,
      displayName: row.displayName,
      rank: row.rank,
      rank_date: row.rank_date,
      unit: row.unit,
      unit_date: row.unit_date,
      status: row.status,
      status_date: row.status_date,
      loa_until: row.loa_until ? new Date(row.loa_until) : undefined,
    };

    // roles comes as array of strings; parse each one
    const roles: Role[] = JSON.parse(row.roles).map((r: string) => JSON.parse(r));

    return { member, roles };
  });
}

export async function mapDiscordtoID(id: number): Promise<number | null> {
  const sql = `SELECT id FROM members WHERE discord_id = ?;`
  let res = await pool.query(sql, [id]);
  return res.length > 0 ? res[0].id : null;
}