using System;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using LinqToDB;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.RazorPages;
using trainav.web.database;
using trainav.web.database.Tables;
using trainav.web.JSON;
using trainav.web.Utils;
using Leg = trainav.web.database.Tables.Leg;

// ReSharper disable PossibleInvalidOperationException

namespace trainav.web.Pages;

public class OEAPIModel : PageModel {
	public int TripId;

	public void OnGet() {
		var link      = Request.Query["link"].ToString();
		var shortcode = link;
		var oepage    = "oeffisear.ch";
		if (link.Contains("oeffisear.ch")) {
			shortcode = link.Split("/#/").Last();
		}
		else if (link.Contains("transit.ztn.sh")) {
			shortcode = link.Split("/#/").Last();
			oepage    = "transit.ztn.sh";
		}

		var jid = shortcode.Split("/").Last();
		shortcode = shortcode.Split("/").First();

		using var db       = new Database.DbConn();
		var       response = new WebClient().DownloadString($"https://{oepage}/journeys?{{\"reqId\":\"{shortcode}\"}}");

		var parsed = OeapiResponse.FromJson(response);

		var authorizedUser = db.Users.FirstOrDefault(p => p.Username == AuthUtil.GetRemoteUser(HttpContext, db));

		if (!string.IsNullOrWhiteSpace(Request.Query["tripid"].ToString()))
			if (db.Trips.First(p => p.TripId == int.Parse(Request.Query["tripid"].ToString())).UserId != authorizedUser!.UserId)
				return;

		var tripId = Request.Query["action"] == "addleg"
						 ? int.Parse(Request.Query["tripid"])
						 : db.InsertWithInt32Identity(new Trip { UserId = authorizedUser!.UserId });

		foreach (var journey in parsed.Data.Journeys[jid].Legs.Where(p => p.IsTransfer != true && p.IsWalking != true)) {
			var arrtime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
			var deptime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
			arrtime = arrtime.AddSeconds((long)journey.Arrival.PlannedTime).ToLocalTime();
			deptime = deptime.AddSeconds((long)journey.Departure.PlannedTime).ToLocalTime();
			var trainNo = int.Parse(journey.Line.TripNum);
			if (trainNo == 0) {
				var extractedTrainNo = Regex.Match(journey.Line.Name, @"\d+").Value;
				if (extractedTrainNo.Length > 0)
					trainNo = int.Parse(extractedTrainNo);
			}

			db.InsertWithInt32Identity(new Leg {
										   TripId       = tripId,
										   UserId       = authorizedUser!.UserId,
										   TrainType    = journey.Line.ProductName,
										   TrainNr      = trainNo,
										   ArrStation   = journey.Arrival.Point.Stop.Name,
										   ArrStationId = int.Parse(journey.Arrival.Point.Stop.Id),
										   ArrTime      = arrtime.ToString("yyyy-MM-ddTHH:mm:ss"),
										   DepStation   = journey.Departure.Point.Stop.Name,
										   DepStationId = int.Parse(journey.Departure.Point.Stop.Id),
										   DepTime      = deptime.ToString("yyyy-MM-ddTHH:mm:ss")
									   });
		}

		TripId = tripId;
	}
}
