import {Attestation, SchemaDecodedItem, SchemaEncoder} from "@ethereum-attestation-service/eas-sdk";
import {SCHEMA, SCHEMA_NAME_DICTIONARY, SCHEMA_UID} from "@/config/config";
import {AttestationData, AttestationDataView} from "@/types/attestationData";
import * as EASService from "@/services/easService";


const Schema = "string University_Name, string Faculty_Name, string Programme_Name, string Type_Name, string Mode_Name, string Academic_Year, string File_Hash";

export const createAttestation = async (attestationData: AttestationData): Promise<string> => {
    const eas = await EASService.getEASClient();

    // Initialize SchemaEncoder with the schema string
    const schemaEncoder = new SchemaEncoder(SCHEMA);
    const encodedData = schemaEncoder.encodeData([
        {name: "University_Name", value: attestationData.universityName, type: "string"},
        {name: "Faculty_Name", value: attestationData.facultyName, type: "string"},
        {name: "Programme_Name", value: attestationData.programmeName, type: "string"},
        {name: "Type_Name", value: attestationData.typeName, type: "string"},
        {name: "Mode_Name", value: attestationData.modeName, type: "string"},
        {name: "Academic_Year", value: attestationData.academicYear, type: "string"},
        {name: "File_Hash", value: attestationData.fileHash, type: "string"}
    ]);

    const tx = await eas.attest({
        schema: SCHEMA_UID,
        data: {
            recipient: attestationData.recipientAddress,
            expirationTime: undefined,
            revocable: false,
            data: encodedData,
        },
    });

    const attestationUID = await tx.wait();

    return attestationUID;
}

const decodeAttestationData = (attestationData: string): SchemaDecodedItem[] => {
    const schemaEncoder = new SchemaEncoder(Schema);

    return schemaEncoder.decodeData(attestationData);
}

const mapAttestationData = (attestation: Attestation, decodedData: SchemaDecodedItem[]): AttestationDataView => {

    const date = new Date(Number(attestation.time) * 1000);
    const dateString =
        new Intl.DateTimeFormat('en-GB', {
            dateStyle: 'full',
            timeStyle: 'long',
        }).format(date);

    console.log("Schema is mapped to attestation data")
    return {
        recipientAddress: attestation!.recipient,
        attester: attestation!.attester,
        schema: attestation!.schema,
        time: dateString,
        uid: attestation!.uid,
        schemaName: SCHEMA_NAME_DICTIONARY[attestation!.schema] || "Unknown",
        universityName: decodedData?.find((item) => item.name === "University_Name")?.value.value.toString() || "",
        facultyName: decodedData?.find((item) => item.name === "Faculty_Name")?.value.value.toString() || "",
        modeName: decodedData?.find((item) => item.name === "Mode_Name")?.value.value.toString() || "",
        typeName: decodedData?.find((item) => item.name === "Type_Name")?.value.value.toString() || "",
        academicYear: decodedData?.find((item) => item.name === "Academic_Year")?.value.value.toString() || "",
        programmeName: decodedData?.find((item) => item.name === "Programme_Name")?.value.value.toString() || "",
        fileHash: decodedData?.find((item) => item.name === "File_Hash")?.value.value.toString() || "",
    };
}

export const parseAttestation = (attestation: Attestation): AttestationDataView => {
    const decodedSchema = decodeAttestationData(attestation.data);
    return mapAttestationData(attestation, decodedSchema);
};