<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;

class NewsController extends Controller
{
    /** @var string テーブル名 */
    protected string $table = 'news';

    /** @var string 主キー列名 */
    protected string $pk    = 'news_id';

    /**
     * 現在ログイン中のオペレーターIDを取得
     * @return int|null
     */
    protected function currentOperatorId(): ?int
    {
        $u = auth()->user();
        return $u->ope_id ?? $u->id ?? null;
    }

    /**
     * 一覧表示（GET/POST）
     * 検索条件：kw（本文/URL 部分一致）、mode、open_datetime 範囲（from/to）
     */
    public function list(Request $request)
    {
        // 一覧用クエリ（表示に必要な列のみ）
        $q = DB::table($this->table)->select([
            "{$this->pk} as id",
            'news',
            'mode',
            'open_datetime',
            'link_url',
            'image1_filename',
            'image2_filename',
            'created_at',
            'updated_at',
        ]);

        // キーワード検索（本文/リンクURL）
        if ($kw = trim((string)$request->input('kw', ''))) {
            $q->where(function($w) use ($kw) {
                $w->where('news','like',"%{$kw}%")
                  ->orWhere('link_url','like',"%{$kw}%");
            });
        }

        // 表示モードで絞り込み（0:非表示 / 1:公開 / 2:下書き など）
        if ($request->filled('mode')) {
            $q->where('mode', (int)$request->input('mode'));
        }

        // 公開日時の範囲指定
        if ($request->filled('from')) { $q->where('open_datetime','>=',$request->input('from')); }
        if ($request->filled('to'))   { $q->where('open_datetime','<=',$request->input('to'));   }

        // {追加} 並び替え（ホワイトリスト）
        $sort = (string)$request->query('sort', '');
        $dir  = strtolower((string)$request->query('dir', 'desc'));
        $dir  = in_array($dir, ['asc','desc'], true) ? $dir : 'desc';

        // 画面キー → 実カラム
        $sortable = [
            'id'            => $this->pk,       // ニュースID
            'news'          => 'news',          // ニュース内容
            'open_datetime' => 'open_datetime', // 公開日時
            'mode'          => 'mode',          // 表示モード
        ];

        if (isset($sortable[$sort])) {
            $q->orderBy($sortable[$sort], $dir);
        } else {
            // 既定：公開日時降順 → 主キー降順
            $q->orderByDesc('open_datetime')
              ->orderByDesc($this->pk);
        }

        // ページング（現在のクエリを維持）
        $rows = $q->paginate(20)->appends($request->except('page'));

        return view('admin.news.list', compact('rows'));
    }

    /**
     * 新規作成（GET:フォーム表示 / POST:登録処理）
     */
    public function add(Request $request)
    {
        if ($request->isMethod('post')) {
            $messages = [
                'required' => ':attribute は、必ず入力してください。',
                'open_datetime.date_format' => '公開日時は :format 形式（YYYY-MM-DD HH:MM:SS）で入力してください。',
            ];
            $attributes = [
                'news' => 'ニュース内容',
                'open_datetime' => '公開日時',
                'mode' => '表示モード',
            ];
            $v = $request->validate([
                'news'            => 'required|string',
                'open_datetime'   => 'required|date_format:Y-m-d H:i:s',
                'link_url'        => 'nullable|string|max:255',
                'image1_filename' => 'nullable|string|max:255',
                'image2_filename' => 'nullable|string|max:255',
                'mode'            => 'required|integer|min:0|max:9',
            ], $messages, $attributes);

            // 登録
            $now = now();
            DB::table($this->table)->insert([
                'news'            => $v['news'],
                'open_datetime'   => $v['open_datetime'],
                'link_url'        => $v['link_url'] ?? null,
                'image1_filename' => $v['image1_filename'] ?? null,
                'image2_filename' => $v['image2_filename'] ?? null,
                'mode'            => $v['mode'],
                'created_at'      => $now,
                'updated_at'      => $now,
                'operator_id'     => $this->currentOperatorId(),
            ]);

            return redirect()->route('news')->with('success','ニュースを登録しました。');
        }

        // フォーム表示
        return view('admin.news.add');
    }

    /**
     * 編集（GET:フォーム表示 / POST:更新処理）
     * @param int $id ニュースID
     */
    public function edit($id, Request $request)
    {
        // 対象データ取得
        $news = DB::table($this->table)->where($this->pk, $id)->first();
        if (!$news) { abort(404); }

        if ($request->isMethod('post')) {
            $messages = [
                'required' => ':attribute は、必ず入力してください。',
                'open_datetime.date_format' => '公開日時は :format 形式（YYYY-MM-DD）で入力してください。',
            ];
            $attributes = [
                'news' => 'ニュース内容',
                'open_datetime' => '公開日時',
                'mode' => '表示モード',
            ];
            $v = $request->validate([
                'news'            => 'required|string',
                'open_datetime'   => 'required|date_format:Y-m-d', 
                'link_url'        => 'nullable|string|max:255',
                'image1_filename' => 'nullable|string|max:255',
                'image2_filename' => 'nullable|string|max:255',
                'mode'            => 'required|integer|min:0|max:9',
            ], $messages, $attributes);

            // 更新
            DB::table($this->table)->where($this->pk, $id)->update([
                'news'            => $v['news'],
                'open_datetime'   => $v['open_datetime'] . ' 00:00:00',
                'link_url'        => $v['link_url'] ?? null,
                'image1_filename' => $v['image1_filename'] ?? null,
                'image2_filename' => $v['image2_filename'] ?? null,
                'mode'            => $v['mode'],
                'updated_at'      => now(),
                'operator_id'     => $this->currentOperatorId(),
            ]);

            return redirect()->route('news_edit', ['id'=>$id])->with('success','更新しました。');
        }

        // フォーム表示
        return view('admin.news.edit', compact('news'));
    }

    /**
     * 詳細表示
     * @param int $id ニュースID
     */
    public function info($id)
    {
        // 詳細用に必要な列を選択
        $news = DB::table($this->table)
            ->select([
                "{$this->pk} as id",
                'news','mode','open_datetime','link_url',
                'image1_filename','image2_filename',
                'created_at','updated_at','operator_id',
            ])->where($this->pk, $id)->first();

        if (!$news) { abort(404); }

        return view('admin.news.info', compact('news'));
    }

    /**
     * 削除（単体 id または 複数 ids[] に対応）
     */
    public function delete(Request $request)
    {
        // 削除対象IDの取得（単体 or 複数）
        $ids = $request->input('ids');
        if (!$ids) {
            $id = (int)$request->input('id');
            if ($id > 0) { $ids = [$id]; }
        }

        // バリデーション：削除対象未選択
        if (!is_array($ids) || empty($ids)) {
            return back()->with('error', '削除対象が選択されていません。');
        }

        // 削除実行
        DB::table($this->table)->whereIn($this->pk, $ids)->delete();

        return back()->with('success','削除しました。');
    }
}
