
import { TradeOrder, OrderType, MarketType, AutoTradeConfig, WatchlistGroup, ReservedOrder, StockTick } from '../types';

export interface HoldingItem {
  code: string;
  name: string;
  avgPrice: number;
  quantity: number;
  market: MarketType;
}

export class DbService {
  private holdingsKey = 'batchukis_sqlite_holdings';
  private configsKey = 'batchukis_sqlite_configs';
  private watchlistGroupsKey = 'batchukis_sqlite_watchlist_groups';
  private reservedOrdersKey = 'batchukis_sqlite_reserved_orders';
  private ticksPrefix = 'batchukis_ticks_';

  constructor() {
    this.initDatabase();
  }

  private initDatabase() {
    if (!localStorage.getItem(this.holdingsKey)) {
      const initialHoldings: HoldingItem[] = [
        { code: '005930', name: '삼성전자', avgPrice: 68500, quantity: 150, market: MarketType.DOMESTIC },
        { code: 'AAPL', name: 'Apple Inc.', avgPrice: 175.20, quantity: 25, market: MarketType.OVERSEAS },
      ];
      localStorage.setItem(this.holdingsKey, JSON.stringify(initialHoldings));
    }
    if (!localStorage.getItem(this.configsKey)) {
      localStorage.setItem(this.configsKey, JSON.stringify([]));
    }
    if (!localStorage.getItem(this.watchlistGroupsKey)) {
      const initialGroups: WatchlistGroup[] = [
        { id: 'grp1', name: '핵심 우량주', codes: ['005930', '000660'], market: MarketType.DOMESTIC },
        { id: 'grp2', name: 'AI 포트폴리오', codes: ['NVDA', 'TSLA'], market: MarketType.OVERSEAS },
        { id: 'grp3', name: '미국 빅테크', codes: ['AAPL'], market: MarketType.OVERSEAS }
      ];
      localStorage.setItem(this.watchlistGroupsKey, JSON.stringify(initialGroups));
    }
    if (!localStorage.getItem(this.reservedOrdersKey)) {
      localStorage.setItem(this.reservedOrdersKey, JSON.stringify([]));
    }
  }

  // 시계열 데이터 저장 (무제한)
  async saveStockTick(tick: StockTick) {
    const key = this.ticksPrefix + tick.code;
    const existing = localStorage.getItem(key);
    const ticks: StockTick[] = existing ? JSON.parse(existing) : [];
    ticks.push(tick);
    localStorage.setItem(key, JSON.stringify(ticks));
  }

  async getStockTicks(code: string): Promise<StockTick[]> {
    const key = this.ticksPrefix + code;
    const data = localStorage.getItem(key);
    return data ? JSON.parse(data) : [];
  }

  async getHoldings(): Promise<HoldingItem[]> {
    const data = localStorage.getItem(this.holdingsKey);
    return data ? JSON.parse(data) : [];
  }

  async syncOrderToHolding(order: TradeOrder) {
    const holdings = await this.getHoldings();
    const existingIdx = holdings.findIndex(h => h.code === order.stockCode);

    if (order.type === OrderType.BUY) {
      if (existingIdx > -1) {
        const h = holdings[existingIdx];
        const newQty = h.quantity + order.quantity;
        const newAvg = ((h.avgPrice * h.quantity) + (order.price * order.quantity)) / newQty;
        holdings[existingIdx] = { ...h, quantity: newQty, avgPrice: newAvg };
      } else {
        holdings.push({
          code: order.stockCode,
          name: order.stockName,
          avgPrice: order.price,
          quantity: order.quantity,
          market: order.stockCode.length > 6 ? MarketType.OVERSEAS : MarketType.DOMESTIC
        });
      }
    } else {
      if (existingIdx > -1) {
        holdings[existingIdx].quantity -= order.quantity;
        if (holdings[existingIdx].quantity <= 0) {
          holdings.splice(existingIdx, 1);
        }
      }
    }
    localStorage.setItem(this.holdingsKey, JSON.stringify(holdings));
    return holdings;
  }

  async getWatchlistGroups(): Promise<WatchlistGroup[]> {
    const data = localStorage.getItem(this.watchlistGroupsKey);
    return data ? JSON.parse(data) : [];
  }

  async saveWatchlistGroup(group: WatchlistGroup) {
    const groups = await this.getWatchlistGroups();
    groups.push(group);
    localStorage.setItem(this.watchlistGroupsKey, JSON.stringify(groups));
  }

  async updateWatchlistGroup(group: WatchlistGroup) {
    const groups = await this.getWatchlistGroups();
    const idx = groups.findIndex(g => g.id === group.id);
    if (idx > -1) {
      groups[idx] = group;
      localStorage.setItem(this.watchlistGroupsKey, JSON.stringify(groups));
    }
  }

  async deleteWatchlistGroup(id: string) {
    const groups = await this.getWatchlistGroups();
    const filtered = groups.filter(g => g.id !== id);
    localStorage.setItem(this.watchlistGroupsKey, JSON.stringify(filtered));
  }

  async getAutoConfigs(): Promise<AutoTradeConfig[]> {
    const data = localStorage.getItem(this.configsKey);
    return data ? JSON.parse(data) : [];
  }

  async saveAutoConfig(config: AutoTradeConfig) {
    const configs = await this.getAutoConfigs();
    configs.push(config);
    localStorage.setItem(this.configsKey, JSON.stringify(configs));
  }

  async updateAutoConfig(config: AutoTradeConfig) {
    const configs = await this.getAutoConfigs();
    const idx = configs.findIndex(c => c.id === config.id);
    if (idx > -1) {
      configs[idx] = config;
      localStorage.setItem(this.configsKey, JSON.stringify(configs));
    }
  }

  async deleteAutoConfig(id: string) {
    const configs = await this.getAutoConfigs();
    const filtered = configs.filter(c => c.id !== id);
    localStorage.setItem(this.configsKey, JSON.stringify(filtered));
  }

  async getReservedOrders(): Promise<ReservedOrder[]> {
    const data = localStorage.getItem(this.reservedOrdersKey);
    return data ? JSON.parse(data) : [];
  }

  async saveReservedOrder(order: ReservedOrder) {
    const orders = await this.getReservedOrders();
    orders.push(order);
    localStorage.setItem(this.reservedOrdersKey, JSON.stringify(orders));
  }

  async updateReservedOrder(order: ReservedOrder) {
    const orders = await this.getReservedOrders();
    const idx = orders.findIndex(o => o.id === order.id);
    if (idx > -1) {
      orders[idx] = order;
      localStorage.setItem(this.reservedOrdersKey, JSON.stringify(orders));
    }
  }

  async deleteReservedOrder(id: string) {
    const orders = await this.getReservedOrders();
    const filtered = orders.filter(o => o.id !== id);
    localStorage.setItem(this.reservedOrdersKey, JSON.stringify(filtered));
  }

  async getAccountSummary() {
    const holdings = await this.getHoldings();
    const totalEval = holdings.reduce((acc, h) => acc + (h.avgPrice * h.quantity), 0);
    return {
      totalAssets: totalEval + 45800000,
      buyingPower: 45800000
    };
  }
}
