using BoredCareers.Entities;
using MySql.Data.MySqlClient;

namespace BoredCareers.Services.DatabaseService {
    public partial class DatabaseService {

        public async Task<int> SetResumeHeader(Resume resume) {
            using (var conn = GetConnection()) {
                await conn.OpenAsync();
                string command = @"
                INSERT INTO Resume
                (ID,AccountID,Title,Name,Field,Email,PhoneNumber,PostalCode,Country,StateOrRegion,City,IsActive)
                VALUES
                (@ID,@AccountID,@Title,@Name,@Field,@Email,@PhoneNumber,@PostalCode,@Country,@StateOrRegion,@City,@IsActive)
                ON DUPLICATE KEY UPDATE
                AccountID = @AccountID,
                Title = @Title,
                Name = @Name,
                Field = @Field,
                Email = @Email,
                PhoneNumber = @PhoneNumber,
                PostalCode = @PostalCode,
                Country = @Country,
                StateOrRegion = @StateOrRegion,
                City = @City,
                IsActive = @IsActive;

                SELECT LAST_INSERT_ID();
                ";

                MySqlCommand cmd = new MySqlCommand(command, conn);
                cmd.Parameters.AddWithValue("@ID", resume.ID);
                cmd.Parameters.AddWithValue("@AccountID", resume.AccountID);
                cmd.Parameters.AddWithValue("@Title", resume.Title);
                cmd.Parameters.AddWithValue("@Name", resume.Name);
                cmd.Parameters.AddWithValue("@Field", resume.Field);
                cmd.Parameters.AddWithValue("@Email", resume.Email);
                cmd.Parameters.AddWithValue("@PhoneNumber", resume.PhoneNumber);
                cmd.Parameters.AddWithValue("@PostalCode", resume.PostalCode);
                cmd.Parameters.AddWithValue("@Country", resume.Country);
                cmd.Parameters.AddWithValue("@StateOrRegion", resume.StateOrRegion);
                cmd.Parameters.AddWithValue("@City", resume.City);
                cmd.Parameters.AddWithValue("@IsActive", resume.IsActive);
                object? result = await cmd.ExecuteScalarAsync();

                if (resume.ID != null && resume.ID != 0) {
                    return Convert.ToInt32(resume.ID);
                } else {
                    cmd.CommandText = "";
                    return Convert.ToInt32(result);
                }
            }
        }

        public async Task SetResumeExperienceBullets(ResumeExperienceBullet bullet) {
            using (var conn = GetConnection()) {
                await conn.OpenAsync();
                string command = @"
                INSERT INTO ResumeExperienceBullet
                (ID,ResumeID,ResumeExperienceID,JobFunction)
                VALUES
                (@ID,@ResumeID,@ResumeExperienceID,@JobFunction)
                ON DUPLICATE KEY UPDATE
                ResumeID = @ResumeID,
                ResumeExperienceID = @ResumeExperienceID,
                JobFunction = @JobFunction;
                ";

                MySqlCommand cmd = new MySqlCommand(command, conn);
                cmd.Parameters.AddWithValue("@ID", bullet.ID);
                cmd.Parameters.AddWithValue("@ResumeID", bullet.ResumeID);
                cmd.Parameters.AddWithValue("@ResumeExperienceID", bullet.ResumeExperienceID);
                cmd.Parameters.AddWithValue("@JobFunction", bullet.JobFunction);

                await cmd.ExecuteNonQueryAsync();
            }
        }

        public async Task<ResumeExperience> SetResumeExperience(ResumeExperience experiences) {
            using (var conn = GetConnection()) {
                await conn.OpenAsync();
                string command = @"
                INSERT INTO ResumeExperience
                (ID,ResumeID,JobTitle,Company,PostalCode,Country,StateOrRegion,City,DateStarted,StillEmployed,DateEnded)
                VALUES
                (@ID,@ResumeID,@JobTitle,@Company,@PostalCode,@Country,@StateOrRegion,@City,@DateStarted,@StillEmployed,@DateEnded)
                ON DUPLICATE KEY UPDATE
                ResumeID = @ResumeID,
                JobTitle = @JobTitle,
                Company = @Company,
                PostalCode = @PostalCode,
                Country = @Country,
                StateOrRegion = @StateOrRegion,
                City = @City,
                DateStarted = @DateStarted,
                StillEmployed = @StillEmployed,
                DateEnded = @DateEnded;

                SELECT LAST_INSERT_ID();
                ";

                MySqlCommand cmd = new MySqlCommand(command, conn);
                cmd.Parameters.AddWithValue("@ID", experiences.ID);
                cmd.Parameters.AddWithValue("@ResumeID", experiences.ResumeID);
                cmd.Parameters.AddWithValue("@JobTitle", experiences.JobTitle);
                cmd.Parameters.AddWithValue("@Company", experiences.Company);
                cmd.Parameters.AddWithValue("@Country", experiences.Country);
                cmd.Parameters.AddWithValue("@StateOrRegion", experiences.StateOrRegion);
                cmd.Parameters.AddWithValue("@City", experiences.City);
                cmd.Parameters.AddWithValue("@PostalCode", experiences.PostalCode);
                cmd.Parameters.AddWithValue("@DateStarted", experiences.DateStarted.ToUniversalTime());
                cmd.Parameters.AddWithValue("@StillEmployed", experiences.StillEmployed);
                cmd.Parameters.AddWithValue("@DateEnded", experiences.DateEnded.ToUniversalTime());
                object? result = await cmd.ExecuteScalarAsync();

                if (experiences.ID == null) {
                    experiences.ID = Convert.ToInt32(result);
                }
                return experiences;
            }
        }

        public async Task SetResumeMilitaryBullets(ResumeMilitaryBullet[] bullets) {
            using (var conn = GetConnection()) {
                await conn.OpenAsync();
                foreach (ResumeMilitaryBullet cur in bullets) {
                    string command = @"
                    INSERT INTO ResumeMilitaryBullet
                    (ID,ResumeID,ResumeMilitaryID,Achievement)
                    VALUES
                    (@ID,@ResumeID,@ResumeMilitaryID,@Achievement)
                    ON DUPLICATE KEY UPDATE
                    ResumeID = @ResumeID,
                    ResumeMilitaryID = @ResumeMilitaryID,
                    Achievement = @Achievement,
                    Description = @Description;
                    ";

                    MySqlCommand cmd = new MySqlCommand(command, conn);
                    cmd.Parameters.AddWithValue("@ID", cur.ID);
                    cmd.Parameters.AddWithValue("@ResumeID", cur.ResumeID);
                    cmd.Parameters.AddWithValue("@ResumeMilitaryID", cur.ResumeMilitaryID);
                    cmd.Parameters.AddWithValue("@Achievement", cur.Achievement);
                    cmd.Parameters.AddWithValue("@Description", cur.Description);

                    await cmd.ExecuteNonQueryAsync();
                }
            }
        }

        public async Task<ResumeMilitary> SetResumeMilitary(ResumeMilitary? military) {
            using (var conn = GetConnection()) {
                await conn.OpenAsync();
                if (military != null) {
                    string command = @"
                    INSERT INTO ResumeMilitary
                    (ID,ResumeID,Country,`Rank`,DateStarted,StillServing,DateEnded)
                    VALUES
                    (@ID,@ResumeID,@Country,@Rank,@DateStarted,@StillServing,@DateEnded)
                    ON DUPLICATE KEY UPDATE
                    ResumeID = @ResumeID,
                    Country = @Country,
                    `Rank` = @Rank,
                    DateStarted = @DateStarted,
                    StillServing = @StillServing,
                    DateEnded = @DateEnded;

                    SELECT LAST_INSERT_ID();
                    ";

                    MySqlCommand cmd = new MySqlCommand(command, conn);
                    cmd.Parameters.AddWithValue("@ID", military.ID);
                    cmd.Parameters.AddWithValue("@ResumeID", military.ResumeID);
                    cmd.Parameters.AddWithValue("@Country", military.Country);
                    cmd.Parameters.AddWithValue("@Rank", military.Rank);
                    cmd.Parameters.AddWithValue("@DateStarted", military.DateStarted.ToUniversalTime());
                    cmd.Parameters.AddWithValue("@StillServing", military.StillServing);
                    cmd.Parameters.AddWithValue("@DateEnded", military.DateEnded.ToUniversalTime());
                    object? result = await cmd.ExecuteScalarAsync();

                    if (military.ID == null) {
                        military.ID = Convert.ToInt32(result);
                    }
                    return military;
                }
                return new ResumeMilitary();
            }
        }

        public async Task SetResumeEducation(ResumeEducation[] educations) {
            using (var conn = GetConnection()) {
                await conn.OpenAsync();
                foreach (ResumeEducation cur in educations) {
                    string command = @"
                    INSERT INTO ResumeEducation
                    (ID,ResumeID,DegreeType,DegreeField,School,PostalCode,Country,StateOrRegion,City,DateStarted,StillStudying,DateEnded)
                    VALUES
                    (@ID,@ResumeID,@DegreeType,@DegreeField,@School,@PostalCode,@Country,@StateOrRegion,@City,@DateStarted,@StillStudying,@DateEnded)
                    ON DUPLICATE KEY UPDATE
                    ResumeID = @ResumeID,
                    DegreeType = @DegreeType,
                    DegreeField = @DegreeField,
                    School = @School,
                    PostalCode = @PostalCode,
                    Country = @Country,
                    StateOrRegion = @StateOrRegion,
                    City = @City,
                    DateStarted = @DateStarted,
                    StillStudying = @StillStudying,
                    DateEnded = @DateEnded;
                    ";

                    MySqlCommand cmd = new MySqlCommand(command, conn);
                    cmd.Parameters.AddWithValue("@ID", cur.ID);
                    cmd.Parameters.AddWithValue("@ResumeID", cur.ResumeID);
                    cmd.Parameters.AddWithValue("@DegreeType", cur.DegreeType);
                    cmd.Parameters.AddWithValue("@DegreeField", cur.DegreeField);
                    cmd.Parameters.AddWithValue("@School", cur.School);
                    cmd.Parameters.AddWithValue("@PostalCode", cur.PostalCode);
                    cmd.Parameters.AddWithValue("@Country", cur.Country);
                    cmd.Parameters.AddWithValue("@StateOrRegion", cur.StateOrRegion);
                    cmd.Parameters.AddWithValue("@City", cur.City);
                    cmd.Parameters.AddWithValue("@DateStarted", cur.DateStarted.ToUniversalTime());
                    cmd.Parameters.AddWithValue("@StillStudying", cur.StillStudying);
                    cmd.Parameters.AddWithValue("@DateEnded", cur.DateEnded.ToUniversalTime());

                    await cmd.ExecuteNonQueryAsync();
                }
            }
        }

        public async Task SetResumeSkills(ResumeSkill[] skills) {
            using (var conn = GetConnection()) {
                await conn.OpenAsync();
                foreach (ResumeSkill cur in skills) {
                    string command = @"
                    INSERT INTO ResumeSkill
                    (ID,ResumeID,Name,Description)
                    VALUES
                    (@ID,@ResumeID,@Name,@Description)
                    ON DUPLICATE KEY UPDATE
                    ResumeID = @ResumeID,
                    Name = @Name,
                    Description = @Description;
                    ";

                    MySqlCommand cmd = new MySqlCommand(command, conn);
                    cmd.Parameters.AddWithValue("@ID", cur.ID);
                    cmd.Parameters.AddWithValue("@ResumeID", cur.ResumeID);
                    cmd.Parameters.AddWithValue("@Name", cur.Name);
                    cmd.Parameters.AddWithValue("@Description", cur.Description);

                    await cmd.ExecuteNonQueryAsync();
                }
            }
        }

        public async Task SetResumeLanguages(ResumeLanguage[] languages) {
            using (var conn = GetConnection()) {
                await conn.OpenAsync();
                foreach (ResumeLanguage cur in languages) {
                    string command = @"
                    INSERT INTO ResumeLanguage
                    (ID,ResumeID,Language,Proficiency)
                    VALUES
                    (@ID,@ResumeID,@Language,@Proficiency)
                    ON DUPLICATE KEY UPDATE
                    ResumeID = @ResumeID,
                    Language = @Language,
                    Proficiency = @Proficiency;
                    ";

                    MySqlCommand cmd = new MySqlCommand(command, conn);
                    cmd.Parameters.AddWithValue("@ID", cur.ID);
                    cmd.Parameters.AddWithValue("@ResumeID", cur.ResumeID);
                    cmd.Parameters.AddWithValue("@Language", cur.Language);
                    cmd.Parameters.AddWithValue("@Proficiency", cur.Proficiency);

                    await cmd.ExecuteNonQueryAsync();
                }
            }
        }

        public async Task SetResumeCertification(ResumeCertification[] certifications) {
            using (var conn = GetConnection()) {
                await conn.OpenAsync();
                foreach (ResumeCertification cur in certifications) {
                    string command = @"
                    INSERT INTO ResumeCertification
                    (ID,ResumeID,Name,VerificationURL,Description)
                    VALUES
                    (@ID,@ResumeID,@Name,@VerificationURL,@Description)
                    ON DUPLICATE KEY UPDATE
                    ResumeID = @ResumeID,
                    Name = @Name,
                    VerificationURL = @VerificationURL,
                    Description = @Description;
                    ";

                    MySqlCommand cmd = new MySqlCommand(command, conn);
                    cmd.Parameters.AddWithValue("@ID", cur.ID);
                    cmd.Parameters.AddWithValue("@ResumeID", cur.ResumeID);
                    cmd.Parameters.AddWithValue("@Name", cur.Name);
                    cmd.Parameters.AddWithValue("@VerificationURL", cur.VerificationURL);
                    cmd.Parameters.AddWithValue("@Description", cur.Description);

                    await cmd.ExecuteNonQueryAsync();
                }
            }
        }

        public async Task SetResumeProjects(ResumeProject[] projects) {
            using (var conn = GetConnection()) {
                await conn.OpenAsync();
                foreach (ResumeProject cur in projects) {
                    string command = @"
                    INSERT INTO ResumeProject
                    (ID,ResumeID,Name,URL,Description)
                    VALUES
                    (@ID,@ResumeID,@Name,@URL,@Description)
                    ON DUPLICATE KEY UPDATE
                    ResumeID = @ResumeID,
                    Name = @Name,
                    URL = @URL,
                    Description = @Description;
                    ";

                    MySqlCommand cmd = new MySqlCommand(command, conn);
                    cmd.Parameters.AddWithValue("@ID", cur.ID);
                    cmd.Parameters.AddWithValue("@ResumeID", cur.ResumeID);
                    cmd.Parameters.AddWithValue("@Name", cur.Name);
                    cmd.Parameters.AddWithValue("@URL", cur.URL);
                    cmd.Parameters.AddWithValue("@Description", cur.Description);

                    await cmd.ExecuteNonQueryAsync();
                }
            }
        }

    }
}
