package com.goldenchart.controller;

import com.goldenchart.entity.GcWatchlist;
import com.goldenchart.entity.GcHoldings;
import com.goldenchart.repository.GcHoldingsRepository;
import com.goldenchart.repository.GcWatchlistRepository;
import com.goldenchart.service.WatchlistService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 관심종목 / 보유종목 REST API.
 *
 * <p>관심종목 추가/삭제 시 {@link WatchlistService} 가 실시간 전략 체크 대상과 자동 연동한다.
 */
@RestController
@RequiredArgsConstructor
@Transactional
public class WatchlistController {

    private final WatchlistService        watchlistService;
    private final GcWatchlistRepository   watchlistRepo;
    private final GcHoldingsRepository    holdingsRepo;

    private Long userId(Map<String, String> h) {
        String v = h.get("x-user-id"); return v != null ? Long.parseLong(v) : null;
    }
    private String deviceId(Map<String, String> h) {
        return h.getOrDefault("x-device-id", "anonymous");
    }

    // ── 관심종목 ──────────────────────────────────────────────────────────────

    @GetMapping("/watchlist")
    @Transactional(readOnly = true)
    public ResponseEntity<List<GcWatchlist>> getWatchlist(@RequestHeader Map<String, String> h) {
        return ResponseEntity.ok(watchlistService.list(userId(h), deviceId(h)));
    }

    @PostMapping("/watchlist")
    public ResponseEntity<GcWatchlist> addWatchlist(
            @RequestHeader Map<String, String> h,
            @RequestBody Map<String, Object> body) {
        Long uid = userId(h);
        String symbol = (String) body.get("symbol");
        GcWatchlist item = watchlistService.add(
                uid,
                deviceId(h),
                symbol,
                (String) body.get("koreanName"),
                (String) body.get("englishName"),
                body.containsKey("displayOrder") ? (Integer) body.get("displayOrder") : null
        );
        return ResponseEntity.ok(item);
    }

    @DeleteMapping("/watchlist/{symbol}")
    public ResponseEntity<Void> removeWatchlist(
            @RequestHeader Map<String, String> h,
            @PathVariable String symbol) {
        watchlistService.remove(userId(h), deviceId(h), symbol);
        return ResponseEntity.noContent().build();
    }

    @PutMapping("/watchlist/order")
    public ResponseEntity<Void> reorderWatchlist(
            @RequestHeader Map<String, String> h,
            @RequestBody List<Map<String, Object>> items) {
        items.forEach(item -> {
            String symbol = (String) item.get("symbol");
            int order = (Integer) item.get("displayOrder");
            Long uid = userId(h);
            watchlistService.list(uid, deviceId(h)).stream()
                    .filter(w -> w.getSymbol().equals(symbol))
                    .findFirst()
                    .ifPresent(w -> { w.setDisplayOrder(order); watchlistRepo.save(w); });
        });
        return ResponseEntity.ok().build();
    }

    // ── 보유종목 ──────────────────────────────────────────────────────────────

    @GetMapping("/holdings")
    @Transactional(readOnly = true)
    public ResponseEntity<List<GcHoldings>> getHoldings(@RequestHeader Map<String, String> h) {
        Long uid = userId(h);
        return ResponseEntity.ok(uid != null
            ? holdingsRepo.findByUserIdOrderByDisplayOrderAsc(uid)
            : holdingsRepo.findByDeviceIdOrderByDisplayOrderAsc(deviceId(h)));
    }

    @PostMapping("/holdings")
    public ResponseEntity<GcHoldings> addHoldings(
            @RequestHeader Map<String, String> h,
            @RequestBody Map<String, Object> body) {
        Long uid = userId(h);
        String did = uid == null ? deviceId(h) : null;
        String symbol = (String) body.get("symbol");

        GcHoldings item = (uid != null
            ? holdingsRepo.findByUserIdOrderByDisplayOrderAsc(uid)
            : holdingsRepo.findByDeviceIdOrderByDisplayOrderAsc(deviceId(h)))
            .stream().filter(hld -> hld.getSymbol().equals(symbol)).findFirst()
            .orElseGet(() -> GcHoldings.builder().userId(uid).deviceId(did).symbol(symbol).build());

        item.setKoreanName((String) body.get("koreanName"));
        item.setEnglishName((String) body.get("englishName"));
        if (body.containsKey("avgPrice"))
            item.setAvgPrice(new BigDecimal(body.get("avgPrice").toString()));
        if (body.containsKey("quantity"))
            item.setQuantity(new BigDecimal(body.get("quantity").toString()));
        if (body.containsKey("displayOrder"))
            item.setDisplayOrder((Integer) body.get("displayOrder"));

        return ResponseEntity.ok(holdingsRepo.save(item));
    }

    @DeleteMapping("/holdings/{symbol}")
    public ResponseEntity<Void> removeHoldings(
            @RequestHeader Map<String, String> h,
            @PathVariable String symbol) {
        Long uid = userId(h);
        if (uid != null) holdingsRepo.deleteByUserIdAndSymbol(uid, symbol);
        else holdingsRepo.deleteByDeviceIdAndSymbol(deviceId(h), symbol);
        return ResponseEntity.noContent().build();
    }
}
