using System;
using System.Collections;
using System.Collections.Generic;
using SimpleJSON;
using UnityEngine;
using UnityEngine.Networking;

[Serializable]
public class ErrorResponse
{
    public int status;
    public Dictionary<string, object> data;
    public string message;
}

public enum ErrorType
{
    None,
    Authentication,
    Network,
    Server,
    Unknown
}

public class webservice : MonoBehaviour
{
    public static webservice instance;
    public string lastError; // Store the last error message
    public ErrorResponse lastErrorResponse;
    public ErrorType lastErrorType;

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        instance = this;
    }

    public IEnumerator LoginRequest(Dictionary<string, string> formData, Action<User> onComplete)
    {
        string url = "http://194.62.43.230:8000/login";
        lastError = null;
        lastErrorResponse = null;
        lastErrorType = ErrorType.None;

        WWWForm form = new WWWForm();
        String par = "";
        foreach (KeyValuePair<string, string> entry in formData)
        {
            par += entry.Key + "=" + entry.Value;
            form.AddField(entry.Key, entry.Value);
        }
        print(url + "?" + par);

        using (UnityWebRequest www = UnityWebRequest.Post(url, form))
        {
            yield return www.SendWebRequest();

            if (www.result == UnityWebRequest.Result.Success)
            {
                print("Response: " + www.downloadHandler.text);
                var json = JSON.Parse(www.downloadHandler.text);

                PlayerPrefs.SetString("user", json["data"].ToString());
                User response = new User(json["data"].ToString());

                onComplete?.Invoke(response);
            }
            else
            {
                try
                {
                    lastErrorResponse = JsonUtility.FromJson<ErrorResponse>(www.downloadHandler.text);
                    lastError = lastErrorResponse.message;

                    if (lastErrorResponse.status >= 400 && lastErrorResponse.status < 500)
                    {
                        lastErrorType = ErrorType.Authentication;
                        lastError = "خطا در احراز هویت: " + lastErrorResponse.message;
                    }
                    else if (lastErrorResponse.status >= 500)
                    {
                        lastErrorType = ErrorType.Server;
                        lastError = "خطای سرور: " + lastErrorResponse.message;
                    }
                    else
                    {
                        lastErrorType = ErrorType.Unknown;
                        lastError = "خطای ناشناخته: " + lastErrorResponse.message;
                    }

                    Debug.LogError($"خطای API: وضعیت={lastErrorResponse.status}, پیام={lastErrorResponse.message}, نوع={lastErrorType}");
                }
                catch (Exception e)
                {
                    lastError = www.error;
                    if (www.error.Contains("NetworkError") ||
                        www.error.Contains("ConnectionError") ||
                        www.error.Contains("Cannot connect"))
                    {
                        lastErrorType = ErrorType.Network;
                        lastError = "خطای اتصال به اینترنت";
                    }
                    else
                    {
                        lastErrorType = ErrorType.Unknown;
                        lastError = "خطای ناشناخته در ارتباط با سرور";
                    }
                    Debug.LogError($"خطای شبکه: {www.error}, نوع={lastErrorType}");
                }
                onComplete?.Invoke(null);
            }
        }
    }

    public IEnumerator GetInfoRequest(Action<GetInfoResponse> onComplete)
    {
        string url = "http://194.62.43.230:8000/getInfo";
        lastError = null;
        lastErrorResponse = null;

        UnityWebRequest www = UnityWebRequest.Get(url);
        www.SetRequestHeader("Authorization", "token " + EN.instance.Me.token);

        yield return www.SendWebRequest();

        if (www.result == UnityWebRequest.Result.Success)
        {
            Debug.Log("Response: " + www.downloadHandler.text);
            var root = JSON.Parse(www.downloadHandler.text);
            GetInfoResponse response = new GetInfoResponse();


            var data = root["data"];

            // --- Customer ---
            var cust = new Customer();
            cust.id = data["customer"]["id"].AsInt;
            cust.semat = data["customer"]["semat"];
            cust.user = data["customer"]["user"].AsInt;
            cust.user_id = data["customer"]["user_id"].AsInt;
            cust.mobile_number = data["customer"]["mobile_number"];
            cust.profile_img = data["customer"]["profile_img"];
            cust.profile_glb = data["customer"]["profile_glb"];
            cust.is_sms_verified = data["customer"]["is_sms_verified"].AsBool;
            cust.is_email_verified = data["customer"]["is_email_verified"].AsBool;
            response.customer = cust;

            // --- Images ---
            var imagesArray = data["images"].AsArray;
            for (int i = 0; i < imagesArray.Count; i++)
            {
                var item = imagesArray[i];
                var img = new ImageData();
                img.id = item["id"].AsInt;
                img.url = item["url"];
                img.image = item["image"];
                img.name = item["name"];
                img.created_at = item["created_at"];
                response.images.Add(img);
            }

            // --- Pdfs ---
            var pdfsArray = data["pdfs"].AsArray;
            for (int i = 0; i < pdfsArray.Count; i++)
            {
                var item = pdfsArray[i];
                var pdf = new PdfData();
                pdf.id = item["id"].AsInt;
                pdf.url = item["url"];
                pdf.pdf = item["pdf"];
                pdf.name = item["name"];
                pdf.created_at = item["created_at"];
                response.pdfs.Add(pdf);
            }

            // --- Videos ---
            var videosArray = data["videos"].AsArray;
            for (int i = 0; i < videosArray.Count; i++)
            {
                var item = videosArray[i];
                var vid = new VideoData();
                vid.id = item["id"].AsInt;
                vid.url = item["url"];
                vid.video = item["video"];
                vid.name = item["name"];
                vid.created_at = item["created_at"];
                response.videos.Add(vid);
            }

            // --- Glbs ---
            var glbsArray = data["glbs"].AsArray;
            for (int i = 0; i < glbsArray.Count; i++)
            {
                var item = glbsArray[i];
                var glb = new GlbData();
                glb.id = item["id"].AsInt;
                glb.url = item["url"];
                glb.glb = item["glb"];
                glb.name = item["name"];
                glb.created_at = item["created_at"];
                response.glbs.Add(glb);
            }

            // حالا response آماده استفاده‌ست
            Debug.Log("موبایل: " + response.customer.mobile_number);
            Debug.Log("اولین عکس: " + (response.images.Count > 0 ? response.images[0].image : "نداره"));

            onComplete?.Invoke(response);

        }
        else
        {
            try
            {
                lastErrorResponse = JsonUtility.FromJson<ErrorResponse>(www.downloadHandler.text);
                lastError = lastErrorResponse.message;
                Debug.LogError($"API Error: Status={lastErrorResponse.status}, Message={lastErrorResponse.message}");
            }
            catch (Exception e)
            {
                lastError = www.error;
                Debug.LogError($"Network Error: {www.error}");
            }
            onComplete?.Invoke(null);
        }
    }
}

[System.Serializable]
public class GetInfoResponse
{
    public Customer customer;
    public List<ImageData> images = new List<ImageData>();
    public List<PdfData> pdfs = new List<PdfData>();
    public List<VideoData> videos = new List<VideoData>();
    public List<GlbData> glbs = new List<GlbData>();
    public object subscription;
}

[System.Serializable]
public class Customer
{
    public int id;
    public string semat;
    public int user;
    public int user_id;
    public string mobile_number;
    public string profile_img;
    public string profile_glb;
    public bool is_sms_verified;
    public bool is_email_verified;
}

[System.Serializable]
public class ImageData
{
    public int id;
    public string url;
    public string image;
    public string name;
    public string created_at;
}

[System.Serializable]
public class PdfData
{
    public int id;
    public string url;
    public string pdf;
    public string name;
    public string created_at;
}

[System.Serializable]
public class VideoData
{
    public int id;
    public string url;
    public string video;
    public string name;
    public string created_at;
}

[System.Serializable]
public class GlbData
{
    public int id;
    public string url;
    public string glb;
    public string name;
    public string created_at;
}

[Serializable]
public class User
{
    public int id;
    public string token;
    public string first_name;
    public string last_name;
    public string job;
    public GameObject character;
    public string characterUrl;
    private string user;

    public User()
    {

    }
    public User(string j)
    {
        if (EN.instance)
            EN.instance.Print(j);
        var json = JSON.Parse(j);
        User response = this;
        response.token = json["token"];

        response.id = json["user"]["id"].AsInt;
        response.first_name = json["user"]["first_name"];
        response.last_name = json["user"]["last_name"];
        response.characterUrl = json["customer"]["profile_glb"];

        EN.instance.Print(response.last_name);
    }
}