require 'sinatra'
require 'sinatra/json'
require 'sinatra/cross_origin'
require 'sqlite3'
require 'securerandom'
require 'time'

register Sinatra::CrossOrigin

configure do
  enable :cross_origin
  set :bind, '0.0.0.0'
  set :port, 4567

  # DB初期化
  db = SQLite3::Database.new File.join(File.dirname(__FILE__), "fanfarm.db")
  db.results_as_hash = true
  set :DB, db

  # テーブル作成（なければ）
  settings.DB.execute <<-SQL
    CREATE TABLE IF NOT EXISTS recruitments (
      id TEXT PRIMARY KEY,
      username TEXT,
      address TEXT,
      pow TEXT,
      conAd TEXT,
      hw TEXT,
      schedule TEXT,
      veg TEXT,
      bucon TEXT
    );
  SQL

  settings.DB.execute <<-SQL
    CREATE TABLE IF NOT EXISTS applies (
      id TEXT PRIMARY KEY,
      username TEXT,
      address TEXT,
      conAd TEXT
    );
  SQL

  settings.DB.execute <<-SQL
    CREATE TABLE IF NOT EXISTS matches (
      id TEXT PRIMARY KEY,
      recruitment_id TEXT,
      apply_id TEXT
    );
  SQL

  settings.DB.execute <<-SQL
    CREATE TABLE IF NOT EXISTS messages (
      id TEXT PRIMARY KEY,
      match_id TEXT,
      user TEXT,
      content TEXT,
      created_at TEXT
    );
  SQL
end

before do
  response.headers['Access-Control-Allow-Origin'] = '*'
  response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
  response.headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Accept, Authorization'
end

options '*' do
  response.headers['Access-Control-Allow-Origin'] = '*'
  response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
  response.headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Accept, Authorization'
  200
end

# ---- API ----

get '/api/ping' do
  content_type :json
  json message: "pong"
end

## 募集一覧
get '/api/recruitments' do
  content_type :json
  r = settings.DB.execute("SELECT * FROM recruitments")
  json r
end

## 募集登録
post '/api/recruitments' do
  content_type :json
  data = JSON.parse(request.body.read)
  uuid = SecureRandom.uuid
  settings.DB.execute("INSERT INTO recruitments (id, username, address, pow, conAd, hw, schedule, veg, bucon) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
    [uuid, data["username"], data["address"], data["pow"], data["conAd"], data["hw"], data["schedule"], data["veg"], data["bucon"]])
  json status: "ok", id: uuid
end

## 応募一覧
get '/api/applies' do
  content_type :json
  a = settings.DB.execute("SELECT * FROM applies")
  json a
end

## 応募登録
post '/api/applies' do
  content_type :json
  data = JSON.parse(request.body.read)
  uuid = SecureRandom.uuid
  settings.DB.execute("INSERT INTO applies (id, username, address, conAd) VALUES (?, ?, ?, ?)",
    [uuid, data["username"], data["address"], data["conAd"]])
  json status: "ok", id: uuid
end

## マッチ一覧
get '/api/matches' do
  content_type :json
  m = settings.DB.execute("SELECT * FROM matches")
  results = m.map do |row|
    recruitment = settings.DB.get_first_row("SELECT * FROM recruitments WHERE id = ?", [row["recruitment_id"]])
    apply = settings.DB.get_first_row("SELECT * FROM applies WHERE id = ?", [row["apply_id"]])
    {
      id: row["id"],
      recruitment: recruitment,
      apply: apply
    }
  end
  json results
end

## マッチ登録
post '/api/matches' do
  content_type :json
  data = JSON.parse(request.body.read)
  uuid = SecureRandom.uuid
  settings.DB.execute("INSERT INTO matches (id, recruitment_id, apply_id) VALUES (?, ?, ?)",
    [uuid, data["recruitment_id"], data["apply_id"]])
  json status: "ok", id: uuid
end

## 掲示板メッセージ一覧
get '/api/messages' do
  content_type :json
  match_id = params['match_id']
  m = settings.DB.execute("SELECT * FROM messages WHERE match_id = ? ORDER BY created_at ASC", [match_id])
  json m
end

## 掲示板メッセージ投稿
post '/api/messages' do
  content_type :json
  data = JSON.parse(request.body.read)
  uuid = SecureRandom.uuid
  now = Time.now.utc.iso8601
  settings.DB.execute("INSERT INTO messages (id, match_id, user, content, created_at) VALUES (?, ?, ?, ?, ?)",
    [uuid, data["match_id"], data["user"], data["content"], now])
  json status: "ok", id: uuid, created_at: now
end