<?php

namespace App\Http\Controllers\Admin;

use App\Http\Requests\PriceRequest;
use App\Models\Park;
use App\Models\Price;
use App\Models\Pplace;
use App\Models\Psection;
use App\Models\Ptype;
use App\Models\Usertype;
use App\Models\Station;
use App\Models\Utils;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Response;

class PriceController extends Controller
{
    public function list(Request $request)
    {
        $inputs = [
            'isExport'   => 0,
            'sort'       => $request->input('sort', ''),       // ソート対象カラム
            'sort_type'  => $request->input('sort_type', ''),  // 昇順/降順
            'page'       => $request->get('page', 1),
        ];

        // Price::search 内で orderBy を反映させる
        $inputs['list'] = Price::search($inputs);

        if ($inputs['list']->total() > 0 && $inputs['page'] > $inputs['list']->lastPage()) {
            return redirect()->route('prices');
        }
        $dataList = $this->getDataDropList();
        $inputs   = array_merge($inputs, $dataList);

        return view('admin.prices.list', $inputs);
    }


    public function add(Request $request)
    {
        if ($request->isMethod('get')) {
            return view('admin.prices.add', array_merge(
                $this->getDataDropList(),
                [
                    'record' => new Price(),
                    'isEdit' => false,
                ]
            ));
        }

        $request->merge([
            'pplace_id' => mb_convert_kana($request->input('pplace_id'), 'n'),
        ]);

        $validated = $this->validateRequest($request);

        $created = false;
        \DB::transaction(function () use ($validated, &$created) {
            $price = new Price();
            $price->fill($validated);
            $created = $price->save();
        });

        return redirect()->route('prices')
            ->with($created ? 'success' : 'error', $created ? '登録しました。' : '登録に失敗しました。');
    }


    public function edit(Request $request, $id)
    {
        $price = Price::getByPk($id);
        if (!$price) {
            abort(404);
        }

        if ($request->isMethod('get')) {
            return view('admin.prices.edit', array_merge(
                $this->getDataDropList(),
                [
                    'record' => $price,
                    'isEdit' => true,
                ]
            ));
        }

        $request->merge([
            'pplace_id' => mb_convert_kana($request->input('pplace_id'), 'n'),
        ]);

        $validated = $this->validateRequest($request, $id);

        $updated = false;
        \DB::transaction(function () use ($validated, &$updated, $price) {
            $price->fill($validated);
            $updated = $price->save();
        });

        return redirect()->route('prices')
            ->with($updated ? 'success' : 'error', $updated ? '更新しました。' : '更新に失敗しました。');
    }



    public function delete(Request $request, $id = null)
    {
        // 一覧画面（checkbox で複数削除）
        $ids = $request->input('pk');

        // 編集画面（単体削除）
        if ($id) {
            $ids = [$id];
        }

        // 削除対象が空
        if (empty($ids)) {
            return redirect()->route('prices')->with('error', '削除対象が選択されていません。');
        }

        // 削除処理
        Price::destroy($ids);

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



    public static function deleteByPk($ids)
    {
        if (!is_array($ids)) {
            $ids = [$ids];
        }
        return self::whereIn('price_parkplaceid', $ids)->delete();
    }

    public function export()
    {
        $filename = '駐輪場所、料金マスタ' . now()->format('YmdHis') . '.csv';

        $file = fopen($filename, 'w+');
        fwrite($file, "\xEF\xBB\xBF"); // BOM追加（UTF-8）

        $columns = [
            '駐輪場所ID',
            '駐輪場ID',
            '商品名',
            '期間',
            '利用者分類ID',
            '駐輪料金（税込）',
            '車種区分ID',
            '駐輪分類ID',
            '駐車車室ID',
        ];

        fputcsv($file, $columns);

        $data = Price::all();
        foreach ($data as $item) {
            fputcsv($file, [
                $item->price_parkplaceid,   // 駐輪場所ID
                $item->park_id,             // 駐輪場ID
                optional($item->getUserType())->print_name,  // 利用者分類名
                $item->price_month,         // 期間
                optional($item->getUserType())->print_name,   // 利用者分類ID
                $item->price,               // 駐輪料金（税込）
                optional($item->getPSection())->psection_subject, // 車種区分名
                optional($item->getPType())->ptype_subject,  // 駐輪分類名
                $item->pplace_id,           // 駐車車室ID
            ]);
        }


        fclose($file);

        $headers = [
            "Content-Type" => "text/csv; charset=UTF-8",
            "Content-Disposition" => "attachment; filename={$filename}",
        ];

        return response()->download($filename, $filename, $headers)->deleteFileAfterSend(true);
    }

    public function exportFiltered(Request $request)
    {
        $parkId = $request->input('park_id');
        $filename = 'price_' . $parkId . '_' . now()->format('YmdHis') . '.csv';

        // 一時ファイル作成
        $file = fopen($filename, 'w+');
        fwrite($file, "\xEF\xBB\xBF"); // UTF-8 BOM追加

        // CSVヘッダ
        $columns = [
            '駐輪場所ID',
            '商品名',
            '期間',
            '駐輪場ID',
            '駐輪場名',
            '車種区分ID',
            '車種区分',
            '駐輪分類ID',
            '駐輪分類',
            '利用者分類ID',
            '利用者分類',
            '駐輪車室ID',
            '駐輪料金（税込）',
        ];
        fputcsv($file, $columns);

        // データ取得（選択した駐輪場IDに限定）
        $data = \App\Models\Price::where('price_parkplaceid', $parkId)->get();

        foreach ($data as $item) {
            fputcsv($file, [
                $item->price_parkplaceid,                        // 駐輪場所ID
                $item->prine_name,                              // 商品名
                $item->price_term ?? $item->price_month,        // 期間
                $item->park_id,                                 // 駐輪場ID
                optional($item->getPark())->park_name,          // 駐輪場名
                $item->psection_id,                             // 車種区分ID
                optional($item->getPSection())->psection_subject, // 車種区分
                $item->price_ptypeid,                           // 駐輪分類ID
                optional($item->getPType())->ptype_subject,      // 駐輪分類
                $item->user_categoryid,                          // 利用者分類ID
                optional($item->getUserType())->print_name,       // 利用者分類
                $item->pplace_id,                                // 駐輪車室ID
                $item->price_taxin ?? $item->price,              // 駐輪料金（税込）
            ]);
        }

        fclose($file);

        // ヘッダ設定
        $headers = [
            "Content-Type" => "text/csv; charset=UTF-8",
            "Content-Disposition" => "attachment; filename=\"{$filename}\"",
        ];

        // ダウンロード後にファイル削除
        return response()->download($filename, $filename, $headers)->deleteFileAfterSend(true);
    }


    public function import(Request $request)
    {
        $file = $request->file('file');
        if (empty($file)) {
            return redirect()->route('prices')->with('error', __('CSVファイルを選択してください。'));
        }

        $data = Utils::csvToArray($file);
        $type = true;
        $msg = '';
        $record = 0;

        DB::beginTransaction();
        try {

            $col = 13; // CSV 項目数
            foreach ($data as $key => $items) {
                $record = $key + 2; // エラー行番号（ヘッダ行を考慮）

                // 項目数チェック
                if (count($items) != $col) {
                    $type = false;
                    $msg = "行:{$record} 列数が一致しません。";
                    break;
                }

                // 必須チェック
                if (empty($items[0])) { $type = false; $msg = "行:{$record} 駐車場所IDが未設定です。"; break; }
                if (empty($items[1])) { $type = false; $msg = "行:{$record} 商品名が未設定です。"; break; }
                if (empty($items[2])) { $type = false; $msg = "行:{$record} 期間が未設定です。"; break; }
                if (empty($items[3])) { $type = false; $msg = "行:{$record} 駐輪場IDが未設定です。"; break; }
                if (empty($items[5])) { $type = false; $msg = "行:{$record} 車種区分IDが未設定です。"; break; }
                if (empty($items[7])) { $type = false; $msg = "行:{$record} 駐輪分類IDが未設定です。"; break; }
                if (empty($items[9])) { $type = false; $msg = "行:{$record} 利用者分類IDが未設定です。"; break; }
                if (empty($items[11])) { $type = false; $msg = "行:{$record} 駐車車室IDが未設定です。"; break; }
                if (empty($items[12])) { $type = false; $msg = "行:{$record} 駐輪料金が未設定です。"; break; }

                // マスタ存在チェック
                if (!Park::where('park_id', $items[3])->exists()) {
                    $type = false; $msg = "行:{$record} 駐輪場IDが存在しません。"; break;
                }
                if (!Psection::where('psection_id', $items[5])->exists()) {
                    $type = false; $msg = "行:{$record} 車種区分IDが存在しません。"; break;
                }
                if (!Ptype::where('ptype_id', $items[7])->exists()) {
                    $type = false; $msg = "行:{$record} 駐輪分類IDが存在しません。"; break;
                }
                if (!Usertype::where('user_categoryid', $items[9])->exists()) {
                    $type = false; $msg = "行:{$record} 利用者分類IDが存在しません。"; break;
                }
                // TODO: 駐車車室ID チェック（pplace_id）
                if (!Pplace::where('pplace_id', $items[11])->exists()) {
                    $type = false; $msg = "行:{$record} 駐車車室IDが存在しません。"; break;
                }

                // 保存（存在すれば更新、なければ新規作成）
                Price::updateOrCreate(
                    ['price_parkplaceid' => $items[0]], // 主キー条件（存在チェック）

                    [
                        'prine_name'        => $items[1],
                        'price_month'       => $items[2],
                        'park_id'           => $items[3],
                        'psection_id'       => $items[5],
                        'price_ptypeid'     => $items[7],
                        'user_categoryid'   => $items[9],
                        'pplace_id'         => $items[11],
                        'price'             => $items[12],
                        'operator_id'       => auth()->user()->operator_id ?? null, // オプション
                        'updated_at'        => now(),
                        'created_at'        => now(),
                    ]
                );
            }
        } catch (\Exception $e) {
            $type = false;
            $msg = "行:{$record} 予期せぬエラー: ".$e->getMessage();
        }

        if ($type) {
            DB::commit();
            return redirect()->route('prices')->with('success', __('インポートが正常に完了しました。'));
        } else {
            DB::rollBack();
            return redirect()->route('prices')->with('error', $msg);
        }
    }


    public function info(Request $request, $id)
    {
        return $this->edit($request, $id, 'admin.prices.info');
    }

    public function getDataDropList()
    {
        $data['parks'] = Park::getList() ;
        $data['psections'] = Psection::getList() ;
        $data['ptypes'] = Ptype::getList() ;
        $data['userTypes'] = Usertype::getList() ;
        $data['pplaces'] = Pplace::getList() ;

        return $data;
    }

    /**
     * Price バリデーション共通
     */
    private function validateRequest(Request $request): array
    {
        return $request->validate([
            'prine_name'        => 'required|string|max:255',
            'price_month'       => 'required|int',
            'park_id'           => 'required|int',
            'psection_id'       => 'required|int',
            'price_ptypeid'     => 'required|int',
            'user_categoryid'   => 'required|int',
            'pplace_id'         => 'nullable|int',
            'park_number'       => 'nullable|int',
            'park_standard'     => 'nullable|int',
            'park_limit'        => 'nullable|int',
            'price'             => 'required|numeric',
            'operator_id'       => 'nullable|int',
        ]);
    }




}