/*
 * Copyright 2023 Hongen Wang All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:proxypin/l10n/app_localizations.dart';
import 'package:proxypin/network/components/manager/request_map_manager.dart';
import 'package:proxypin/network/components/manager/rewrite_rule.dart';
import 'package:proxypin/ui/component/state_component.dart';

import '../../../component/utils.dart';

/// 重写替换
/// @author wanghongen
/// 2023/10/8
class MobileMapLocal extends StatefulWidget {
  final RequestMapItem? item;
  final ScrollController? scrollController;

  const MobileMapLocal({super.key, this.item, this.scrollController});

  @override
  State<MobileMapLocal> createState() => MobileMapLocaleState();
}

class MobileMapLocaleState extends State<MobileMapLocal> {
  final _headerKey = GlobalKey<HeadersState>();
  final bodyTextController = TextEditingController();

  RxString bodyType = RxString(ReplaceBodyType.text.name);
  Rxn<String> bodyFile = Rxn<String>();
  TextEditingController statusCodeController = TextEditingController(text: '200');

  late ScrollController? bodyScrollController;

  AppLocalizations get localizations => AppLocalizations.of(context)!;

  @override
  initState() {
    super.initState();
    initItem(widget.item);
    bodyScrollController = trackingScroll(widget.scrollController);
  }

  @override
  dispose() {
    bodyTextController.dispose();
    statusCodeController.dispose();
    bodyScrollController?.dispose();
    super.dispose();
  }

  ///初始化重写项
  void initItem(RequestMapItem? item) {
    if (item == null) {
      return;
    }
    statusCodeController.text = item.statusCode?.toString() ?? '200';
    bodyTextController.text = item.body ?? '';
    bodyType.value = item.bodyType ?? ReplaceBodyType.text.name;
    if (item.bodyType == ReplaceBodyType.file.name) {
      bodyFile.value = item.bodyFile;
    }
  }

  RequestMapItem getRequestMapItem() {
    RequestMapItem item = widget.item ?? RequestMapItem();
    var headers = _headerKey.currentState?.getHeaders() ?? widget.item?.headers;
    item.statusCode = int.tryParse(statusCodeController.text) ?? 200;
    item.headers = headers;
    item.body = bodyTextController.text;
    item.bodyType = bodyType.value;
    if (item.bodyType == ReplaceBodyType.file.name) {
      item.bodyFile = bodyFile.value;
    } else {
      item.bodyFile = null;
    }
    return item;
  }

  @override
  Widget build(BuildContext context) {
    List<String> tabs = [localizations.statusCode, localizations.responseHeader, localizations.responseBody];

    return DefaultTabController(
        length: tabs.length,
        initialIndex: tabs.length - 1,
        child: Scaffold(
          appBar: tabBar(tabs),
          body: TabBarView(children: [
            KeepAliveWrapper(child: statusCodeEdit()),
            KeepAliveWrapper(child: headers()),
            KeepAliveWrapper(child: body())
          ]),
        ));
  }

  //tabBar
  TabBar tabBar(List<String> tabs) {
    return TabBar(
        tabs: tabs
            .map((label) => Tab(
                  height: 38,
                  child: Text(label, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500)),
                ))
            .toList());
  }

  //body
  Widget body() {
    bool isEN = Localizations.localeOf(context) == const Locale.fromSubtags(languageCode: 'en');

    return Obx(() => ListView(physics: const ClampingScrollPhysics(), children: [
          Row(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [
            const SizedBox(width: 5),
            Text("${localizations.type}: "),
            SizedBox(
                width: 90,
                child: DropdownButtonFormField<String>(
                    value: bodyType.value,
                    focusColor: Colors.transparent,
                    itemHeight: 48,
                    decoration: const InputDecoration(
                        contentPadding: EdgeInsets.all(10), isDense: true, border: InputBorder.none),
                    items: ReplaceBodyType.values
                        .map((e) => DropdownMenuItem(
                            value: e.name,
                            child: Text(isEN ? e.name.toUpperCase() : e.label,
                                style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500))))
                        .toList(),
                    onChanged: (val) => bodyType.value = val ?? ReplaceBodyType.text.name)),
          ]),
          const SizedBox(height: 10),
          if (bodyType.value == ReplaceBodyType.file.name)
            fileBodyEdit()
          else
            TextFormField(
                controller: bodyTextController,
                scrollPhysics: const BouncingScrollPhysics(),
                scrollController: bodyScrollController,
                style: const TextStyle(fontSize: 14),
                minLines: 18,
                maxLines: 20,
                decoration: decoration(localizations.replaceBodyWith,
                    hintText: '${localizations.example} {"code":"200","data":{}}')),
        ]));
  }

  Widget fileBodyEdit() {
    //选择文件  删除
    return Obx(() => Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
          Expanded(
              child: bodyFile.value == null
                  ? Container(height: 50)
                  : Container(
                      padding: const EdgeInsets.all(5),
                      foregroundDecoration:
                          BoxDecoration(border: Border.all(color: Theme.of(context).colorScheme.primary, width: 1)),
                      child: Text(bodyFile.value ?? ''))),
          const SizedBox(width: 10),
          FilledButton(
              onPressed: () async {
                FilePickerResult? result = await FilePicker.platform.pickFiles();
                String? path = result?.files.single.path;

                if (path == null) {
                  return;
                }
                bodyFile.value = path;
              },
              child: Text(localizations.selectFile, style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500))),
          const SizedBox(width: 10),
          FilledButton(
              onPressed: () {
                setState(() {
                  bodyFile.value = null;
                });
              },
              child: Text(localizations.delete, style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500))),
        ]));
  }

  //headers
  Widget headers() {
    return Headers(headers: widget.item?.headers, key: _headerKey);
  }

  Widget textField(String label, dynamic value, String hint, {ValueChanged<String>? onChanged}) {
    return Row(children: [
      SizedBox(width: 80, child: Text(label)),
      Expanded(
          child: TextFormField(
        initialValue: value,
        onChanged: onChanged,
        decoration: InputDecoration(
            hintText: hint,
            hintStyle: TextStyle(color: Colors.grey.shade500, fontSize: 14),
            contentPadding: const EdgeInsets.all(10),
            errorStyle: const TextStyle(height: 0, fontSize: 0),
            focusedBorder: focusedBorder(),
            isDense: true,
            border: const OutlineInputBorder()),
      ))
    ]);
  }

  Widget statusCodeEdit() {
    return Container(
        padding: const EdgeInsets.all(10),
        child: Column(children: [
          Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
            Text(localizations.statusCode),
            const SizedBox(width: 10),
            SizedBox(
                width: 100,
                child: TextFormField(
                  controller: statusCodeController,
                  style: const TextStyle(fontSize: 14),
                  inputFormatters: [FilteringTextInputFormatter.digitsOnly],
                  decoration: InputDecoration(
                      contentPadding: const EdgeInsets.all(10),
                      focusedBorder: focusedBorder(),
                      isDense: true,
                      border: const OutlineInputBorder()),
                )),
            const SizedBox(width: 10),
          ])
        ]));
  }

  InputDecoration decoration(String label, {String? hintText}) {
    Color color = Theme.of(context).colorScheme.primary;
    // Color color = Colors.blueAccent;
    return InputDecoration(
        floatingLabelBehavior: FloatingLabelBehavior.always,
        labelText: label,
        hintStyle: TextStyle(color: Colors.grey.shade500),
        hintText: hintText,
        isDense: true,
        border: OutlineInputBorder(borderSide: BorderSide(width: 0.8, color: color)),
        enabledBorder: OutlineInputBorder(borderSide: BorderSide(width: 1.5, color: color)),
        focusedBorder: OutlineInputBorder(borderSide: BorderSide(width: 2, color: color)));
  }

  InputBorder focusedBorder() {
    return OutlineInputBorder(borderSide: BorderSide(color: Theme.of(context).colorScheme.primary, width: 2));
  }
}

///请求头
class Headers extends StatefulWidget {
  final Map<String, String>? headers;

  const Headers({super.key, this.headers});

  @override
  State<StatefulWidget> createState() {
    return HeadersState();
  }
}

class HeadersState extends State<Headers> with AutomaticKeepAliveClientMixin {
  final Map<TextEditingController, TextEditingController> _headers = {};

  @override
  bool get wantKeepAlive => true;

  AppLocalizations get localizations => AppLocalizations.of(context)!;

  @override
  void initState() {
    super.initState();
    if (widget.headers == null) {
      _headers[TextEditingController()] = TextEditingController();
      return;
    }

    setHeaders(widget.headers);
  }

  void setHeaders(Map<String, String>? headers) {
    _clear();
    headers?.forEach((name, value) {
      _headers[TextEditingController(text: name)] = TextEditingController(text: value);
    });
    _headers[TextEditingController()] = TextEditingController();
  }

  ///获取所有请求头
  Map<String, String> getHeaders() {
    var headers = <String, String>{};
    _headers.forEach((name, value) {
      if (name.text.isEmpty) {
        return;
      }
      headers[name.text] = value.text;
    });
    return headers;
  }

  @override
  dispose() {
    _clear();
    super.dispose();
  }

  void _clear() {
    _headers.forEach((key, value) {
      key.dispose();
      value.dispose();
    });
    _headers.clear();
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);

    var list = _buildRows();

    return Column(children: [
      Expanded(
          child: Padding(
              padding: const EdgeInsets.only(top: 10, bottom: 10),
              child: ListView.separated(
                  shrinkWrap: true,
                  separatorBuilder: (context, index) =>
                      index == list.length ? const SizedBox() : const Divider(thickness: 0.2),
                  itemBuilder: (context, index) => list[index],
                  itemCount: list.length))),
      TextButton(
        child: Text("${localizations.add}Header", textAlign: TextAlign.center),
        onPressed: () {
          setState(() {
            _headers[TextEditingController()] = TextEditingController();
          });
        },
      ),
    ]);
  }

  List<Widget> _buildRows() {
    List<Widget> list = [];

    _headers.forEach((key, val) {
      list.add(_row(
          _cell(key, isKey: true),
          _cell(val),
          Padding(
              padding: const EdgeInsets.only(right: 15),
              child: InkWell(
                  onTap: () {
                    setState(() {
                      _headers.remove(key);
                    });
                  },
                  child: const Icon(Icons.remove_circle_outline, size: 16)))));
    });

    return list;
  }

  Widget _cell(TextEditingController val, {bool isKey = false}) {
    return Container(
        padding: const EdgeInsets.only(right: 5),
        child: TextFormField(
            style: TextStyle(fontSize: 12, fontWeight: isKey ? FontWeight.w500 : null),
            controller: val,
            minLines: 1,
            maxLines: 3,
            decoration: InputDecoration(
                isDense: true,
                border: const OutlineInputBorder(),
                enabledBorder: OutlineInputBorder(borderSide: BorderSide(width: 0.5, color: Colors.grey)),
                hintStyle: TextStyle(fontSize: 12, color: Colors.grey),
                hintText: isKey ? "Key" : "Value")));
  }

  Widget _row(Widget key, Widget val, Widget? op) {
    return Row(children: [
      Expanded(flex: 4, child: key),
      const Text(": ", style: TextStyle(color: Colors.deepOrangeAccent)),
      Expanded(flex: 6, child: val),
      op ?? const SizedBox()
    ]);
  }
}
