using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System;

namespace Elwig.Helpers.Export {

    using Row = Tuple<(string?, string?, string?, string?, string, int, string, int), (string, int, string, string, string, int, string, double, double)>;

    public class Bki : Csv<Row> {

        private readonly string _clientData;

        public Bki(string filename) : base(filename, ';', Encoding.Latin1) {
            Header = """
                EDV-Liste zum automatischen Einlesen in die Weindatenbank;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                Stammdaten;;;;;;;;;;;;;;Transportschein;;;;;;;;;;;;;;;;
                Empfänger:;;;;;;;Versender:;;;;;;;;;;;;;;;;;;;;;;;
                Betriebsnr;Name od. Firmenname;Vorname;Straße;Hausnr;Plz;Ort;Betriebsnr;Name od. Firmenname;Vorname;Straße;Hausnr;Plz;Ort;Datum der Lieferung;Menge in kg;Art;Weiß;Rot;Sorte1;Sorte2;Sorte3;Qualitätsstufe;Jahrgang;Herkunft;°KMW;°Oe;Vollablieferer;Ha Gesamt;Ha Ertragsfähig;Flächenbindung in Ha für AMA
                """;
            var c = App.Client;
            var (a1, a2) = Utils.SplitAddress(c.Address);
            _clientData = $"{c.LfbisNr};{c.NameFull};;{a1};\t{a2};{c.Plz};{c.Ort}";
        }

        public async Task ExportAsync(int year) {
            using var cnx = await AppDbContext.ConnectAsync();
            using var cmd = cnx.CreateCommand();
            cmd.CommandText = $"""
                SELECT lfbis_nr, name, other_names, billing_name, address, plz, ort, area,
                       date, weight, type, sortid, qualid, year, hkid, kmw, oe
                FROM v_bki_delivery
                WHERE year = {year}
                """;
            var r = await cmd.ExecuteReaderAsync();
            List<Row> rows = [];
            while (await r.ReadAsync()) {
                rows.Add(new(
                    (r.IsDBNull(0) ? null : r.GetString(0), r.IsDBNull(1) ? null : r.GetString(1), r.IsDBNull(2) ? null : r.GetString(2), r.IsDBNull(3) ? null : r.GetString(3), r.GetString(4), r.GetInt32(5), r.GetString(6), r.GetInt32(7)),
                    (r.GetString(8), r.GetInt32(9), r.GetString(10), r.GetString(11), r.GetString(12), r.GetInt32(13), r.GetString(14), r.GetDouble(15), r.GetDouble(16))
                ));
            }

            await ExportAsync(rows);
        }

        public void Export(int year) {
            ExportAsync(year).GetAwaiter().GetResult();
        }

        public override string FormatRow(Row row) {
            var (member, delivery) = row;
            var (lfBisNr, familyName, name, billingName, address, plz, ort, area) = member;
            var (date, weight, type, sortid, qualid, year, hkid, kmw, oe) = delivery;

            var (n1, n2) = billingName == null ? (familyName, name) : Utils.SplitName(billingName, familyName);
            var (a1, a2) = Utils.SplitAddress(address);
            var memberData = $"{lfBisNr};{n1};{n2};{a1};\t{a2};{plz};{ort}";
            var deliveryData = $"{string.Join(".", date.Split("-").Reverse())};{weight};TB;{(type == "W" ? "J" : "")};{(type == "R" ? "J" : "")};{sortid};;;{qualid};{year};{hkid};{kmw:0.0};{oe:0}";
            var vollData = $"N;;;{area / 10_000.0}";

            return $"{_clientData};{memberData};{deliveryData};{vollData}";
        }
    }
}
