/// EIS4 measurement data types and hardware enums.
/// All types are Codable for GRDB/JSON storage.

import Foundation

// MARK: - Measurement points

struct EisPoint: Codable, Identifiable {
    let id = UUID()
    var freqHz: Float
    var magOhms: Float
    var phaseDeg: Float
    var zReal: Float
    var zImag: Float
    var rtiaMagBefore: Float
    var rtiaMagAfter: Float
    var revMag: Float
    var revPhase: Float
    var pctErr: Float

    enum CodingKeys: String, CodingKey {
        case freqHz, magOhms, phaseDeg, zReal, zImag
        case rtiaMagBefore, rtiaMagAfter, revMag, revPhase, pctErr
    }
}

struct LsvPoint: Codable, Identifiable {
    let id = UUID()
    var vMv: Float
    var iUa: Float

    enum CodingKeys: String, CodingKey {
        case vMv, iUa
    }
}

struct AmpPoint: Codable, Identifiable {
    let id = UUID()
    var tMs: Float
    var iUa: Float

    enum CodingKeys: String, CodingKey {
        case tMs, iUa
    }
}

struct ClPoint: Codable, Identifiable {
    let id = UUID()
    var tMs: Float
    var iUa: Float
    var phase: UInt8

    enum CodingKeys: String, CodingKey {
        case tMs, iUa, phase
    }
}

struct ClResult: Codable {
    var iFreeUa: Float
    var iTotalUa: Float
}

struct PhResult: Codable {
    var vOcpMv: Float
    var ph: Float
    var tempC: Float
}

// MARK: - Config

struct EisConfig: Codable {
    var freqStart: Float
    var freqStop: Float
    var ppd: UInt16
    var rtia: Rtia
    var rcal: Rcal
    var electrode: Electrode
}

// MARK: - Hardware enums

enum Rtia: UInt8, Codable, CaseIterable, Identifiable {
    var id: UInt8 { rawValue }

    case r200   = 0
    case r1K    = 1
    case r5K    = 2
    case r10K   = 3
    case r20K   = 4
    case r40K   = 5
    case r80K   = 6
    case r160K  = 7
    case extDe0 = 8

    var label: String {
        switch self {
        case .r200:   "200\u{2126}"
        case .r1K:    "1k\u{2126}"
        case .r5K:    "5k\u{2126}"
        case .r10K:   "10k\u{2126}"
        case .r20K:   "20k\u{2126}"
        case .r40K:   "40k\u{2126}"
        case .r80K:   "80k\u{2126}"
        case .r160K:  "160k\u{2126}"
        case .extDe0: "Ext 3k\u{2126} (DE0)"
        }
    }
}

enum Rcal: UInt8, Codable, CaseIterable, Identifiable {
    var id: UInt8 { rawValue }

    case r200 = 0
    case r3K  = 1

    var label: String {
        switch self {
        case .r200: "200\u{2126} (RCAL0\u{2194}RCAL1)"
        case .r3K:  "3k\u{2126} (RCAL0\u{2194}AIN0)"
        }
    }
}

enum Electrode: UInt8, Codable, CaseIterable, Identifiable {
    var id: UInt8 { rawValue }

    case fourWire  = 0
    case threeWire = 1

    var label: String {
        switch self {
        case .fourWire:  "4-wire (AIN)"
        case .threeWire: "3-wire (CE0/RE0/SE0)"
        }
    }
}

enum LpRtia: UInt8, Codable, CaseIterable, Identifiable {
    var id: UInt8 { rawValue }

    case r200  = 0
    case r1K   = 1
    case r2K   = 2
    case r3K   = 3
    case r4K   = 4
    case r6K   = 5
    case r8K   = 6
    case r10K  = 7
    case r12K  = 8
    case r16K  = 9
    case r20K  = 10
    case r24K  = 11
    case r30K  = 12
    case r32K  = 13
    case r40K  = 14
    case r48K  = 15
    case r64K  = 16
    case r85K  = 17
    case r96K  = 18
    case r100K = 19
    case r120K = 20
    case r128K = 21
    case r160K = 22
    case r196K = 23
    case r256K = 24
    case r512K = 25

    var label: String {
        switch self {
        case .r200:  "200\u{2126}"
        case .r1K:   "1k\u{2126}"
        case .r2K:   "2k\u{2126}"
        case .r3K:   "3k\u{2126}"
        case .r4K:   "4k\u{2126}"
        case .r6K:   "6k\u{2126}"
        case .r8K:   "8k\u{2126}"
        case .r10K:  "10k\u{2126}"
        case .r12K:  "12k\u{2126}"
        case .r16K:  "16k\u{2126}"
        case .r20K:  "20k\u{2126}"
        case .r24K:  "24k\u{2126}"
        case .r30K:  "30k\u{2126}"
        case .r32K:  "32k\u{2126}"
        case .r40K:  "40k\u{2126}"
        case .r48K:  "48k\u{2126}"
        case .r64K:  "64k\u{2126}"
        case .r85K:  "85k\u{2126}"
        case .r96K:  "96k\u{2126}"
        case .r100K: "100k\u{2126}"
        case .r120K: "120k\u{2126}"
        case .r128K: "128k\u{2126}"
        case .r160K: "160k\u{2126}"
        case .r196K: "196k\u{2126}"
        case .r256K: "256k\u{2126}"
        case .r512K: "512k\u{2126}"
        }
    }
}

// MARK: - Measurement type tag

enum MeasurementType: String, Codable {
    case eis
    case lsv
    case amp
    case chlorine
    case ph
}
