using System.Collections.Generic;
using System;
using System.Text;
using Newtonsoft.Json;
using EDPlayerJournal.BGS;
using System.Linq;
using System.Windows;
using EDPlayerJournal;
using System.ComponentModel;

namespace EliteBGS;

public class UITransaction : INotifyPropertyChanged {
    private bool isenabled = true;

    public event PropertyChangedEventHandler PropertyChanged;

    public bool IsEnabled {
        get { return isenabled; }
        set {
            isenabled = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsEnabled"));
        }
    }

    public bool IsExpanded { get; set; } = true;

    public Visibility IsCombatZone {
        get {
            return (Transaction != null && Transaction.GetType() == typeof(CombatZone)) ? Visibility.Visible : Visibility.Hidden;
        }
    }

    public Visibility IsSellCargo {
        get {
            return (Transaction != null && Transaction.GetType() == typeof(SellCargo)) ? Visibility.Visible : Visibility.Hidden;
        }
    }

    public Visibility IsGroundCombatZone {
        get {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return Visibility.Hidden;
            }

            if (string.Compare(combat.Type, CombatZones.GroundCombatZone) == 0) {
                return Visibility.Visible;
            }

            return Visibility.Hidden;
        }
    }

    public Visibility IsShipCombatZone {
        get {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return Visibility.Hidden;
            }

            if (string.Compare(combat.Type, CombatZones.ShipCombatZone) == 0) {
                return Visibility.Visible;
            }

            return Visibility.Hidden;
        }
    }

    public Visibility IsAXCombatZone {
        get {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return Visibility.Hidden;
            }

            if (string.Compare(combat.Type, CombatZones.AXCombatZone) == 0) {
                return Visibility.Visible;
            }

            return Visibility.Hidden;
        }
    }

    public bool HasSpecOps {
        get {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return false;
            }

            return combat.SpecOps ?? false;
        }
        set {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return;
            }

            combat.SpecOps = value;
        }
    }

    public bool HasCapitalShip {
        get {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return false;
            }

            return combat.CapitalShip ?? false;
        }
        set {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return;
            }

            combat.CapitalShip = value;
        }
    }

    public bool HasEnemyCaptain {
        get {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return false;
            }

            return combat.EnemyCaptain ?? false;
        }
        set {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return;
            }

            combat.EnemyCaptain = value;
        }
    }

    public bool HasAlliedCaptain {
        get {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return false;
            }

            return combat.AlliedCaptain ?? false;
        }
        set {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return;
            }

            combat.AlliedCaptain = value;
        }
    }

    public bool HasEnemyCorrespondent {
        get {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return false;
            }

            return combat.EnemyCorrespondent ?? false;
        }
        set {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return;
            }

            combat.EnemyCorrespondent = value;
        }
    }

    public bool HasAlliedCorrespondent {
        get {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return false;
            }

            return combat.AlliedCorrespondent ?? false;
        }
        set {
            CombatZone combat = Transaction as CombatZone;
            if (combat == null) {
                return;
            }

            combat.AlliedCorrespondent = value;
        }
    }

    /// <summary>
    /// Profit from selling, used in the XAML ui for binding
    /// </summary>
    public string Profit {
        get {
            SellCargo cargo = Transaction as SellCargo;
            if (cargo == null) {
                return "";
            }
            return cargo.Profit.ToString();
        }
        set {
            SellCargo cargo = Transaction as SellCargo;
            if (cargo == null) {
                return;
            }
            try {
                long profit_as_number = Convert.ToInt64(value);
                cargo.Profit = profit_as_number;
            } catch (FormatException) {
            }
        }
    }

    public Transaction Transaction { get; set; }

    public UITransaction() { }

    public UITransaction(Transaction transaction) {
        Transaction = transaction;
    }

    public string Name {
        get { return ToString(); }
    }

    public string CompletedAt {
        get { return Transaction.CompletedAt; }
    }

    public override string ToString() {
        return Transaction.ToString();
    }
}

public class Objective : IComparable<Objective> {
    public bool IsEnabled { get; set; } = true;

    public List<UITransaction> UITransactions { get; } = new List<UITransaction>();

    public List<Transaction> Transactions {
        get { return UITransactions.Select(x => x.Transaction).ToList<Transaction>(); }
    }

    public Visibility HasSystem {
        get { return string.IsNullOrEmpty(System) ? Visibility.Hidden : Visibility.Visible; }
    }

    public Visibility HasFaction {
        get { return string.IsNullOrEmpty(Faction) ? Visibility.Hidden : Visibility.Visible; }
    }

    public string Name {
        get { return this.ToString(); }
    }

    public bool IsExpanded { get; set; }

    public void Clear() {
        if (Transactions == null) {
            return;
        }
        Transactions.Clear();
    }

    public bool Matches(string system, string faction) {
        return string.Compare(system, System) == 0 &&
               string.Compare(faction, Faction) == 0;
    }

    public bool Matches(string system) {
        return string.Compare(system, System) == 0;
    }

    public int CompareTo(Objective other) {
        return (other.System == System &&
            other.Faction == Faction) ? 0 : -1;
    }

    public bool IsValid {
        get { return !string.IsNullOrEmpty(System) && !string.IsNullOrEmpty(Faction); }
    }

    public string System { get; set; }

    public string Faction { get; set; }

    public override string ToString() {
        StringBuilder str = new StringBuilder();
        if (!string.IsNullOrEmpty(System)) {
            str.AppendFormat("System: {0}", System);
        } else {
            str.AppendFormat("System: Unknown");
        }
        if (!string.IsNullOrEmpty(Faction)) {
            if (str.Length > 0) {
                str.Append(", ");
            }
            str.AppendFormat("Faction: {0}", Faction);
        }
        return str.ToString();
    }

    public List<Type> EnabledOfType<Type>() where Type : Transaction {
        return UITransactions
            .Where(x => x.IsEnabled)
            .Select(x => x.Transaction)
            .OfType<Type>()
            .ToList()
            ;
    }
}
