<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\SettlementTransaction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\StreamedResponse;

class SettlementTransactionController extends Controller
{
    /**
     * 一覧
     * ルート: settlement_transactions
     */
    public function list(Request $request)
    {
        // 解除ボタンが押された場合 → 一覧にリダイレクトして検索条件リセット
        if ($request->input('action') === 'unlink') {
            return redirect()->route('settlement_transactions');
        }

        $q = SettlementTransaction::query();

        // --- 絞り込み
        $contractId = $request->input('contract_id');
        $status     = trim((string)$request->input('status', ''));
        $from       = $request->input('from'); // 支払日時 from
        $to         = $request->input('to');   // 支払日時 to

        if ($contractId !== null && $contractId !== '') {
            $q->where('contract_id', (int)$contractId);
        }
        if ($status !== '') {
            $q->where('status', 'like', "%{$status}%");
        }
        if ($from) {
            $q->whereDate('pay_date', '>=', $from);
        }
        if ($to) {
            $q->whereDate('pay_date', '<=', $to);
        }

        // --- ソート（既定：created_at desc）
        $sort  = $request->input('sort', 'created_at');
        $type  = strtolower($request->input('sort_type', 'desc'));
        $allow = [
            'settlement_transaction_id', 'created_at', 'updated_at',
            'contract_id', 'status', 'pay_date', 'settlement_amount',
        ];
        if (!in_array($sort, $allow, true)) $sort = 'created_at';
        if (!in_array($type, ['asc', 'desc'], true)) $type = 'desc';
        $q->orderBy($sort, $type);

        return view('admin.settlement_transactions.list', [
            'transactions' => $q->paginate(20)->appends($request->except('page')),
            'contract_id'  => $contractId,
            'status'       => $status,
            'from'         => $from,
            'to'           => $to,
            'sort'         => $sort,
            'sort_type'    => $type,
        ]);
    }


    /**
     * 新規
     * ルート: settlement_transactions_add
     */
    public function add(Request $request)
    {
        if ($request->isMethod('post')) {
            $data = $this->validatePayload($request);
            SettlementTransaction::create($data);
            return redirect()->route('settlement_transactions')->with('success', '登録しました');
        }

        return view('admin.settlement_transactions.add', [
            'transaction' => null,
            'isEdit'      => false,
            'isInfo'      => false,
        ]);
    }

    /**
     * 編集
     * ルート: settlement_transactions_edit
     */
    public function edit(int $settlement_transaction_id, Request $request)
    {
        $transaction = SettlementTransaction::findOrFail($settlement_transaction_id);

        if ($request->isMethod('post')) {
            $data = $this->validatePayload($request);
            $transaction->update($data);
            return redirect()->route('settlement_transactions')->with('success', '更新しました');
        }

        return view('admin.settlement_transactions.edit', [
            'transaction' => $transaction,
            'isEdit'      => true,
            'isInfo'      => false,
        ]);
    }

    /**
     * 詳細
     * ルート: settlement_transactions_info
     */
    public function info(int $settlement_transaction_id)
    {
        $transaction = SettlementTransaction::findOrFail($settlement_transaction_id);

        return view('admin.settlement_transactions.info', [
            'transaction' => $transaction,
            'isEdit'      => false,
            'isInfo'      => true,
        ]);
    }

    /**
     * 一括削除（一覧のチェック name="ids[]"）
     * ルート: settlement_transactions_delete
     */
    public function delete(Request $request)
    {
        $ids = (array) $request->input('ids', []);
        $ids = array_values(array_filter($ids, fn($v) => preg_match('/^\d+$/', (string)$v)));

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

        SettlementTransaction::whereIn('settlement_transaction_id', $ids)->delete();

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

    /**
     * CSVインポート（簡易）
     * ルート: settlement_transactions_import
     *
     * 想定カラム順:
     * contract_id,status,pay_code,contract_payment_number,corp_code,
     * mms_date,cvs_code,shop_code,pay_date,settlement_amount,stamp_flag,md5_string
     * 1行目ヘッダ可
     */
    public function import(Request $request)
    {
        $request->validate([
            'file' => ['required', 'file', 'mimetypes:text/plain,text/csv,text/tsv', 'max:4096'],
        ]);

        $path = $request->file('file')->getRealPath();

        $created = 0;
        $updated = 0;
        $skipped = 0;

        DB::beginTransaction();
        try {
            if (($fp = fopen($path, 'r')) !== false) {
                $line = 0;
                while (($row = fgetcsv($fp)) !== false) {
                    $line++;

                    // ヘッダ行をスキップ
                    if ($line === 1) {
                        $joined = strtolower(implode(',', $row));
                        if (str_contains($joined, 'contract_id') || str_contains($joined, 'status')) {
                            continue;
                        }
                    }

                    // 入力列を安全に展開
                    [$contract_id,$status,$pay_code,$contract_payment_number,$corp_code,$mms_date,$cvs_code,$shop_code,$pay_date,$settlement_amount,$stamp_flag,$md5_string] = array_pad($row, 12, null);

                    // 正規化
                    $payload = [
                        'contract_id'             => ($contract_id === '' || $contract_id === null) ? null : (int)$contract_id,
                        'status'                  => $status !== null ? trim($status) : null,
                        'pay_code'                => $pay_code !== null ? trim($pay_code) : null,
                        'contract_payment_number' => $contract_payment_number !== null ? trim($contract_payment_number) : null,
                        'corp_code'               => $corp_code !== null ? trim($corp_code) : null,
                        'mms_date'                => $mms_date !== null ? trim($mms_date) : null,
                        'cvs_code'                => $cvs_code !== null ? trim($cvs_code) : null,
                        'shop_code'               => $shop_code !== null ? trim($shop_code) : null,
                        'pay_date'                => $pay_date ? date('Y-m-d H:i:s', strtotime($pay_date)) : null,
                        'settlement_amount'       => ($settlement_amount === '' || $settlement_amount === null) ? null : (float)preg_replace('/[^\d.]/','',$settlement_amount),
                        'stamp_flag'              => $stamp_flag !== null ? trim($stamp_flag) : null,
                        'md5_string'              => $md5_string !== null ? trim($md5_string) : null,
                    ];

                    // upsert キー（優先: md5_string、なければ contract_id+pay_date）
                    $ex = null;
                    if (!empty($payload['md5_string'])) {
                        $ex = SettlementTransaction::where('md5_string', $payload['md5_string'])->first();
                    } elseif (!empty($payload['contract_id']) && !empty($payload['pay_date'])) {
                        $ex = SettlementTransaction::where('contract_id', $payload['contract_id'])
                               ->where('pay_date', $payload['pay_date'])->first();
                    }

                    if ($ex) { $ex->update($payload); $updated++; }
                    else     { SettlementTransaction::create($payload); $created++; }
                }
                fclose($fp);
            }

            DB::commit();
            return redirect()->route('settlement_transactions')
                ->with('success', "インポート完了：新規 {$created} 件、更新 {$updated} 件、スキップ {$skipped} 件");
        } catch (\Throwable $e) {
            DB::rollBack();
            return redirect()->route('settlement_transactions')
                ->with('error', 'インポートに失敗しました：' . $e->getMessage());
        }
    }

    /**
     * CSVエクスポート
     * ルート: settlement_transactions_export
     */
    public function export(Request $request): StreamedResponse
    {
        $q = SettlementTransaction::query();

        // 一覧と同じソートを適用（任意で絞り込みも追加可能）
        $sort = $request->input('sort', 'created_at');
        $type = strtolower($request->input('sort_type', 'desc'));
        if (!in_array($type, ['asc','desc'], true)) $type = 'desc';
        $q->orderBy($sort, $type);

        $filename = 'settlement_transactions_' . now()->format('Ymd_His') . '.csv';

        return response()->streamDownload(function () use ($q) {
            $out = fopen('php://output', 'w');
            fputcsv($out, [
                'ID','契約ID','ステータス','支払コード','契約課金番号','企業コード',
                'MMS日付','CVSコード','店舗コード','支払日時','金額','スタンプ','MD5',
                '登録日時','更新日時'
            ]);
            $q->chunk(500, function ($rows) use ($out) {
                foreach ($rows as $r) {
                    fputcsv($out, [
                        $r->settlement_transaction_id,
                        $r->contract_id,
                        $r->status,
                        $r->pay_code,
                        $r->contract_payment_number,
                        $r->corp_code,
                        $r->mms_date,
                        $r->cvs_code,
                        $r->shop_code,
                        optional($r->pay_date)->format('Y-m-d H:i:s'),
                        $r->settlement_amount,
                        $r->stamp_flag,
                        $r->md5_string,
                        optional($r->created_at)->format('Y-m-d H:i:s'),
                        optional($r->updated_at)->format('Y-m-d H:i:s'),
                    ]);
                }
            });
            fclose($out);
        }, $filename, ['Content-Type' => 'text/csv; charset=UTF-8']);
    }

    /**
     * 共通バリデーション
     */
    private function validatePayload(Request $request): array
    {
        return $request->validate([
            'contract_id'             => ['nullable','integer'],
            'status'                  => ['nullable','string','max:255'],
            'pay_code'                => ['nullable','string','max:255'],
            'contract_payment_number' => ['nullable','string','max:255'],
            'corp_code'               => ['nullable','string','max:255'],
            'mms_date'                => ['nullable','string','max:255'],
            'cvs_code'                => ['nullable','string','max:255'],
            'shop_code'               => ['nullable','string','max:255'],
            'pay_date'                => ['nullable','date'],
            'settlement_amount'       => ['nullable','numeric'], // DB は decimal(10,0)
            'stamp_flag'              => ['nullable','string','max:255'],
            'md5_string'              => ['nullable','string','max:255'],
        ]);
    }
}
