CREATE TABLE IF NOT EXISTS lectures (
  id UUID PRIMARY KEY,
  type VARCHAR(20) NOT NULL CHECK (type IN ('youtube', 'ppt', 'news', 'link', 'video')),
  title TEXT NOT NULL,
  description TEXT NOT NULL DEFAULT '',
  tags TEXT[] NOT NULL DEFAULT '{}',
  youtube_url TEXT,
  file_name TEXT,
  original_name TEXT,
  preview_title TEXT,
  slide_count INTEGER NOT NULL DEFAULT 0,
  thumbnail_url TEXT,
  thumbnail_status VARCHAR(20) NOT NULL DEFAULT 'pending',
  thumbnail_retry_count INTEGER NOT NULL DEFAULT 0,
  thumbnail_error TEXT,
  thumbnail_updated_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  list_section VARCHAR(20) NOT NULL DEFAULT 'learning',
  news_url TEXT
);

ALTER TABLE lectures DROP CONSTRAINT IF EXISTS lectures_type_check;
ALTER TABLE lectures ADD CONSTRAINT lectures_type_check CHECK (type IN ('youtube', 'ppt', 'news', 'link', 'video'));
ALTER TABLE lectures ADD COLUMN IF NOT EXISTS list_section VARCHAR(20) NOT NULL DEFAULT 'learning';
ALTER TABLE lectures ADD COLUMN IF NOT EXISTS news_url TEXT;

CREATE INDEX IF NOT EXISTS idx_lectures_type_created_at ON lectures (type, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_lectures_created_at ON lectures (created_at DESC);
CREATE INDEX IF NOT EXISTS idx_lectures_tags ON lectures USING GIN (tags);

CREATE OR REPLACE FUNCTION set_lectures_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_lectures_updated_at ON lectures;
CREATE TRIGGER trg_lectures_updated_at
BEFORE UPDATE ON lectures
FOR EACH ROW
EXECUTE FUNCTION set_lectures_updated_at();

-- AX 과제 신청 (PDF 양식 기반)
CREATE TABLE IF NOT EXISTS ax_assignments (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  department VARCHAR(200) NOT NULL,
  name VARCHAR(100) NOT NULL,
  employee_id VARCHAR(50),
  position VARCHAR(100),
  phone VARCHAR(50),
  email VARCHAR(200),
  work_process_description TEXT,
  pain_point TEXT,
  current_time_spent VARCHAR(100),
  error_rate_before VARCHAR(100),
  collaboration_depts TEXT,
  reason_to_solve TEXT,
  ai_expectation TEXT,
  output_type TEXT,
  automation_level VARCHAR(50),
  data_readiness VARCHAR(50),
  data_location TEXT,
  personal_info VARCHAR(50),
  data_quality VARCHAR(50),
  data_count VARCHAR(100),
  data_types TEXT[],
  time_reduction VARCHAR(100),
  error_reduction VARCHAR(100),
  volume_increase VARCHAR(100),
  cost_reduction VARCHAR(100),
  response_time VARCHAR(100),
  other_metrics TEXT,
  annual_savings VARCHAR(100),
  labor_replacement VARCHAR(100),
  revenue_increase VARCHAR(100),
  other_effects TEXT,
  qualitative_effects TEXT[],
  tech_stack TEXT[],
  risks TEXT[],
  risk_detail TEXT,
  participation_pledge BOOLEAN DEFAULT false,
  application_file TEXT,
  status VARCHAR(20) NOT NULL DEFAULT '신청',
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

ALTER TABLE ax_assignments ADD COLUMN IF NOT EXISTS application_file TEXT;

CREATE INDEX IF NOT EXISTS idx_ax_assignments_created_at ON ax_assignments (created_at DESC);

CREATE OR REPLACE FUNCTION set_ax_assignments_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_ax_assignments_updated_at ON ax_assignments;
CREATE TRIGGER trg_ax_assignments_updated_at
BEFORE UPDATE ON ax_assignments
FOR EACH ROW
EXECUTE FUNCTION set_ax_assignments_updated_at();

-- OPS 이메일(@ncue.net) 매직 링크 인증 — 이벤트 감사 로그
CREATE TABLE IF NOT EXISTS ops_email_auth_events (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  email VARCHAR(320) NOT NULL,
  event_type VARCHAR(40) NOT NULL CHECK (event_type IN ('magic_link_requested', 'login_success', 'logout', 'sessions_revoked')),
  ip_address VARCHAR(45),
  user_agent TEXT,
  return_to TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_ops_email_auth_events_email_created ON ops_email_auth_events (email, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_ops_email_auth_events_created ON ops_email_auth_events (created_at DESC);
CREATE INDEX IF NOT EXISTS idx_ops_email_auth_events_event_type ON ops_email_auth_events (event_type);

-- 이메일별 최초·최근 로그인 및 누적 로그인 횟수
CREATE TABLE IF NOT EXISTS ops_email_users (
  email VARCHAR(320) PRIMARY KEY,
  first_seen_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  last_login_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  login_count INTEGER NOT NULL DEFAULT 0,
  sessions_revoked_at TIMESTAMPTZ
);

CREATE INDEX IF NOT EXISTS idx_ops_email_users_last_login ON ops_email_users (last_login_at DESC);

ALTER TABLE ops_email_users ADD COLUMN IF NOT EXISTS sessions_revoked_at TIMESTAMPTZ;

ALTER TABLE ops_email_auth_events DROP CONSTRAINT IF EXISTS ops_email_auth_events_event_type_check;
ALTER TABLE ops_email_auth_events ADD CONSTRAINT ops_email_auth_events_event_type_check
  CHECK (event_type IN ('magic_link_requested', 'login_success', 'logout', 'sessions_revoked'));

-- 회의록 AI: 이메일(OPS 세션) 기반 사용자·프롬프트·회의 저장
CREATE TABLE IF NOT EXISTS meeting_ai_users (
  email VARCHAR(320) PRIMARY KEY,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS meeting_ai_prompts (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_email VARCHAR(320) NOT NULL REFERENCES meeting_ai_users(email) ON DELETE CASCADE,
  include_title_line BOOLEAN NOT NULL DEFAULT true,
  include_attendees BOOLEAN NOT NULL DEFAULT true,
  include_summary BOOLEAN NOT NULL DEFAULT true,
  include_action_items BOOLEAN NOT NULL DEFAULT true,
  include_checklist BOOLEAN NOT NULL DEFAULT false,
  custom_instructions TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  CONSTRAINT uq_meeting_ai_prompts_user UNIQUE (user_email)
);

CREATE INDEX IF NOT EXISTS idx_meeting_ai_prompts_user ON meeting_ai_prompts (user_email);

-- 기존 DB: 신규 행 기본값만 갱신(이미 저장된 include_checklist 값은 유지)
ALTER TABLE meeting_ai_prompts ALTER COLUMN include_checklist SET DEFAULT false;

CREATE TABLE IF NOT EXISTS meeting_ai_meetings (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_email VARCHAR(320) NOT NULL REFERENCES meeting_ai_users(email) ON DELETE CASCADE,
  title VARCHAR(500) NOT NULL DEFAULT '',
  source_text TEXT,
  transcript_text TEXT,
  generated_minutes TEXT,
  summary_text TEXT,
  audio_file_path TEXT,
  audio_original_name TEXT,
  chat_model VARCHAR(80) NOT NULL DEFAULT 'gpt-5-mini',
  transcription_model VARCHAR(80),
  meeting_date DATE,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_meeting_ai_meetings_user_created ON meeting_ai_meetings (user_email, created_at DESC);

-- 기존 DB 마이그레이션: 전사에 사용한 OpenAI 모델(gpt-4o-mini-transcribe, gpt-4o-transcribe 등)
ALTER TABLE meeting_ai_meetings ADD COLUMN IF NOT EXISTS transcription_model VARCHAR(80);

-- 미팅 일자(회의가 열린 날짜, 선택)
ALTER TABLE meeting_ai_meetings ADD COLUMN IF NOT EXISTS meeting_date DATE;

-- 회의록 생성 후 체크리스트 자동 추출(JSON 스냅샷, 업무 체크리스트 AI 연동)
ALTER TABLE meeting_ai_meetings ADD COLUMN IF NOT EXISTS checklist_snapshot JSONB;

-- 업무 체크리스트 툴팁용 짧은 요약(생성 시 회의록 본문에서 추출해 저장, 없으면 조회 시 추출)
ALTER TABLE meeting_ai_meetings ADD COLUMN IF NOT EXISTS summary_text TEXT;

CREATE OR REPLACE FUNCTION set_meeting_ai_prompts_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_meeting_ai_prompts_updated_at ON meeting_ai_prompts;
CREATE TRIGGER trg_meeting_ai_prompts_updated_at
BEFORE UPDATE ON meeting_ai_prompts
FOR EACH ROW
EXECUTE FUNCTION set_meeting_ai_prompts_updated_at();

CREATE OR REPLACE FUNCTION set_meeting_ai_meetings_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_meeting_ai_meetings_updated_at ON meeting_ai_meetings;
CREATE TRIGGER trg_meeting_ai_meetings_updated_at
BEFORE UPDATE ON meeting_ai_meetings
FOR EACH ROW
EXECUTE FUNCTION set_meeting_ai_meetings_updated_at();

-- 업무 체크리스트 AI: 사용자별 항목(회의록에서 가져오기 또는 수동)
CREATE TABLE IF NOT EXISTS meeting_ai_checklist_items (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_email VARCHAR(320) NOT NULL REFERENCES meeting_ai_users(email) ON DELETE CASCADE,
  meeting_id UUID REFERENCES meeting_ai_meetings(id) ON DELETE SET NULL,
  title TEXT NOT NULL,
  detail TEXT,
  assignee VARCHAR(300),
  due_note VARCHAR(300),
  completed BOOLEAN NOT NULL DEFAULT false,
  completed_at TIMESTAMPTZ,
  completion_note TEXT,
  sort_order INT NOT NULL DEFAULT 0,
  source VARCHAR(20) NOT NULL DEFAULT 'imported' CHECK (source IN ('imported', 'manual')),
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

ALTER TABLE meeting_ai_checklist_items ADD COLUMN IF NOT EXISTS completion_note TEXT;

CREATE INDEX IF NOT EXISTS idx_meeting_ai_checklist_user_updated ON meeting_ai_checklist_items (user_email, updated_at DESC);
CREATE INDEX IF NOT EXISTS idx_meeting_ai_checklist_meeting ON meeting_ai_checklist_items (meeting_id);

CREATE OR REPLACE FUNCTION set_meeting_ai_checklist_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_meeting_ai_checklist_updated_at ON meeting_ai_checklist_items;
CREATE TRIGGER trg_meeting_ai_checklist_updated_at
BEFORE UPDATE ON meeting_ai_checklist_items
FOR EACH ROW
EXECUTE FUNCTION set_meeting_ai_checklist_updated_at();

-- PPT 썸네일 작업 이벤트 로그 (기존 data/thumbnail-events.json 대체)
CREATE TABLE IF NOT EXISTS lecture_thumbnail_events (
  id UUID PRIMARY KEY,
  occurred_at TIMESTAMPTZ NOT NULL,
  event_type VARCHAR(40) NOT NULL,
  lecture_id UUID,
  lecture_title TEXT,
  reason VARCHAR(200),
  force_flag BOOLEAN NOT NULL DEFAULT false,
  queue_size_after INTEGER,
  retry_count INTEGER,
  duration_ms INTEGER,
  error_text TEXT
);

CREATE INDEX IF NOT EXISTS idx_lecture_thumbnail_events_occurred ON lecture_thumbnail_events (occurred_at DESC);
CREATE INDEX IF NOT EXISTS idx_lecture_thumbnail_events_type ON lecture_thumbnail_events (event_type);
CREATE INDEX IF NOT EXISTS idx_lecture_thumbnail_events_lecture ON lecture_thumbnail_events (lecture_id);

-- 경영성과 대시보드: 엑셀 업로드·차트용 JSON 스냅샷
CREATE TABLE IF NOT EXISTS mgmt_perf_uploads (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_email VARCHAR(320),
  original_filename TEXT NOT NULL,
  fiscal_year INT NOT NULL,
  quarter INT NOT NULL CHECK (quarter >= 1 AND quarter <= 4),
  file_path TEXT NOT NULL,
  file_size BIGINT,
  parse_status VARCHAR(32) NOT NULL DEFAULT 'ok',
  parse_error TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_mgmt_perf_uploads_created ON mgmt_perf_uploads (created_at DESC);

CREATE TABLE IF NOT EXISTS mgmt_perf_snapshots (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  upload_id UUID NOT NULL UNIQUE REFERENCES mgmt_perf_uploads (id) ON DELETE CASCADE,
  payload JSONB NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_mgmt_perf_snapshots_upload ON mgmt_perf_snapshots (upload_id);

-- AI 활용 사례: 일반 사용자 제출(글쓰기) — 본문 4섹션·썸네일·첨부, 제출자 이메일·시각
CREATE TABLE IF NOT EXISTS ai_use_case_submissions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  submitter_email VARCHAR(320) NOT NULL,
  title TEXT NOT NULL,
  situation TEXT NOT NULL DEFAULT '',
  task_goal TEXT NOT NULL DEFAULT '',
  action_taken TEXT NOT NULL DEFAULT '',
  result_outcome TEXT NOT NULL DEFAULT '',
  tags TEXT[] NOT NULL DEFAULT '{}',
  thumbnail_relative_path TEXT,
  thumbnail_files JSONB NOT NULL DEFAULT '[]',
  attachment_files JSONB NOT NULL DEFAULT '[]',
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_ai_use_case_submissions_created ON ai_use_case_submissions (created_at DESC);
CREATE INDEX IF NOT EXISTS idx_ai_use_case_submissions_submitter ON ai_use_case_submissions (submitter_email, created_at DESC);

CREATE OR REPLACE FUNCTION set_ai_use_case_submissions_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_ai_use_case_submissions_updated_at ON ai_use_case_submissions;
CREATE TRIGGER trg_ai_use_case_submissions_updated_at
BEFORE UPDATE ON ai_use_case_submissions
FOR EACH ROW
EXECUTE FUNCTION set_ai_use_case_submissions_updated_at();

-- 썸네일 다중 업로드(최대 5): 기존 DB 마이그레이션
ALTER TABLE ai_use_case_submissions
  ADD COLUMN IF NOT EXISTS thumbnail_files JSONB NOT NULL DEFAULT '[]';

UPDATE ai_use_case_submissions
SET thumbnail_files = jsonb_build_array(
  jsonb_build_object(
    'originalName', COALESCE(NULLIF(regexp_replace(thumbnail_relative_path, '^.+/', ''), ''), 'thumbnail'),
    'relativePath', thumbnail_relative_path
  )
)
WHERE thumbnail_relative_path IS NOT NULL
  AND btrim(thumbnail_relative_path) <> ''
  AND (thumbnail_files IS NULL OR thumbnail_files = '[]'::jsonb);

-- AI 활용 사례 제출: 페이지뷰 조회수(제출자 본인 로그인 조회 제외) · 좋아요
ALTER TABLE ai_use_case_submissions
  ADD COLUMN IF NOT EXISTS view_count INTEGER NOT NULL DEFAULT 0;

-- (legacy) 초기 unique 조회 추적용 — 현재 집계는 view_count 페이지뷰만 사용
CREATE TABLE IF NOT EXISTS ai_use_case_views (
  submission_id UUID NOT NULL REFERENCES ai_use_case_submissions(id) ON DELETE CASCADE,
  viewer_email VARCHAR(320) NOT NULL,
  viewed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  PRIMARY KEY (submission_id, viewer_email)
);

CREATE INDEX IF NOT EXISTS idx_ai_use_case_views_submission ON ai_use_case_views (submission_id);

CREATE TABLE IF NOT EXISTS ai_use_case_submission_likes (
  submission_id UUID NOT NULL REFERENCES ai_use_case_submissions(id) ON DELETE CASCADE,
  user_email VARCHAR(320) NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  PRIMARY KEY (submission_id, user_email)
);

CREATE INDEX IF NOT EXISTS idx_ai_use_case_submission_likes_submission
  ON ai_use_case_submission_likes (submission_id);

-- 프롬프트 라이브러리: 공식 템플릿(company-prompts.json id) + 커뮤니티 공유 글에 대한 좋아요
CREATE TABLE IF NOT EXISTS prompt_likes (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_email VARCHAR(320) NOT NULL,
  target_kind VARCHAR(20) NOT NULL CHECK (target_kind IN ('official', 'community')),
  target_id VARCHAR(200) NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  CONSTRAINT uq_prompt_likes_user_target UNIQUE (user_email, target_kind, target_id)
);

CREATE INDEX IF NOT EXISTS idx_prompt_likes_target ON prompt_likes (target_kind, target_id);
CREATE INDEX IF NOT EXISTS idx_prompt_likes_user ON prompt_likes (user_email, created_at DESC);

-- 임직원이 공유한 프롬프트(라이브러리 커뮤니티) — author_email: POST 시 세션(OPS) 이메일, UI는 @ 앞 로컬부로 표시
CREATE TABLE IF NOT EXISTS prompt_community_entries (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  author_email VARCHAR(320) NOT NULL,
  title VARCHAR(500) NOT NULL,
  description TEXT NOT NULL DEFAULT '',
  body TEXT NOT NULL,
  tag VARCHAR(100) NOT NULL DEFAULT '기타',
  is_published BOOLEAN NOT NULL DEFAULT true,
  is_deleted BOOLEAN NOT NULL DEFAULT false,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_prompt_community_author ON prompt_community_entries (author_email, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_prompt_community_created ON prompt_community_entries (created_at DESC) WHERE is_deleted = false AND is_published = true;

CREATE OR REPLACE FUNCTION set_prompt_community_entries_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_prompt_community_entries_updated_at ON prompt_community_entries;
CREATE TRIGGER trg_prompt_community_entries_updated_at
BEFORE UPDATE ON prompt_community_entries
FOR EACH ROW
EXECUTE FUNCTION set_prompt_community_entries_updated_at();

-- 팀 공유 프롬프트: 프롬프트 관련·결과(샘플) 첨부(JSON 배열, 경로는 /uploads/…)
ALTER TABLE prompt_community_entries ADD COLUMN IF NOT EXISTS prompt_attachments JSONB NOT NULL DEFAULT '[]';
ALTER TABLE prompt_community_entries ADD COLUMN IF NOT EXISTS result_sample_attachments JSONB NOT NULL DEFAULT '[]';
