//
//  LineChartView.cpp
//  react-native-charts
//
//  Created by Peter Vu on 12/01/2023.
//

#import "LineChartView.h"

#import <react/renderer/components/RNChartsViewSpec/ComponentDescriptors.h>
#import <react/renderer/components/RNChartsViewSpec/EventEmitters.h>
#import <react/renderer/components/RNChartsViewSpec/Props.h>
#import <react/renderer/components/RNChartsViewSpec/RCTComponentViewHelpers.h>

#import "RCTFabricComponentsPlugins.h"
#import "RNCharts-Swift.h"
#import "NumberFormatterAxisValueFormatter.h"

using namespace facebook::react;

@interface RNLineChartView () <RCTRNLineChartViewViewProtocol>

@end

@implementation RNLineChartView {
	LineChartView * _view;
}

+ (ComponentDescriptorProvider)componentDescriptorProvider
{
	return concreteComponentDescriptorProvider<RNLineChartViewComponentDescriptor>();
}

- (instancetype)initWithFrame:(CGRect)frame
{
  if (self = [super initWithFrame:frame]) {
	static const auto defaultProps = std::make_shared<const RNLineChartViewProps>();
	_props = defaultProps;

	_view = [[LineChartView alloc] init];

	self.contentView = _view;
	  _view.chartDescription.enabled = NO;
	  _view.pinchZoomEnabled = NO;
	  _view.legend.enabled = NO;
	  _view.scaleYEnabled = NO;
	  _view.scaleXEnabled = NO;
	  _view.dragYEnabled = NO;
	  _view.drawBordersEnabled = NO;
	  _view.doubleTapToZoomEnabled = NO;
	  _view.highlightPerTapEnabled = NO;
	  _view.drawGridBackgroundEnabled = NO;
	  _view.highlightPerDragEnabled = NO;
  }

  return self;
}

- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
{
	const auto &oldViewProps = *std::static_pointer_cast<RNLineChartViewProps const>(_props);
	const auto &newViewProps = *std::static_pointer_cast<RNLineChartViewProps const>(props);

//	NSMutableArray<LineChartDataSet*>* dataSets = [[NSMutableArray alloc] init];
//	for (auto it = begin (newViewProps.seriesData.series.data); it != end (newViewProps.seriesData.series.data); ++it) {
//		NSMutableArray<ChartDataEntry*>* entries = [[NSMutableArray alloc] init];
//		for (auto eIdx = begin (it->data); eIdx != end (it->data); ++eIdx) {
//			ChartDataEntry* newEntry = [[ChartDataEntry alloc] initWithX:eIdx->x y:eIdx->y];
//			[entries addObject:newEntry];
//		}
//		
//		LineChartDataSet* dataSet = [[LineChartDataSet alloc] initWithEntries:entries];
//		dataSet.drawCirclesEnabled = NO;
//		dataSet.drawValuesEnabled = NO;
//		dataSet.lineWidth = 3;
//		
//		// it->color from std::string to NSString
//		NSString* colorString = [NSString stringWithUTF8String:it->color.c_str()];
//		dataSet.colors = @[[self hexStringToColor:colorString]];
//		[dataSets addObject:dataSet];
//	}
//    
    //
    
    std::string dataJsonString = newViewProps.seriesJsonData.series.data;
    NSString *convertedDataJsonString = [NSString stringWithUTF8String:dataJsonString.c_str()];
        
    NSError *error;
    NSDictionary *parsedData = [NSJSONSerialization JSONObjectWithData:[convertedDataJsonString dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
        
    NSArray *dataValuesArray = [parsedData allValues];
    
    NSMutableArray<LineChartDataSet*>* dataSets = [[NSMutableArray alloc] init];
    for (int dataSetIndex = 0; dataSetIndex < [dataValuesArray count]; dataSetIndex++) {
        NSDictionary *dataSetValue = dataValuesArray[dataSetIndex];
        NSMutableArray<ChartDataEntry*>* entries = [[NSMutableArray alloc] init];
        
        NSArray *dataItemValue = [dataSetValue[@"data"] allValues];
        
        // Create data entries for each dataset
        for (int entryIndex = 0; entryIndex < [dataItemValue count]; entryIndex++) {
            NSDictionary *dataEntryValue = dataItemValue[entryIndex];
            NSNumber *xValue = dataEntryValue[@"x"];
            NSNumber *yValue = dataEntryValue[@"y"];
            ChartDataEntry* newEntry = [[ChartDataEntry alloc] initWithX:xValue.doubleValue
                                                                       y:yValue.doubleValue];
            [entries addObject:newEntry];
        }
        
        LineChartDataSet* dataSet = [[LineChartDataSet alloc] initWithEntries:entries];
        dataSet.drawCirclesEnabled = NO;
        dataSet.drawValuesEnabled = NO;
        dataSet.lineWidth = 3;
        
        NSString *colorStringValue = dataSetValue[@"color"];

//        NSString* colorString = [NSString stringWithUTF8String:colorStringValue.c_str()];
        dataSet.colors = @[[self hexStringToColor:colorStringValue]];
//        dataSet.drawValuesEnabled = NO;
        
        [dataSets addObject:dataSet];
    }
	
	
	LineChartData* data = [[LineChartData alloc] initWithDataSets:dataSets];
	if (dataSets.count > 1) {
		[_view.xAxis setCenterAxisLabelsEnabled:YES];
		_view.xAxis.axisMinimum = 0;
	} else {
		[_view.xAxis setCenterAxisLabelsEnabled:NO];
		_view.xAxis.axisMinimum = -0.5;
	}
	
	_view.data = data;
	_view.rightAxis.enabled = NO;
	_view.leftAxis.axisMinimum = 0;
	_view.leftAxis.gridLineWidth = 1;
	_view.leftAxis.axisLineColor = UIColor.clearColor;
	_view.leftAxis.labelFont = [UIFont systemFontOfSize:newViewProps.yAxis.labels.style.fontSize];
	_view.leftAxis.labelTextColor = [self hexStringToColor:[NSString stringWithUTF8String:newViewProps.yAxis.labels.style.color.c_str()]];
	_view.leftAxis.axisLineWidth = newViewProps.yAxis.gridLineWidth;
	_view.leftAxis.gridLineWidth = newViewProps.yAxis.gridLineWidth;
	_view.leftAxis.gridColor = [self hexStringToColor:[NSString stringWithUTF8String:newViewProps.yAxis.gridLineColor.c_str()]];
	[_view.leftAxis setLabelPosition:YAxisLabelPositionOutsideChart];
//	_view.leftAxis.valueFormatter = LargeValueFormatter
	_view.leftAxis.valueFormatter = [[NumberFormatterAxisValueFormatter alloc] init];
	
	_view.xAxis.granularityEnabled = YES;
	_view.xAxis.axisMinimum = 0;
	_view.xAxis.granularity = 1;
	_view.xAxis.labelPosition = XAxisLabelPositionBottom;
	_view.xAxis.yOffset = 6;
	_view.xAxis.axisLineColor = UIColor.clearColor;
	_view.xAxis.gridLineWidth = newViewProps.xAxis.lineWidth;
	_view.xAxis.gridColor = [self hexStringToColor:[NSString stringWithUTF8String:newViewProps.xAxis.lineColor.c_str()]];
	_view.xAxis.labelTextColor = [self hexStringToColor:[NSString stringWithUTF8String:newViewProps.xAxis.labels.style.color.c_str()]];
//	_view.xAxis.axisMinimum = newViewProps.xAxis.categories.size();
	_view.xAxis.labelFont = [UIFont systemFontOfSize:newViewProps.xAxis.labels.style.fontSize];
	[_view.xAxis setCenterAxisLabelsEnabled:NO];
	[_view.xAxis setDrawGridLinesEnabled:YES];
	
	NSMutableArray<NSString*>* categories = [[NSMutableArray alloc] init];
	for (auto it = begin (newViewProps.xAxis.categories); it != end (newViewProps.xAxis.categories); ++it) {
		[categories addObject:[NSString stringWithUTF8String:it->c_str()]];
	}
	_view.xAxis.valueFormatter = [[ChartIndexAxisValueFormatter alloc] initWithValues:categories];
	[_view setVisibleXRangeMaximum:5];
	[_view setVisibleXRangeMinimum:0];
	
	[super updateProps:props oldProps:oldProps];
}

Class<RCTComponentViewProtocol> RNLineChartViewCls(void)
{
	return RNLineChartView.class;
}

- hexStringToColor:(NSString *)stringToConvert
{
	NSString *noHashString = [stringToConvert stringByReplacingOccurrencesOfString:@"#" withString:@""];
	NSScanner *stringScanner = [NSScanner scannerWithString:noHashString];
	
	unsigned hex;
	if (![stringScanner scanHexInt:&hex]) return nil;
	int r = (hex >> 16) & 0xFF;
	int g = (hex >> 8) & 0xFF;
	int b = (hex) & 0xFF;
	
	return [UIColor colorWithRed:r / 255.0f green:g / 255.0f blue:b / 255.0f alpha:1.0f];
}

@end
