// 간단한 JSON 파일 저장소 (외부 DB 의존성 없음)
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const DATA_DIR = path.join(__dirname, '..', 'data');
const DB_PATH = path.join(DATA_DIR, 'db.json');

const DEFAULT_DB = {
  media: [],
  schedules: [],
  // 재사용 재생목록(캠페인) — 스케줄에서 참조
  playlists: [],
  settings: {
    // 전광판 출력 해상도
    resolution: { width: 1920, height: 1080, preset: '1920x1080' },
    // 스케일링 방식: contain(비율유지·여백, 왜곡없음/1:1) | cover(비율유지·꽉채움·잘림) | fill(늘려서 꽉채움)
    scaleMode: 'contain',
    // 대기 화면(편성 없음): black(검은화면) | clock(시계)
    idleMode: 'black',
    // 오버레이(자막 티커 / 시계 / 날씨 위젯) — 모든 송출 화면 위에 표시
    overlay: {
      ticker: { enabled: false, text: '', source: 'text', rssUrl: '', position: 'bottom', speedSec: 20, bg: '#000000', opacity: 65, color: '#ffffff' },
      clock: { enabled: false, position: 'top-right', showDate: true },
      weather: { enabled: false, lat: 37.5665, lon: 126.9780, label: '서울', position: 'top-left' },
    },
    // 화면 레이아웃(멀티존): single | split-lr | split-tb | main-bottom
    layout: { preset: 'single', subMediaIds: [] },
    // 화면 전원(취침) 스케줄 — 지정 시간엔 검은 화면
    power: { enabled: false, offStart: '00:00', offEnd: '06:00', days: [0, 1, 2, 3, 4, 5, 6] },
    // 밝기 제어
    brightness: {
      mode: 'auto',            // 'manual' | 'auto'
      manual: 100,             // 수동 밝기 (0~100)
      day: { start: '06:00', value: 100 },   // 주간 밝기
      night: { start: '18:00', value: 45 },  // 야간 밝기
    },
  },
  // 포스터/현수막 편성 (이미지) — 일반 스케줄보다 우선 송출
  // { id, name, mediaId(이미지), startDate:'YYYY-MM-DD', endDate, days:[0-6], slots:[{start,end}], displaySeconds, enabled }
  posters: [],
  // 긴급 송출 (모든 것을 덮어씀)
  emergency: { active: false, mediaId: null, startedAt: null },
  // 관리자 로그인(무조건 필요) — 최초 실행 시 비밀번호 설정. scrypt 해시 저장(평문 보관 안 함)
  auth: { salt: '', hash: '' },
  // 원격 지원(Remote Client) 설정 — 활성화 시 Remote Manager에 연결되어 원격 제어/업데이트 허용
  remote: {
    enabled: false,
    managerUrl: '',   // 예) ws://내서버주소:4100/agent
    token: '',        // 매니저가 알려준 페어링 토큰
    clientName: '',   // 이 전광판의 표시 이름
    allowUpdate: true, // 원격 패치/업그레이드 허용
  },
  // 클라우드(cms.hcjoyn.com) 계정 연결 — 스케줄 서버 백업/복구
  cloud: {
    portalUrl: 'https://cms.hcjoyn.com', // 포털 주소
    linked: false,        // 계정 연결 여부
    email: '',            // 연결된 계정 이메일
    deviceToken: '',      // 기기 토큰(포털 발급) — 비밀
    deviceName: '',       // 이 전광판(기기) 표시 이름
    orgName: '',          // 소속 회원사명(표시용)
    autoBackup: true,     // 하루 2회 자동 백업
    lastBackupAt: null,   // 마지막 백업 시각
    lastBackupStatus: '', // ok | 오류메시지
    lastRestoreAt: null,  // 마지막 복구 적용 시각
  },
};

let db = null;

function ensureDataDir() {
  if (!fs.existsSync(DATA_DIR)) fs.mkdirSync(DATA_DIR, { recursive: true });
}

export function load() {
  ensureDataDir();
  if (!fs.existsSync(DB_PATH)) {
    db = structuredClone(DEFAULT_DB);
    save();
    return db;
  }
  try {
    const raw = JSON.parse(fs.readFileSync(DB_PATH, 'utf-8'));
    // 기본값과 병합 (누락 필드 보정)
    db = {
      ...structuredClone(DEFAULT_DB),
      ...raw,
      settings: { ...DEFAULT_DB.settings, ...(raw.settings || {}) },
      emergency: { ...DEFAULT_DB.emergency, ...(raw.emergency || {}) },
      remote: { ...DEFAULT_DB.remote, ...(raw.remote || {}) },
      cloud: { ...DEFAULT_DB.cloud, ...(raw.cloud || {}) },
      auth: { ...DEFAULT_DB.auth, ...(raw.auth || {}) },
      posters: Array.isArray(raw.posters) ? raw.posters : [],
      playlists: Array.isArray(raw.playlists) ? raw.playlists : [],
    };
    db.settings.brightness = { ...DEFAULT_DB.settings.brightness, ...(db.settings.brightness || {}) };
    db.settings.resolution = { ...DEFAULT_DB.settings.resolution, ...(db.settings.resolution || {}) };
    const ov = db.settings.overlay || {};
    db.settings.overlay = {
      ticker: { ...DEFAULT_DB.settings.overlay.ticker, ...(ov.ticker || {}) },
      clock: { ...DEFAULT_DB.settings.overlay.clock, ...(ov.clock || {}) },
      weather: { ...DEFAULT_DB.settings.overlay.weather, ...(ov.weather || {}) },
    };
    db.settings.layout = { ...DEFAULT_DB.settings.layout, ...(db.settings.layout || {}) };
    db.settings.power = { ...DEFAULT_DB.settings.power, ...(db.settings.power || {}) };
    // 구버전 idleShowClock → idleMode 마이그레이션
    if (raw.settings && raw.settings.idleMode === undefined && raw.settings.idleShowClock !== undefined) {
      db.settings.idleMode = raw.settings.idleShowClock ? 'clock' : 'black';
    }
    delete db.settings.idleShowClock;
  } catch (e) {
    console.error('[store] db.json 파싱 실패, 기본값으로 시작합니다:', e.message);
    db = structuredClone(DEFAULT_DB);
  }
  return db;
}

let saveTimer = null;
export function save() {
  ensureDataDir();
  // 디바운스 저장 (잦은 쓰기 방지)
  if (saveTimer) clearTimeout(saveTimer);
  saveTimer = setTimeout(() => {
    fs.writeFileSync(DB_PATH, JSON.stringify(db, null, 2), 'utf-8');
  }, 100);
}

export function saveNow() {
  ensureDataDir();
  fs.writeFileSync(DB_PATH, JSON.stringify(db, null, 2), 'utf-8');
}

export function getDb() {
  if (!db) load();
  return db;
}

export const paths = { DATA_DIR, DB_PATH };
