package midTest.cardPack;
import selfTest.card.Card;
import java.time.LocalDate;
import java.util.*;
enum CardType {
GIFT(0.01, 0.0),
CASH(0.02,0.0),
CREDIT(0.05,0.1);
private final double fee;
private final double texRate;
CardType(double fee, double texRate){
this.fee = fee; this.texRate = texRate;
}
public double getFee() {return fee;}
public double getTexRate() {return texRate;}
}
class User{
private Long idx;
private String email;
public User(long idx, String email){
this.idx = idx; this.email = email;
}
public Long getIdx() {
return idx;
}
public void setIdx(Long idx) {
this.idx = idx;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"idx=" + idx +
", email='" + email + '\'' +
'}';
}
}
class TransactionData{
long cardIdx;
private Date date;
private int price;
private String exData ="X";
public TransactionData(long cardIdx, Date date, int price){
this.cardIdx = cardIdx; this.date = date; this.price = price;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public void setExData(String exData) {
this.exData = exData;
}
public String getExData() {
return exData;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "TransactionData{" +
"card=" + cardIdx +
"date=" + date +
", price=" + price +
'}';
}
}
class Chargeable{
protected long idx;
protected CardType cardType;
protected List<TransactionData> datas; //사용 내역
protected Chargeable(long idx, CardType cardType){
this.idx = idx;
this.cardType = cardType;
this.datas = new ArrayList<>();
}
public void setIdx(long idx) {
this.idx = idx;
}
public CardType getCardType() {
return cardType;
}
protected void payment(int price){
datas.add(new TransactionData(idx,new Date(), price));
}
protected void cardPaymentHistories(){
System.out.println(cardType);
System.out.println(idx);
System.out.println("\n===========================");
System.out.println(datas);
System.out.println("===========================\n");
}
@Override
public boolean equals(Object object) {
if (this == object) return true;
if (object == null || getClass() != object.getClass()) return false;
Chargeable that = (Chargeable) object;
return idx == that.idx;
}
@Override
public int hashCode() {
return Objects.hash(idx);
}
@Override
public String toString() {
return "Chargeable{" +
"idx=" + idx +
", cardType=" + cardType +
'}';
}
}
class GiftCards extends Chargeable{
GiftCards(long idx){
super(idx, CardType.GIFT);
}
@Override
public String toString() {
return super.cardType.name() + "card";
}
}
class Card_ extends Chargeable{
protected String cardNumber;
protected Card_(long idx,CardType cardType){
super(idx,cardType);
}
}
class CashCards extends Card_{
private String accountNumber;
public CashCards(long idx, String cardNumber,String accountNumber){
super(idx,CardType.CASH);
super.cardNumber = cardNumber;
this.accountNumber = accountNumber;
}
public String getAccountNumber(){return accountNumber;}
@Override
public String toString() {
return super.toString() +
"\n{" + "accountNumber"+accountNumber + '}';
}
@Override
protected void payment(int price) {
super.payment(price);
datas.get(datas.size() -1).setExData("accountNumber: "+accountNumber);
}
}
class CreditCards extends Card_{
private String endDate;
public CreditCards(long idx, String cardNumber, String endDate){
super(idx,CardType.CREDIT);
super.cardNumber = cardNumber;
this.endDate = endDate;
}
public String getEndDate() {
return endDate;
}
@Override
public String toString() {
return super.toString() +
"\n{" + "endDate"+endDate + '}';
}
@Override
protected void payment(int price) {
super.payment(price);
datas.get(datas.size() -1).setExData("end date: "+endDate);
}
}
public class SinhanCard {
private static SinhanCard INSTANCE;
private Map<User, List<Chargeable>> users;
private Long userIdx = 1000L;
private Long cardNum = 10000L;
public SinhanCard(){users = new HashMap<>();}
public static synchronized SinhanCard getINSTANCE(){
if(INSTANCE == null) INSTANCE = new SinhanCard();
return INSTANCE;
}
public void createUser(String email){
users.put(new User(userIdx++, email), new ArrayList<Chargeable>());
}
private User findUser(long idx){
for(var user: users.keySet()){
if (user.getIdx().equals(idx)) return user;
}
System.out.println("user not found");
return null;
}
public void createCard(long idx, CardType cardType){
var user = findUser(idx);
if(users == null) return;
var cards = users.get(user);
switch (cardType){
case CREDIT -> {
cards.add(new CreditCards(cardNum++,"1111-11111-1111", LocalDate.now().toString()));
}
case CASH -> {
cards.add(new CashCards(cardNum++,"222222-22222-2222", "33333-33333-33333"));
}
case GIFT -> {
cards.add(new GiftCards(cardNum++));
}
}
}
public Chargeable findMyCard(long userIdx, CardType cardType){
Scanner scanner = new Scanner(System.in);
var user = findUser(userIdx);
if(user == null) return null;
var cs = users.get(user);
System.out.println("선택할 카드 번호를 입력하시오");
for (var card : cs){
if(card.getCardType().equals(cardType)){
System.out.println(cs.indexOf(card));
System.out.println(card);
System.out.println('\n');
}
}
int index = scanner.nextInt();
return cs.get(index);
}
}
class Main_{
Chargeable card;
public void pay(int price){
if (card == null){
System.out.println("카드 먼저 선택");
return;
}
switch (card.getCardType()){
case GIFT -> {
var gCard = (GiftCards)card;
gCard.payment(price);
}
case CASH -> {
var cCard = (CashCards)card;
cCard.payment(price);
}
case CREDIT -> {
var crCard = (CreditCards)card;
crCard.payment(price);
}
}
}
public void setCard(Chargeable card) {
this.card = card;
}
public static void main(String[] args) {
Main_ my = new Main_();
var b = SinhanCard.getINSTANCE();
b.createUser("qor@naver.com");
b.createCard(1000L, CardType.GIFT);
b.createCard(1000L, CardType.GIFT);
b.createCard(1000L,CardType.CREDIT);
b.createCard(1000L, CardType.CASH);
my.setCard(b.findMyCard(1000L, CardType.GIFT));
my.pay(1000);
my.card.cardPaymentHistories();
my.setCard(b.findMyCard(1000L, CardType.CREDIT));
my.pay(100000);
my.pay(200);
my.pay(500);
my.card.cardPaymentHistories();
}
}